blob: bb68132fb49783ecc5404ca22463b3194716e28c [file] [log] [blame]
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Colin Crossd09b0b62018-04-18 11:06:47 -070018 "fmt"
Colin Crossa4f08812018-10-02 22:03:40 -070019 "path/filepath"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080020 "reflect"
Colin Crossb69301e2017-12-01 10:48:26 -080021 "sort"
Colin Crossd09b0b62018-04-18 11:06:47 -070022 "strings"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080023 "testing"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070024
25 "github.com/google/blueprint/proptools"
26
27 "android/soong/android"
28 "android/soong/cc"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080029)
30
Paul Duffin0ed42d32021-03-13 02:19:32 +000031// testAppConfig is a legacy way of creating a test Config for testing java app modules.
32//
33// See testJava for an explanation as to how to stop using this deprecated method.
34//
35// deprecated
36func testAppConfig(env map[string]string, bp string, fs map[string][]byte) android.Config {
37 return testConfig(env, bp, fs)
38}
39
40// testApp runs tests using the javaFixtureFactory
41//
42// See testJava for an explanation as to how to stop using this deprecated method.
43//
44// deprecated
45func testApp(t *testing.T, bp string) *android.TestContext {
46 t.Helper()
47 result := javaFixtureFactory.RunTestWithBp(t, bp)
48 return result.TestContext
49}
50
51func TestApp(t *testing.T) {
52 resourceFiles := []string{
Colin Cross3bc7ffa2017-11-22 16:19:37 -080053 "res/layout/layout.xml",
54 "res/values/strings.xml",
55 "res/values-en-rUS/strings.xml",
56 }
57
Paul Duffin0ed42d32021-03-13 02:19:32 +000058 compiledResourceFiles := []string{
Colin Cross3bc7ffa2017-11-22 16:19:37 -080059 "aapt2/res/layout_layout.xml.flat",
60 "aapt2/res/values_strings.arsc.flat",
61 "aapt2/res/values-en-rUS_strings.arsc.flat",
62 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -080063
Colin Crossa97c5d32018-03-28 14:58:31 -070064 for _, moduleType := range []string{"android_app", "android_library"} {
65 t.Run(moduleType, func(t *testing.T) {
Paul Duffin0ed42d32021-03-13 02:19:32 +000066 result := javaFixtureFactory.Extend(
67 android.FixtureModifyMockFS(func(fs android.MockFS) {
68 for _, file := range resourceFiles {
69 fs[file] = nil
70 }
71 }),
72 ).RunTestWithBp(t, moduleType+` {
Colin Crossa97c5d32018-03-28 14:58:31 -070073 name: "foo",
74 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +090075 sdk_version: "current"
Colin Crossa97c5d32018-03-28 14:58:31 -070076 }
77 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080078
Paul Duffin0ed42d32021-03-13 02:19:32 +000079 foo := result.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080080
Colin Cross31656952018-05-24 16:11:20 -070081 var expectedLinkImplicits []string
82
83 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
84 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080085
Paul Duffin0ed42d32021-03-13 02:19:32 +000086 frameworkRes := result.ModuleForTests("framework-res", "android_common")
Colin Crossa97c5d32018-03-28 14:58:31 -070087 expectedLinkImplicits = append(expectedLinkImplicits,
88 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080089
Colin Crossa97c5d32018-03-28 14:58:31 -070090 // Test the mapping from input files to compiled output file names
91 compile := foo.Output(compiledResourceFiles[0])
Paul Duffin0ed42d32021-03-13 02:19:32 +000092 android.AssertDeepEquals(t, "aapt2 compile inputs", resourceFiles, compile.Inputs.Strings())
Colin Crossb69301e2017-12-01 10:48:26 -080093
Colin Crossa97c5d32018-03-28 14:58:31 -070094 compiledResourceOutputs := compile.Outputs.Strings()
95 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -080096
Colin Crossa97c5d32018-03-28 14:58:31 -070097 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080098
Colin Crossa97c5d32018-03-28 14:58:31 -070099 list := foo.Output("aapt2/res.list")
100 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800101
Colin Crossa97c5d32018-03-28 14:58:31 -0700102 // Check that the link rule uses
Paul Duffin0ed42d32021-03-13 02:19:32 +0000103 res := result.ModuleForTests("foo", "android_common").Output("package-res.apk")
104 android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings())
Colin Crossa97c5d32018-03-28 14:58:31 -0700105 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800106 }
107}
Colin Cross890ff552017-11-30 20:13:19 -0800108
Colin Crosse560c4a2019-03-19 16:03:11 -0700109func TestAppSplits(t *testing.T) {
110 ctx := testApp(t, `
111 android_app {
112 name: "foo",
113 srcs: ["a.java"],
114 package_splits: ["v4", "v7,hdpi"],
Jeongik Cha538c0d02019-07-11 15:54:27 +0900115 sdk_version: "current"
Colin Crosse560c4a2019-03-19 16:03:11 -0700116 }`)
117
118 foo := ctx.ModuleForTests("foo", "android_common")
119
120 expectedOutputs := []string{
121 filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
122 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
123 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
124 }
125 for _, expectedOutput := range expectedOutputs {
126 foo.Output(expectedOutput)
127 }
128
Colin Cross41955e82019-05-29 14:40:35 -0700129 outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
130 if err != nil {
131 t.Fatal(err)
132 }
133 if g, w := outputFiles.Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
134 t.Errorf(`want OutputFiles("") = %q, got %q`, w, g)
Colin Crosse560c4a2019-03-19 16:03:11 -0700135 }
136}
137
Jeongik Cha538c0d02019-07-11 15:54:27 +0900138func TestPlatformAPIs(t *testing.T) {
139 testJava(t, `
140 android_app {
141 name: "foo",
142 srcs: ["a.java"],
143 platform_apis: true,
144 }
145 `)
146
147 testJava(t, `
148 android_app {
149 name: "foo",
150 srcs: ["a.java"],
151 sdk_version: "current",
152 }
153 `)
154
155 testJavaError(t, "platform_apis must be true when sdk_version is empty.", `
156 android_app {
157 name: "bar",
158 srcs: ["b.java"],
159 }
160 `)
161
162 testJavaError(t, "platform_apis must be false when sdk_version is not empty.", `
163 android_app {
164 name: "bar",
165 srcs: ["b.java"],
166 sdk_version: "system_current",
167 platform_apis: true,
168 }
169 `)
170}
171
Jeongik Chae403e9e2019-12-07 00:16:24 +0900172func TestAndroidAppLinkType(t *testing.T) {
173 testJava(t, `
174 android_app {
175 name: "foo",
176 srcs: ["a.java"],
177 libs: ["bar"],
178 static_libs: ["baz"],
179 platform_apis: true,
180 }
181
182 java_library {
183 name: "bar",
184 sdk_version: "current",
185 srcs: ["b.java"],
186 }
187
188 android_library {
189 name: "baz",
190 sdk_version: "system_current",
191 srcs: ["c.java"],
192 }
193 `)
194
Steven Moreland00298982020-11-17 21:44:36 +0000195 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900196 android_app {
197 name: "foo",
198 srcs: ["a.java"],
199 libs: ["bar"],
200 sdk_version: "current",
201 static_libs: ["baz"],
202 }
203
204 java_library {
205 name: "bar",
206 sdk_version: "current",
207 srcs: ["b.java"],
208 }
209
210 android_library {
211 name: "baz",
212 sdk_version: "system_current",
213 srcs: ["c.java"],
214 }
215 `)
216
217 testJava(t, `
218 android_app {
219 name: "foo",
220 srcs: ["a.java"],
221 libs: ["bar"],
222 sdk_version: "system_current",
223 static_libs: ["baz"],
224 }
225
226 java_library {
227 name: "bar",
228 sdk_version: "current",
229 srcs: ["b.java"],
230 }
231
232 android_library {
233 name: "baz",
234 sdk_version: "system_current",
235 srcs: ["c.java"],
236 }
237 `)
238
Steven Moreland00298982020-11-17 21:44:36 +0000239 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900240 android_app {
241 name: "foo",
242 srcs: ["a.java"],
243 libs: ["bar"],
244 sdk_version: "system_current",
245 static_libs: ["baz"],
246 }
247
248 java_library {
249 name: "bar",
250 sdk_version: "current",
251 srcs: ["b.java"],
252 }
253
254 android_library {
255 name: "baz",
256 srcs: ["c.java"],
257 }
258 `)
259}
260
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100261func TestUpdatableApps(t *testing.T) {
262 testCases := []struct {
263 name string
264 bp string
265 expectedError string
266 }{
267 {
268 name: "Stable public SDK",
269 bp: `android_app {
270 name: "foo",
271 srcs: ["a.java"],
272 sdk_version: "29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100273 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100274 updatable: true,
275 }`,
276 },
277 {
278 name: "Stable system SDK",
279 bp: `android_app {
280 name: "foo",
281 srcs: ["a.java"],
282 sdk_version: "system_29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100283 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100284 updatable: true,
285 }`,
286 },
287 {
288 name: "Current public SDK",
289 bp: `android_app {
290 name: "foo",
291 srcs: ["a.java"],
292 sdk_version: "current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100293 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100294 updatable: true,
295 }`,
296 },
297 {
298 name: "Current system SDK",
299 bp: `android_app {
300 name: "foo",
301 srcs: ["a.java"],
302 sdk_version: "system_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100303 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100304 updatable: true,
305 }`,
306 },
307 {
308 name: "Current module SDK",
309 bp: `android_app {
310 name: "foo",
311 srcs: ["a.java"],
312 sdk_version: "module_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100313 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100314 updatable: true,
315 }`,
316 },
317 {
318 name: "Current core SDK",
319 bp: `android_app {
320 name: "foo",
321 srcs: ["a.java"],
322 sdk_version: "core_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100323 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100324 updatable: true,
325 }`,
326 },
327 {
328 name: "No Platform APIs",
329 bp: `android_app {
330 name: "foo",
331 srcs: ["a.java"],
332 platform_apis: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100333 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100334 updatable: true,
335 }`,
336 expectedError: "Updatable apps must use stable SDKs",
337 },
338 {
339 name: "No Core Platform APIs",
340 bp: `android_app {
341 name: "foo",
342 srcs: ["a.java"],
343 sdk_version: "core_platform",
Artur Satayevf40fc852020-04-16 13:43:02 +0100344 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100345 updatable: true,
346 }`,
347 expectedError: "Updatable apps must use stable SDKs",
348 },
349 {
350 name: "No unspecified APIs",
351 bp: `android_app {
352 name: "foo",
353 srcs: ["a.java"],
354 updatable: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100355 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100356 }`,
357 expectedError: "Updatable apps must use stable SDK",
358 },
Artur Satayevf40fc852020-04-16 13:43:02 +0100359 {
360 name: "Must specify min_sdk_version",
361 bp: `android_app {
362 name: "app_without_min_sdk_version",
363 srcs: ["a.java"],
364 sdk_version: "29",
365 updatable: true,
366 }`,
367 expectedError: "updatable apps must set min_sdk_version.",
368 },
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100369 }
370
371 for _, test := range testCases {
372 t.Run(test.name, func(t *testing.T) {
373 if test.expectedError == "" {
374 testJava(t, test.bp)
375 } else {
376 testJavaError(t, test.expectedError, test.bp)
377 }
378 })
379 }
380}
381
Jooyung Han749dc692020-04-15 11:03:39 +0900382func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
383 testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
384 android_app {
385 name: "foo",
386 srcs: ["a.java"],
387 updatable: true,
388 sdk_version: "current",
389 min_sdk_version: "29",
390 static_libs: ["bar"],
391 }
392
393 java_library {
394 name: "bar",
395 sdk_version: "current",
396 }
397 `)
398}
399
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900400func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
401 testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
402 android_app {
403 name: "foo",
404 srcs: ["a.java"],
405 updatable: true,
406 sdk_version: "current",
407 min_sdk_version: "current",
408 jni_libs: ["libjni"],
409 }
410
411 cc_library {
412 name: "libjni",
413 stl: "none",
414 system_shared_libs: [],
415 sdk_version: "current",
416 }
417 `)
418}
419
420func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
421 bp := cc.GatherRequiredDepsForTest(android.Android) + `
422 android_app {
423 name: "foo",
424 srcs: ["a.java"],
425 updatable: true,
426 sdk_version: "current",
427 min_sdk_version: "29",
428 jni_libs: ["libjni"],
429 }
430
431 cc_library {
432 name: "libjni",
433 stl: "none",
434 system_shared_libs: [],
435 sdk_version: "29",
436 }
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900437 `
438 fs := map[string][]byte{
439 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
440 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": nil,
441 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o": nil,
442 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o": nil,
443 }
444
445 ctx, _ := testJavaWithConfig(t, testConfig(nil, bp, fs))
446
447 inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
448 var crtbeginFound, crtendFound bool
Dan Albert92fe7402020-07-15 13:33:30 -0700449 expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
450 "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
451 expectedCrtEnd := ctx.ModuleForTests("crtend_so",
452 "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
453 implicits := []string{}
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900454 for _, input := range inputs {
Dan Albert92fe7402020-07-15 13:33:30 -0700455 implicits = append(implicits, input.String())
456 if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900457 crtbeginFound = true
Dan Albert92fe7402020-07-15 13:33:30 -0700458 } else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900459 crtendFound = true
460 }
461 }
Dan Albert92fe7402020-07-15 13:33:30 -0700462 if !crtbeginFound {
463 t.Error(fmt.Sprintf(
464 "expected implicit with suffix %q, have the following implicits:\n%s",
465 expectedCrtBegin, strings.Join(implicits, "\n")))
466 }
467 if !crtendFound {
468 t.Error(fmt.Sprintf(
469 "expected implicit with suffix %q, have the following implicits:\n%s",
470 expectedCrtEnd, strings.Join(implicits, "\n")))
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900471 }
472}
473
474func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
475 bp := cc.GatherRequiredDepsForTest(android.Android) + `
476 android_app {
477 name: "foo",
478 srcs: ["a.java"],
479 updatable: true,
480 sdk_version: "current",
481 min_sdk_version: "29", // this APK should support 29
482 jni_libs: ["libjni"],
483 }
484
485 cc_library {
486 name: "libjni",
487 stl: "none",
488 sdk_version: "current",
489 }
490 `
491 testJavaError(t, `"libjni" .*: sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
492}
493
494func TestUpdatableApps_ErrorIfDepSdkVersionIsHigher(t *testing.T) {
495 bp := cc.GatherRequiredDepsForTest(android.Android) + `
496 android_app {
497 name: "foo",
498 srcs: ["a.java"],
499 updatable: true,
500 sdk_version: "current",
501 min_sdk_version: "29", // this APK should support 29
502 jni_libs: ["libjni"],
503 }
504
505 cc_library {
506 name: "libjni",
507 stl: "none",
508 shared_libs: ["libbar"],
509 system_shared_libs: [],
510 sdk_version: "27",
511 }
512
513 cc_library {
514 name: "libbar",
515 stl: "none",
516 system_shared_libs: [],
517 sdk_version: "current",
518 }
519 `
520 testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp)
521}
522
Colin Cross0ddae7f2019-02-07 15:30:01 -0800523func TestResourceDirs(t *testing.T) {
524 testCases := []struct {
525 name string
526 prop string
527 resources []string
528 }{
529 {
530 name: "no resource_dirs",
531 prop: "",
532 resources: []string{"res/res/values/strings.xml"},
533 },
534 {
535 name: "resource_dirs",
536 prop: `resource_dirs: ["res"]`,
537 resources: []string{"res/res/values/strings.xml"},
538 },
539 {
540 name: "empty resource_dirs",
541 prop: `resource_dirs: []`,
542 resources: nil,
543 },
544 }
545
546 fs := map[string][]byte{
547 "res/res/values/strings.xml": nil,
548 }
549
550 bp := `
551 android_app {
552 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900553 sdk_version: "current",
Colin Cross0ddae7f2019-02-07 15:30:01 -0800554 %s
555 }
556 `
557
558 for _, testCase := range testCases {
559 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800560 config := testConfig(nil, fmt.Sprintf(bp, testCase.prop), fs)
Colin Crossae8600b2020-10-29 17:09:13 -0700561 ctx := testContext(config)
Colin Cross0ddae7f2019-02-07 15:30:01 -0800562 run(t, ctx, config)
563
564 module := ctx.ModuleForTests("foo", "android_common")
565 resourceList := module.MaybeOutput("aapt2/res.list")
566
567 var resources []string
568 if resourceList.Rule != nil {
569 for _, compiledResource := range resourceList.Inputs.Strings() {
570 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
571 }
572 }
573
574 if !reflect.DeepEqual(resources, testCase.resources) {
575 t.Errorf("expected resource files %q, got %q",
576 testCase.resources, resources)
577 }
578 })
579 }
580}
581
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800582func TestLibraryAssets(t *testing.T) {
583 bp := `
584 android_app {
585 name: "foo",
586 sdk_version: "current",
587 static_libs: ["lib1", "lib2", "lib3"],
588 }
589
590 android_library {
591 name: "lib1",
592 sdk_version: "current",
593 asset_dirs: ["assets_a"],
594 }
595
596 android_library {
597 name: "lib2",
598 sdk_version: "current",
599 }
600
601 android_library {
602 name: "lib3",
603 sdk_version: "current",
604 static_libs: ["lib4"],
605 }
606
607 android_library {
608 name: "lib4",
609 sdk_version: "current",
610 asset_dirs: ["assets_b"],
611 }
612 `
613
614 testCases := []struct {
615 name string
616 assetFlag string
617 assetPackages []string
618 }{
619 {
620 name: "foo",
621 // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
622 assetPackages: []string{
623 buildDir + "/.intermediates/foo/android_common/aapt2/package-res.apk",
624 buildDir + "/.intermediates/lib1/android_common/assets.zip",
625 buildDir + "/.intermediates/lib3/android_common/assets.zip",
626 },
627 },
628 {
629 name: "lib1",
630 assetFlag: "-A assets_a",
631 },
632 {
633 name: "lib2",
634 },
635 {
636 name: "lib3",
637 assetPackages: []string{
638 buildDir + "/.intermediates/lib3/android_common/aapt2/package-res.apk",
639 buildDir + "/.intermediates/lib4/android_common/assets.zip",
640 },
641 },
642 {
643 name: "lib4",
644 assetFlag: "-A assets_b",
645 },
646 }
647 ctx := testApp(t, bp)
648
649 for _, test := range testCases {
650 t.Run(test.name, func(t *testing.T) {
651 m := ctx.ModuleForTests(test.name, "android_common")
652
653 // Check asset flag in aapt2 link flags
654 var aapt2link android.TestingBuildParams
655 if len(test.assetPackages) > 0 {
656 aapt2link = m.Output("aapt2/package-res.apk")
657 } else {
658 aapt2link = m.Output("package-res.apk")
659 }
660 aapt2Flags := aapt2link.Args["flags"]
661 if test.assetFlag != "" {
662 if !strings.Contains(aapt2Flags, test.assetFlag) {
663 t.Errorf("Can't find asset flag %q in aapt2 link flags %q", test.assetFlag, aapt2Flags)
664 }
665 } else {
666 if strings.Contains(aapt2Flags, " -A ") {
667 t.Errorf("aapt2 link flags %q contain unexpected asset flag", aapt2Flags)
668 }
669 }
670
671 // Check asset merge rule.
672 if len(test.assetPackages) > 0 {
673 mergeAssets := m.Output("package-res.apk")
674 if !reflect.DeepEqual(test.assetPackages, mergeAssets.Inputs.Strings()) {
675 t.Errorf("Unexpected mergeAssets inputs: %v, expected: %v",
676 mergeAssets.Inputs.Strings(), test.assetPackages)
677 }
678 }
679 })
680 }
681}
682
Colin Crossb014f072021-02-26 14:54:36 -0800683func TestAppJavaResources(t *testing.T) {
684 bp := `
685 android_app {
686 name: "foo",
687 sdk_version: "current",
688 java_resources: ["resources/a"],
689 srcs: ["a.java"],
690 }
691
692 android_app {
693 name: "bar",
694 sdk_version: "current",
695 java_resources: ["resources/a"],
696 }
697 `
698
699 ctx := testApp(t, bp)
700
701 foo := ctx.ModuleForTests("foo", "android_common")
702 fooResources := foo.Output("res/foo.jar")
703 fooDexJar := foo.Output("dex-withres/foo.jar")
704 fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
705 fooApk := foo.Rule("combineApk")
706
707 if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) {
708 t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g)
709 }
710
711 if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w {
712 t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g)
713 }
714
715 if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) {
716 t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
717 }
718
719 bar := ctx.ModuleForTests("bar", "android_common")
720 barResources := bar.Output("res/bar.jar")
721 barApk := bar.Rule("combineApk")
722
723 if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) {
724 t.Errorf("expected resources jar %q in bar apk inputs %q", w, g)
725 }
726}
727
Colin Crossbec85302019-02-13 13:15:46 -0800728func TestAndroidResources(t *testing.T) {
Colin Cross5c4791c2019-02-01 11:44:44 -0800729 testCases := []struct {
730 name string
731 enforceRROTargets []string
732 enforceRROExcludedOverlays []string
Colin Crossbec85302019-02-13 13:15:46 -0800733 resourceFiles map[string][]string
Colin Cross5c4791c2019-02-01 11:44:44 -0800734 overlayFiles map[string][]string
735 rroDirs map[string][]string
736 }{
737 {
738 name: "no RRO",
739 enforceRROTargets: nil,
740 enforceRROExcludedOverlays: nil,
Colin Crossbec85302019-02-13 13:15:46 -0800741 resourceFiles: map[string][]string{
742 "foo": nil,
743 "bar": {"bar/res/res/values/strings.xml"},
744 "lib": nil,
745 "lib2": {"lib2/res/res/values/strings.xml"},
746 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800747 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800748 "foo": {
749 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800750 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000751 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800752 "foo/res/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800753 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
754 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Anton Hansson53c88442019-03-18 15:53:16 +0000755 "product/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800756 },
Colin Crossbec85302019-02-13 13:15:46 -0800757 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800758 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
759 "device/vendor/blah/overlay/bar/res/values/strings.xml",
760 },
Colin Crossbec85302019-02-13 13:15:46 -0800761 "lib": {
762 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
763 "lib/res/res/values/strings.xml",
764 "device/vendor/blah/overlay/lib/res/values/strings.xml",
765 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800766 },
767 rroDirs: map[string][]string{
768 "foo": nil,
769 "bar": nil,
770 },
771 },
772 {
773 name: "enforce RRO on foo",
774 enforceRROTargets: []string{"foo"},
775 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossbec85302019-02-13 13:15:46 -0800776 resourceFiles: map[string][]string{
777 "foo": nil,
778 "bar": {"bar/res/res/values/strings.xml"},
779 "lib": nil,
780 "lib2": {"lib2/res/res/values/strings.xml"},
781 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800782 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800783 "foo": {
784 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800785 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000786 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800787 "foo/res/res/values/strings.xml",
788 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
789 },
Colin Crossbec85302019-02-13 13:15:46 -0800790 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800791 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
792 "device/vendor/blah/overlay/bar/res/values/strings.xml",
793 },
Colin Crossbec85302019-02-13 13:15:46 -0800794 "lib": {
795 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
796 "lib/res/res/values/strings.xml",
Colin Crossbec85302019-02-13 13:15:46 -0800797 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800798 },
Colin Crossc1c37552019-01-31 11:42:41 -0800799
Colin Cross5c4791c2019-02-01 11:44:44 -0800800 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800801 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000802 "device:device/vendor/blah/overlay/foo/res",
Anton Hansson53c88442019-03-18 15:53:16 +0000803 "product:product/vendor/blah/overlay/foo/res",
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700804 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800805 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800806 "bar": nil,
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700807 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800808 },
809 },
810 {
811 name: "enforce RRO on all",
812 enforceRROTargets: []string{"*"},
813 enforceRROExcludedOverlays: []string{
814 // Excluding specific apps/res directories also allowed.
815 "device/vendor/blah/static_overlay/foo",
816 "device/vendor/blah/static_overlay/bar/res",
817 },
Colin Crossbec85302019-02-13 13:15:46 -0800818 resourceFiles: map[string][]string{
819 "foo": nil,
820 "bar": {"bar/res/res/values/strings.xml"},
821 "lib": nil,
822 "lib2": {"lib2/res/res/values/strings.xml"},
823 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800824 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800825 "foo": {
826 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800827 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000828 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800829 "foo/res/res/values/strings.xml",
830 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
831 },
Colin Crossbec85302019-02-13 13:15:46 -0800832 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
833 "lib": {
834 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
835 "lib/res/res/values/strings.xml",
836 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800837 },
838 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800839 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000840 "device:device/vendor/blah/overlay/foo/res",
841 "product:product/vendor/blah/overlay/foo/res",
842 // Lib dep comes after the direct deps
843 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800844 },
Anton Hansson53c88442019-03-18 15:53:16 +0000845 "bar": {"device:device/vendor/blah/overlay/bar/res"},
846 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800847 },
848 },
849 }
850
Anton Hansson53c88442019-03-18 15:53:16 +0000851 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -0800852 "device/vendor/blah/overlay",
853 "device/vendor/blah/overlay2",
854 "device/vendor/blah/static_overlay",
855 }
856
Anton Hansson53c88442019-03-18 15:53:16 +0000857 productResourceOverlays := []string{
858 "product/vendor/blah/overlay",
859 }
860
Colin Cross890ff552017-11-30 20:13:19 -0800861 fs := map[string][]byte{
862 "foo/res/res/values/strings.xml": nil,
863 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800864 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800865 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800866 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
867 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800868 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800869 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
870 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
871 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +0000872 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800873 }
874
875 bp := `
876 android_app {
877 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900878 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800879 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +0000880 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -0800881 }
882
883 android_app {
884 name: "bar",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900885 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800886 resource_dirs: ["bar/res"],
887 }
Colin Cross6ed7dea2019-01-31 14:44:30 -0800888
889 android_library {
890 name: "lib",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900891 sdk_version: "current",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800892 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -0800893 static_libs: ["lib2"],
894 }
895
896 android_library {
897 name: "lib2",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900898 sdk_version: "current",
Colin Crossbec85302019-02-13 13:15:46 -0800899 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -0800900 }
Anton Hansson53c88442019-03-18 15:53:16 +0000901
902 // This library has the same resources as lib (should not lead to dupe RROs)
903 android_library {
904 name: "lib3",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900905 sdk_version: "current",
Anton Hansson53c88442019-03-18 15:53:16 +0000906 resource_dirs: ["lib/res"]
907 }
Colin Cross890ff552017-11-30 20:13:19 -0800908 `
909
Colin Cross5c4791c2019-02-01 11:44:44 -0800910 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -0800911 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800912 config := testAppConfig(nil, bp, fs)
Anton Hansson53c88442019-03-18 15:53:16 +0000913 config.TestProductVariables.DeviceResourceOverlays = deviceResourceOverlays
914 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800915 if testCase.enforceRROTargets != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800916 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800917 }
918 if testCase.enforceRROExcludedOverlays != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800919 config.TestProductVariables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800920 }
921
Colin Crossae8600b2020-10-29 17:09:13 -0700922 ctx := testContext(config)
Colin Cross890ff552017-11-30 20:13:19 -0800923 run(t, ctx, config)
924
Colin Crossbec85302019-02-13 13:15:46 -0800925 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
926 for _, o := range list {
927 res := module.MaybeOutput(o)
928 if res.Rule != nil {
929 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
930 // verify the inputs to the .arsc.flat rule.
931 files = append(files, res.Inputs.Strings()...)
932 } else {
933 // Otherwise, verify the full path to the output of the other module
934 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +0000935 }
Colin Cross890ff552017-11-30 20:13:19 -0800936 }
Colin Crossbec85302019-02-13 13:15:46 -0800937 return files
Colin Cross890ff552017-11-30 20:13:19 -0800938 }
939
Colin Crossbec85302019-02-13 13:15:46 -0800940 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
941 module := ctx.ModuleForTests(moduleName, "android_common")
942 resourceList := module.MaybeOutput("aapt2/res.list")
943 if resourceList.Rule != nil {
944 resourceFiles = resourceListToFiles(module, resourceList.Inputs.Strings())
Anton Hansson0375a4f2019-01-24 14:39:19 +0000945 }
Colin Crossbec85302019-02-13 13:15:46 -0800946 overlayList := module.MaybeOutput("aapt2/overlay.list")
947 if overlayList.Rule != nil {
948 overlayFiles = resourceListToFiles(module, overlayList.Inputs.Strings())
949 }
950
Anton Hansson53c88442019-03-18 15:53:16 +0000951 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
952 var prefix string
953 if d.overlayType == device {
954 prefix = "device:"
955 } else if d.overlayType == product {
956 prefix = "product:"
957 } else {
958 t.Fatalf("Unexpected overlayType %d", d.overlayType)
959 }
960 rroDirs = append(rroDirs, prefix+d.path.String())
961 }
Colin Crossbec85302019-02-13 13:15:46 -0800962
963 return resourceFiles, overlayFiles, rroDirs
964 }
965
966 modules := []string{"foo", "bar", "lib", "lib2"}
967 for _, module := range modules {
968 resourceFiles, overlayFiles, rroDirs := getResources(module)
969
970 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
971 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
972 module, testCase.resourceFiles[module], resourceFiles)
973 }
974 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
975 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
976 module, testCase.overlayFiles[module], overlayFiles)
977 }
978 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +0000979 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossbec85302019-02-13 13:15:46 -0800980 module, testCase.rroDirs[module], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +0000981 }
Colin Cross890ff552017-11-30 20:13:19 -0800982 }
Colin Cross890ff552017-11-30 20:13:19 -0800983 })
984 }
985}
Colin Crossd09b0b62018-04-18 11:06:47 -0700986
Jeongik Cha219141c2020-08-06 23:00:37 +0900987func checkSdkVersion(t *testing.T, config android.Config, expectedSdkVersion string) {
Colin Crossae8600b2020-10-29 17:09:13 -0700988 ctx := testContext(config)
Jeongik Cha219141c2020-08-06 23:00:37 +0900989
990 run(t, ctx, config)
991
992 foo := ctx.ModuleForTests("foo", "android_common")
993 link := foo.Output("package-res.apk")
994 linkFlags := strings.Split(link.Args["flags"], " ")
995 min := android.IndexList("--min-sdk-version", linkFlags)
996 target := android.IndexList("--target-sdk-version", linkFlags)
997
998 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
999 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
1000 }
1001
1002 gotMinSdkVersion := linkFlags[min+1]
1003 gotTargetSdkVersion := linkFlags[target+1]
1004
1005 if gotMinSdkVersion != expectedSdkVersion {
1006 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
1007 expectedSdkVersion, gotMinSdkVersion)
1008 }
1009
1010 if gotTargetSdkVersion != expectedSdkVersion {
1011 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
1012 expectedSdkVersion, gotTargetSdkVersion)
1013 }
1014}
1015
Colin Crossd09b0b62018-04-18 11:06:47 -07001016func TestAppSdkVersion(t *testing.T) {
1017 testCases := []struct {
1018 name string
1019 sdkVersion string
1020 platformSdkInt int
1021 platformSdkCodename string
1022 platformSdkFinal bool
1023 expectedMinSdkVersion string
Jeongik Cha538c0d02019-07-11 15:54:27 +09001024 platformApis bool
Dan Albert4f378d72020-07-23 17:32:15 -07001025 activeCodenames []string
Colin Crossd09b0b62018-04-18 11:06:47 -07001026 }{
1027 {
1028 name: "current final SDK",
1029 sdkVersion: "current",
1030 platformSdkInt: 27,
1031 platformSdkCodename: "REL",
1032 platformSdkFinal: true,
1033 expectedMinSdkVersion: "27",
1034 },
1035 {
1036 name: "current non-final SDK",
1037 sdkVersion: "current",
1038 platformSdkInt: 27,
1039 platformSdkCodename: "OMR1",
1040 platformSdkFinal: false,
1041 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001042 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001043 },
1044 {
1045 name: "default final SDK",
1046 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001047 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001048 platformSdkInt: 27,
1049 platformSdkCodename: "REL",
1050 platformSdkFinal: true,
1051 expectedMinSdkVersion: "27",
1052 },
1053 {
1054 name: "default non-final SDK",
1055 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001056 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001057 platformSdkInt: 27,
1058 platformSdkCodename: "OMR1",
1059 platformSdkFinal: false,
1060 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001061 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001062 },
1063 {
1064 name: "14",
1065 sdkVersion: "14",
1066 expectedMinSdkVersion: "14",
Dan Albert4f378d72020-07-23 17:32:15 -07001067 platformSdkCodename: "S",
1068 activeCodenames: []string{"S"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001069 },
1070 }
1071
1072 for _, moduleType := range []string{"android_app", "android_library"} {
1073 for _, test := range testCases {
1074 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Jeongik Cha538c0d02019-07-11 15:54:27 +09001075 platformApiProp := ""
1076 if test.platformApis {
1077 platformApiProp = "platform_apis: true,"
1078 }
Colin Crossd09b0b62018-04-18 11:06:47 -07001079 bp := fmt.Sprintf(`%s {
1080 name: "foo",
1081 srcs: ["a.java"],
1082 sdk_version: "%s",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001083 %s
1084 }`, moduleType, test.sdkVersion, platformApiProp)
Colin Crossd09b0b62018-04-18 11:06:47 -07001085
Colin Cross98be1bb2019-12-13 20:41:13 -08001086 config := testAppConfig(nil, bp, nil)
Colin Crossd09b0b62018-04-18 11:06:47 -07001087 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
1088 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
Dan Albert4f378d72020-07-23 17:32:15 -07001089 config.TestProductVariables.Platform_version_active_codenames = test.activeCodenames
Colin Crossd09b0b62018-04-18 11:06:47 -07001090 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
Jeongik Cha219141c2020-08-06 23:00:37 +09001091 checkSdkVersion(t, config, test.expectedMinSdkVersion)
Colin Crossd09b0b62018-04-18 11:06:47 -07001092
Colin Crossd09b0b62018-04-18 11:06:47 -07001093 })
1094 }
1095 }
1096}
Colin Crossa4f08812018-10-02 22:03:40 -07001097
Jeongik Cha219141c2020-08-06 23:00:37 +09001098func TestVendorAppSdkVersion(t *testing.T) {
1099 testCases := []struct {
1100 name string
1101 sdkVersion string
1102 platformSdkInt int
1103 platformSdkCodename string
1104 platformSdkFinal bool
1105 deviceCurrentApiLevelForVendorModules string
1106 expectedMinSdkVersion string
1107 }{
1108 {
1109 name: "current final SDK",
1110 sdkVersion: "current",
1111 platformSdkInt: 29,
1112 platformSdkCodename: "REL",
1113 platformSdkFinal: true,
1114 deviceCurrentApiLevelForVendorModules: "29",
1115 expectedMinSdkVersion: "29",
1116 },
1117 {
1118 name: "current final SDK",
1119 sdkVersion: "current",
1120 platformSdkInt: 29,
1121 platformSdkCodename: "REL",
1122 platformSdkFinal: true,
1123 deviceCurrentApiLevelForVendorModules: "28",
1124 expectedMinSdkVersion: "28",
1125 },
1126 {
1127 name: "current final SDK",
1128 sdkVersion: "current",
1129 platformSdkInt: 29,
1130 platformSdkCodename: "Q",
1131 platformSdkFinal: false,
Jeongik Cha219141c2020-08-06 23:00:37 +09001132 deviceCurrentApiLevelForVendorModules: "28",
1133 expectedMinSdkVersion: "28",
1134 },
1135 }
1136
1137 for _, moduleType := range []string{"android_app", "android_library"} {
1138 for _, sdkKind := range []string{"", "system_"} {
1139 for _, test := range testCases {
1140 t.Run(moduleType+" "+test.name, func(t *testing.T) {
1141 bp := fmt.Sprintf(`%s {
1142 name: "foo",
1143 srcs: ["a.java"],
1144 sdk_version: "%s%s",
1145 vendor: true,
1146 }`, moduleType, sdkKind, test.sdkVersion)
1147
1148 config := testAppConfig(nil, bp, nil)
1149 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
1150 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
1151 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
1152 config.TestProductVariables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
1153 config.TestProductVariables.DeviceSystemSdkVersions = []string{"28", "29"}
1154 checkSdkVersion(t, config, test.expectedMinSdkVersion)
1155 })
1156 }
1157 }
1158 }
1159}
1160
Paul Duffin50c217c2019-06-12 13:25:22 +01001161func TestJNIABI(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001162 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001163 cc_library {
1164 name: "libjni",
1165 system_shared_libs: [],
Colin Crossc511bc52020-04-07 16:50:32 +00001166 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001167 stl: "none",
1168 }
1169
1170 android_test {
1171 name: "test",
1172 sdk_version: "core_platform",
1173 jni_libs: ["libjni"],
1174 }
1175
1176 android_test {
1177 name: "test_first",
1178 sdk_version: "core_platform",
1179 compile_multilib: "first",
1180 jni_libs: ["libjni"],
1181 }
1182
1183 android_test {
1184 name: "test_both",
1185 sdk_version: "core_platform",
1186 compile_multilib: "both",
1187 jni_libs: ["libjni"],
1188 }
1189
1190 android_test {
1191 name: "test_32",
1192 sdk_version: "core_platform",
1193 compile_multilib: "32",
1194 jni_libs: ["libjni"],
1195 }
1196
1197 android_test {
1198 name: "test_64",
1199 sdk_version: "core_platform",
1200 compile_multilib: "64",
1201 jni_libs: ["libjni"],
1202 }
1203 `)
1204
1205 testCases := []struct {
1206 name string
1207 abis []string
1208 }{
1209 {"test", []string{"arm64-v8a"}},
1210 {"test_first", []string{"arm64-v8a"}},
1211 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
1212 {"test_32", []string{"armeabi-v7a"}},
1213 {"test_64", []string{"arm64-v8a"}},
1214 }
1215
1216 for _, test := range testCases {
1217 t.Run(test.name, func(t *testing.T) {
1218 app := ctx.ModuleForTests(test.name, "android_common")
1219 jniLibZip := app.Output("jnilibs.zip")
1220 var abis []string
1221 args := strings.Fields(jniLibZip.Args["jarArgs"])
1222 for i := 0; i < len(args); i++ {
1223 if args[i] == "-P" {
1224 abis = append(abis, filepath.Base(args[i+1]))
1225 i++
1226 }
1227 }
1228 if !reflect.DeepEqual(abis, test.abis) {
1229 t.Errorf("want abis %v, got %v", test.abis, abis)
1230 }
1231 })
1232 }
1233}
1234
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001235func TestAppSdkVersionByPartition(t *testing.T) {
1236 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
1237 android_app {
1238 name: "foo",
1239 srcs: ["a.java"],
1240 vendor: true,
1241 platform_apis: true,
1242 }
1243 `)
1244
1245 testJava(t, `
1246 android_app {
1247 name: "bar",
1248 srcs: ["b.java"],
1249 platform_apis: true,
1250 }
1251 `)
1252
1253 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001254 bp := `
1255 android_app {
1256 name: "foo",
1257 srcs: ["a.java"],
1258 product_specific: true,
1259 platform_apis: true,
1260 }
1261 `
Colin Cross98be1bb2019-12-13 20:41:13 -08001262
1263 config := testAppConfig(nil, bp, nil)
1264 config.TestProductVariables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001265 if enforce {
Colin Cross98be1bb2019-12-13 20:41:13 -08001266 testJavaErrorWithConfig(t, "sdk_version must have a value when the module is located at vendor or product", config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001267 } else {
Colin Cross98be1bb2019-12-13 20:41:13 -08001268 testJavaWithConfig(t, config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001269 }
1270 }
1271}
1272
Paul Duffin50c217c2019-06-12 13:25:22 +01001273func TestJNIPackaging(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001274 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001275 cc_library {
1276 name: "libjni",
1277 system_shared_libs: [],
1278 stl: "none",
Colin Cross094cde42020-02-15 10:38:00 -08001279 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001280 }
1281
1282 android_app {
1283 name: "app",
1284 jni_libs: ["libjni"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001285 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001286 }
1287
1288 android_app {
1289 name: "app_noembed",
1290 jni_libs: ["libjni"],
1291 use_embedded_native_libs: false,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001292 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001293 }
1294
1295 android_app {
1296 name: "app_embed",
1297 jni_libs: ["libjni"],
1298 use_embedded_native_libs: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001299 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001300 }
1301
1302 android_test {
1303 name: "test",
Colin Crossc511bc52020-04-07 16:50:32 +00001304 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001305 jni_libs: ["libjni"],
1306 }
1307
1308 android_test {
1309 name: "test_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00001310 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001311 jni_libs: ["libjni"],
1312 use_embedded_native_libs: false,
1313 }
1314
1315 android_test_helper_app {
1316 name: "test_helper",
Colin Crossc511bc52020-04-07 16:50:32 +00001317 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001318 jni_libs: ["libjni"],
1319 }
1320
1321 android_test_helper_app {
1322 name: "test_helper_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00001323 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001324 jni_libs: ["libjni"],
1325 use_embedded_native_libs: false,
1326 }
1327 `)
1328
1329 testCases := []struct {
1330 name string
1331 packaged bool
1332 compressed bool
1333 }{
1334 {"app", false, false},
1335 {"app_noembed", false, false},
1336 {"app_embed", true, false},
1337 {"test", true, false},
1338 {"test_noembed", true, true},
1339 {"test_helper", true, false},
1340 {"test_helper_noembed", true, true},
1341 }
1342
1343 for _, test := range testCases {
1344 t.Run(test.name, func(t *testing.T) {
1345 app := ctx.ModuleForTests(test.name, "android_common")
1346 jniLibZip := app.MaybeOutput("jnilibs.zip")
1347 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
1348 t.Errorf("expected jni packaged %v, got %v", w, g)
1349 }
1350
1351 if jniLibZip.Rule != nil {
1352 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
1353 t.Errorf("expected jni compressed %v, got %v", w, g)
1354 }
Colin Crossc511bc52020-04-07 16:50:32 +00001355
1356 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
1357 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
1358 }
Paul Duffin50c217c2019-06-12 13:25:22 +01001359 }
1360 })
1361 }
Colin Cross47fa9d32019-03-26 10:51:39 -07001362}
1363
Colin Cross3c007702020-05-08 11:20:24 -07001364func TestJNISDK(t *testing.T) {
1365 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
1366 cc_library {
1367 name: "libjni",
1368 system_shared_libs: [],
1369 stl: "none",
1370 sdk_version: "current",
1371 }
1372
1373 android_test {
1374 name: "app_platform",
1375 jni_libs: ["libjni"],
1376 platform_apis: true,
1377 }
1378
1379 android_test {
1380 name: "app_sdk",
1381 jni_libs: ["libjni"],
1382 sdk_version: "current",
1383 }
1384
1385 android_test {
1386 name: "app_force_platform",
1387 jni_libs: ["libjni"],
1388 sdk_version: "current",
1389 jni_uses_platform_apis: true,
1390 }
1391
1392 android_test {
1393 name: "app_force_sdk",
1394 jni_libs: ["libjni"],
1395 platform_apis: true,
1396 jni_uses_sdk_apis: true,
1397 }
Colin Crossc2d24052020-05-13 11:05:02 -07001398
1399 cc_library {
1400 name: "libvendorjni",
1401 system_shared_libs: [],
1402 stl: "none",
1403 vendor: true,
1404 }
1405
1406 android_test {
1407 name: "app_vendor",
1408 jni_libs: ["libvendorjni"],
1409 sdk_version: "current",
1410 vendor: true,
1411 }
Colin Cross3c007702020-05-08 11:20:24 -07001412 `)
1413
1414 testCases := []struct {
Colin Crossc2d24052020-05-13 11:05:02 -07001415 name string
1416 sdkJNI bool
1417 vendorJNI bool
Colin Cross3c007702020-05-08 11:20:24 -07001418 }{
Colin Crossc2d24052020-05-13 11:05:02 -07001419 {name: "app_platform"},
1420 {name: "app_sdk", sdkJNI: true},
1421 {name: "app_force_platform"},
1422 {name: "app_force_sdk", sdkJNI: true},
1423 {name: "app_vendor", vendorJNI: true},
Colin Cross3c007702020-05-08 11:20:24 -07001424 }
1425
Colin Crossc2d24052020-05-13 11:05:02 -07001426 platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared").
1427 Output("libjni.so").Output.String()
1428 sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
1429 Output("libjni.so").Output.String()
1430 vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared").
1431 Output("libvendorjni.so").Output.String()
1432
Colin Cross3c007702020-05-08 11:20:24 -07001433 for _, test := range testCases {
1434 t.Run(test.name, func(t *testing.T) {
1435 app := ctx.ModuleForTests(test.name, "android_common")
Colin Cross3c007702020-05-08 11:20:24 -07001436
1437 jniLibZip := app.MaybeOutput("jnilibs.zip")
1438 if len(jniLibZip.Implicits) != 1 {
1439 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
1440 }
1441 gotJNI := jniLibZip.Implicits[0].String()
1442
1443 if test.sdkJNI {
1444 if gotJNI != sdkJNI {
1445 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI)
1446 }
Colin Crossc2d24052020-05-13 11:05:02 -07001447 } else if test.vendorJNI {
1448 if gotJNI != vendorJNI {
1449 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI)
1450 }
Colin Cross3c007702020-05-08 11:20:24 -07001451 } else {
1452 if gotJNI != platformJNI {
1453 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI)
1454 }
1455 }
1456 })
1457 }
1458
1459 t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
1460 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
1461 android_test {
1462 name: "app_platform",
1463 platform_apis: true,
1464 jni_uses_platform_apis: true,
1465 }
1466 `)
1467 })
1468
1469 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
1470 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
1471 android_test {
1472 name: "app_sdk",
1473 sdk_version: "current",
1474 jni_uses_sdk_apis: true,
1475 }
1476 `)
1477 })
1478
1479}
1480
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001481func TestCertificates(t *testing.T) {
1482 testCases := []struct {
1483 name string
1484 bp string
1485 certificateOverride string
Liz Kammere2b27f42020-05-07 13:24:05 -07001486 expectedLineage string
1487 expectedCertificate string
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001488 }{
1489 {
1490 name: "default",
1491 bp: `
1492 android_app {
1493 name: "foo",
1494 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001495 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001496 }
1497 `,
1498 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001499 expectedLineage: "",
1500 expectedCertificate: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001501 },
1502 {
1503 name: "module certificate property",
1504 bp: `
1505 android_app {
1506 name: "foo",
1507 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001508 certificate: ":new_certificate",
1509 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001510 }
1511
1512 android_app_certificate {
1513 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07001514 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001515 }
1516 `,
1517 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001518 expectedLineage: "",
1519 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001520 },
1521 {
1522 name: "path certificate property",
1523 bp: `
1524 android_app {
1525 name: "foo",
1526 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001527 certificate: "expiredkey",
1528 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001529 }
1530 `,
1531 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001532 expectedLineage: "",
1533 expectedCertificate: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001534 },
1535 {
1536 name: "certificate overrides",
1537 bp: `
1538 android_app {
1539 name: "foo",
1540 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001541 certificate: "expiredkey",
1542 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001543 }
1544
1545 android_app_certificate {
1546 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07001547 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001548 }
1549 `,
1550 certificateOverride: "foo:new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07001551 expectedLineage: "",
1552 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
1553 },
1554 {
1555 name: "certificate lineage",
1556 bp: `
1557 android_app {
1558 name: "foo",
1559 srcs: ["a.java"],
1560 certificate: ":new_certificate",
1561 lineage: "lineage.bin",
1562 sdk_version: "current",
1563 }
1564
1565 android_app_certificate {
1566 name: "new_certificate",
1567 certificate: "cert/new_cert",
1568 }
1569 `,
1570 certificateOverride: "",
1571 expectedLineage: "--lineage lineage.bin",
1572 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001573 },
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08001574 {
1575 name: "lineage from filegroup",
1576 bp: `
1577 android_app {
1578 name: "foo",
1579 srcs: ["a.java"],
1580 certificate: ":new_certificate",
1581 lineage: ":lineage_bin",
1582 sdk_version: "current",
1583 }
1584
1585 android_app_certificate {
1586 name: "new_certificate",
1587 certificate: "cert/new_cert",
1588 }
1589
1590 filegroup {
1591 name: "lineage_bin",
1592 srcs: ["lineage.bin"],
1593 }
1594 `,
1595 certificateOverride: "",
1596 expectedLineage: "--lineage lineage.bin",
1597 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
1598 },
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001599 }
1600
1601 for _, test := range testCases {
1602 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001603 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001604 if test.certificateOverride != "" {
1605 config.TestProductVariables.CertificateOverrides = []string{test.certificateOverride}
1606 }
Colin Crossae8600b2020-10-29 17:09:13 -07001607 ctx := testContext(config)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001608
1609 run(t, ctx, config)
1610 foo := ctx.ModuleForTests("foo", "android_common")
1611
1612 signapk := foo.Output("foo.apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07001613 signCertificateFlags := signapk.Args["certificates"]
1614 if test.expectedCertificate != signCertificateFlags {
1615 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedCertificate, signCertificateFlags)
1616 }
1617
1618 signFlags := signapk.Args["flags"]
1619 if test.expectedLineage != signFlags {
1620 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedLineage, signFlags)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001621 }
1622 })
1623 }
1624}
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001625
Songchun Fan688de9a2020-03-24 20:32:24 -07001626func TestRequestV4SigningFlag(t *testing.T) {
1627 testCases := []struct {
1628 name string
1629 bp string
1630 expected string
1631 }{
1632 {
1633 name: "default",
1634 bp: `
1635 android_app {
1636 name: "foo",
1637 srcs: ["a.java"],
1638 sdk_version: "current",
1639 }
1640 `,
1641 expected: "",
1642 },
1643 {
1644 name: "default",
1645 bp: `
1646 android_app {
1647 name: "foo",
1648 srcs: ["a.java"],
1649 sdk_version: "current",
1650 v4_signature: false,
1651 }
1652 `,
1653 expected: "",
1654 },
1655 {
1656 name: "module certificate property",
1657 bp: `
1658 android_app {
1659 name: "foo",
1660 srcs: ["a.java"],
1661 sdk_version: "current",
1662 v4_signature: true,
1663 }
1664 `,
1665 expected: "--enable-v4",
1666 },
1667 }
1668
1669 for _, test := range testCases {
1670 t.Run(test.name, func(t *testing.T) {
1671 config := testAppConfig(nil, test.bp, nil)
Colin Crossae8600b2020-10-29 17:09:13 -07001672 ctx := testContext(config)
Songchun Fan688de9a2020-03-24 20:32:24 -07001673
1674 run(t, ctx, config)
1675 foo := ctx.ModuleForTests("foo", "android_common")
1676
1677 signapk := foo.Output("foo.apk")
1678 signFlags := signapk.Args["flags"]
1679 if test.expected != signFlags {
1680 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
1681 }
1682 })
1683 }
1684}
1685
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001686func TestPackageNameOverride(t *testing.T) {
1687 testCases := []struct {
1688 name string
1689 bp string
1690 packageNameOverride string
1691 expected []string
1692 }{
1693 {
1694 name: "default",
1695 bp: `
1696 android_app {
1697 name: "foo",
1698 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001699 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001700 }
1701 `,
1702 packageNameOverride: "",
1703 expected: []string{
1704 buildDir + "/.intermediates/foo/android_common/foo.apk",
1705 buildDir + "/target/product/test_device/system/app/foo/foo.apk",
1706 },
1707 },
1708 {
1709 name: "overridden",
1710 bp: `
1711 android_app {
1712 name: "foo",
1713 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001714 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001715 }
1716 `,
1717 packageNameOverride: "foo:bar",
1718 expected: []string{
1719 // The package apk should be still be the original name for test dependencies.
Jaewoong Jung5a498812019-11-07 14:14:38 -08001720 buildDir + "/.intermediates/foo/android_common/bar.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001721 buildDir + "/target/product/test_device/system/app/bar/bar.apk",
1722 },
1723 },
1724 }
1725
1726 for _, test := range testCases {
1727 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001728 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001729 if test.packageNameOverride != "" {
1730 config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
1731 }
Colin Crossae8600b2020-10-29 17:09:13 -07001732 ctx := testContext(config)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001733
1734 run(t, ctx, config)
1735 foo := ctx.ModuleForTests("foo", "android_common")
1736
1737 outputs := foo.AllOutputs()
1738 outputMap := make(map[string]bool)
1739 for _, o := range outputs {
1740 outputMap[o] = true
1741 }
1742 for _, e := range test.expected {
1743 if _, exist := outputMap[e]; !exist {
1744 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
1745 }
1746 }
1747 })
1748 }
1749}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001750
1751func TestInstrumentationTargetOverridden(t *testing.T) {
1752 bp := `
1753 android_app {
1754 name: "foo",
1755 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001756 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001757 }
1758
1759 android_test {
1760 name: "bar",
1761 instrumentation_for: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001762 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001763 }
1764 `
Colin Cross98be1bb2019-12-13 20:41:13 -08001765 config := testAppConfig(nil, bp, nil)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001766 config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
Colin Crossae8600b2020-10-29 17:09:13 -07001767 ctx := testContext(config)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001768
1769 run(t, ctx, config)
1770
1771 bar := ctx.ModuleForTests("bar", "android_common")
1772 res := bar.Output("package-res.apk")
1773 aapt2Flags := res.Args["flags"]
1774 e := "--rename-instrumentation-target-package org.dandroid.bp"
1775 if !strings.Contains(aapt2Flags, e) {
1776 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
1777 }
1778}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001779
1780func TestOverrideAndroidApp(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001781 ctx, _ := testJava(t, `
Jaewoong Jung525443a2019-02-28 15:35:54 -08001782 android_app {
1783 name: "foo",
1784 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -07001785 certificate: "expiredkey",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001786 overrides: ["qux"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001787 sdk_version: "current",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001788 }
1789
1790 override_android_app {
1791 name: "bar",
1792 base: "foo",
1793 certificate: ":new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07001794 lineage: "lineage.bin",
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001795 logging_parent: "bah",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001796 }
1797
1798 android_app_certificate {
1799 name: "new_certificate",
1800 certificate: "cert/new_cert",
1801 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001802
1803 override_android_app {
1804 name: "baz",
1805 base: "foo",
1806 package_name: "org.dandroid.bp",
1807 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00001808
1809 override_android_app {
1810 name: "baz_no_rename_resources",
1811 base: "foo",
1812 package_name: "org.dandroid.bp",
1813 rename_resources_package: false,
1814 }
1815
1816 android_app {
1817 name: "foo_no_rename_resources",
1818 srcs: ["a.java"],
1819 certificate: "expiredkey",
1820 overrides: ["qux"],
1821 rename_resources_package: false,
1822 sdk_version: "current",
1823 }
1824
1825 override_android_app {
1826 name: "baz_base_no_rename_resources",
1827 base: "foo_no_rename_resources",
1828 package_name: "org.dandroid.bp",
1829 }
1830
1831 override_android_app {
1832 name: "baz_override_base_rename_resources",
1833 base: "foo_no_rename_resources",
1834 package_name: "org.dandroid.bp",
1835 rename_resources_package: true,
1836 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001837 `)
1838
1839 expectedVariants := []struct {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001840 name string
1841 moduleName string
1842 variantName string
1843 apkName string
1844 apkPath string
1845 certFlag string
1846 lineageFlag string
1847 overrides []string
1848 packageFlag string
1849 renameResources bool
1850 logging_parent string
Jaewoong Jung525443a2019-02-28 15:35:54 -08001851 }{
1852 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001853 name: "foo",
1854 moduleName: "foo",
1855 variantName: "android_common",
1856 apkPath: "/target/product/test_device/system/app/foo/foo.apk",
1857 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1858 lineageFlag: "",
1859 overrides: []string{"qux"},
1860 packageFlag: "",
1861 renameResources: false,
1862 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001863 },
1864 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001865 name: "foo",
1866 moduleName: "bar",
1867 variantName: "android_common_bar",
1868 apkPath: "/target/product/test_device/system/app/bar/bar.apk",
1869 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
1870 lineageFlag: "--lineage lineage.bin",
1871 overrides: []string{"qux", "foo"},
1872 packageFlag: "",
1873 renameResources: false,
1874 logging_parent: "bah",
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001875 },
1876 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001877 name: "foo",
1878 moduleName: "baz",
1879 variantName: "android_common_baz",
1880 apkPath: "/target/product/test_device/system/app/baz/baz.apk",
1881 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1882 lineageFlag: "",
1883 overrides: []string{"qux", "foo"},
1884 packageFlag: "org.dandroid.bp",
1885 renameResources: true,
1886 logging_parent: "",
1887 },
1888 {
1889 name: "foo",
1890 moduleName: "baz_no_rename_resources",
1891 variantName: "android_common_baz_no_rename_resources",
1892 apkPath: "/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
1893 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1894 lineageFlag: "",
1895 overrides: []string{"qux", "foo"},
1896 packageFlag: "org.dandroid.bp",
1897 renameResources: false,
1898 logging_parent: "",
1899 },
1900 {
1901 name: "foo_no_rename_resources",
1902 moduleName: "baz_base_no_rename_resources",
1903 variantName: "android_common_baz_base_no_rename_resources",
1904 apkPath: "/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
1905 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1906 lineageFlag: "",
1907 overrides: []string{"qux", "foo_no_rename_resources"},
1908 packageFlag: "org.dandroid.bp",
1909 renameResources: false,
1910 logging_parent: "",
1911 },
1912 {
1913 name: "foo_no_rename_resources",
1914 moduleName: "baz_override_base_rename_resources",
1915 variantName: "android_common_baz_override_base_rename_resources",
1916 apkPath: "/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
1917 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1918 lineageFlag: "",
1919 overrides: []string{"qux", "foo_no_rename_resources"},
1920 packageFlag: "org.dandroid.bp",
1921 renameResources: true,
1922 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001923 },
1924 }
1925 for _, expected := range expectedVariants {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001926 variant := ctx.ModuleForTests(expected.name, expected.variantName)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001927
1928 // Check the final apk name
1929 outputs := variant.AllOutputs()
1930 expectedApkPath := buildDir + expected.apkPath
1931 found := false
1932 for _, o := range outputs {
1933 if o == expectedApkPath {
1934 found = true
1935 break
1936 }
1937 }
1938 if !found {
1939 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
1940 }
1941
1942 // Check the certificate paths
Jaewoong Jung5a498812019-11-07 14:14:38 -08001943 signapk := variant.Output(expected.moduleName + ".apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07001944 certFlag := signapk.Args["certificates"]
1945 if expected.certFlag != certFlag {
1946 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.certFlag, certFlag)
1947 }
1948
1949 // Check the lineage flags
1950 lineageFlag := signapk.Args["flags"]
1951 if expected.lineageFlag != lineageFlag {
1952 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.lineageFlag, lineageFlag)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001953 }
1954
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001955 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -08001956 mod := variant.Module().(*AndroidApp)
1957 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
1958 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
1959 expected.overrides, mod.appProperties.Overrides)
1960 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001961
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001962 // Test Overridable property: Logging_parent
1963 logging_parent := mod.aapt.LoggingParent
1964 if expected.logging_parent != logging_parent {
1965 t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q",
1966 expected.logging_parent, logging_parent)
1967 }
1968
Liz Kammer1d5983b2020-05-19 19:15:37 +00001969 // Check the package renaming flag, if exists.
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001970 res := variant.Output("package-res.apk")
1971 aapt2Flags := res.Args["flags"]
Liz Kammer9f9fd022020-06-18 19:44:06 +00001972 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
1973 expectedPackage := expected.packageFlag
1974 if !expected.renameResources {
1975 expectedPackage = ""
Liz Kammer1d5983b2020-05-19 19:15:37 +00001976 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00001977 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001978 }
1979}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001980
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001981func TestOverrideAndroidAppDependency(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001982 ctx, _ := testJava(t, `
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001983 android_app {
1984 name: "foo",
1985 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001986 sdk_version: "current",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001987 }
1988
1989 override_android_app {
1990 name: "bar",
1991 base: "foo",
1992 package_name: "org.dandroid.bp",
1993 }
1994
1995 android_test {
1996 name: "baz",
1997 srcs: ["b.java"],
1998 instrumentation_for: "foo",
1999 }
2000
2001 android_test {
2002 name: "qux",
2003 srcs: ["b.java"],
2004 instrumentation_for: "bar",
2005 }
2006 `)
2007
2008 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
2009 javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
2010 fooTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
2011 if !strings.Contains(javac.Args["classpath"], fooTurbine) {
2012 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
2013 }
2014
2015 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
2016 javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
2017 barTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common_bar", "turbine-combined", "foo.jar")
2018 if !strings.Contains(javac.Args["classpath"], barTurbine) {
2019 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
2020 }
2021}
2022
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002023func TestOverrideAndroidTest(t *testing.T) {
2024 ctx, _ := testJava(t, `
2025 android_app {
2026 name: "foo",
2027 srcs: ["a.java"],
2028 package_name: "com.android.foo",
2029 sdk_version: "current",
2030 }
2031
2032 override_android_app {
2033 name: "bar",
2034 base: "foo",
2035 package_name: "com.android.bar",
2036 }
2037
2038 android_test {
2039 name: "foo_test",
2040 srcs: ["b.java"],
2041 instrumentation_for: "foo",
2042 }
2043
2044 override_android_test {
2045 name: "bar_test",
2046 base: "foo_test",
2047 package_name: "com.android.bar.test",
2048 instrumentation_for: "bar",
2049 instrumentation_target_package: "com.android.bar",
2050 }
2051 `)
2052
2053 expectedVariants := []struct {
2054 moduleName string
2055 variantName string
2056 apkPath string
2057 overrides []string
2058 targetVariant string
2059 packageFlag string
2060 targetPackageFlag string
2061 }{
2062 {
2063 variantName: "android_common",
Jaewoong Jung326a9412019-11-21 10:41:00 -08002064 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002065 overrides: nil,
2066 targetVariant: "android_common",
2067 packageFlag: "",
2068 targetPackageFlag: "",
2069 },
2070 {
2071 variantName: "android_common_bar_test",
Jaewoong Jung326a9412019-11-21 10:41:00 -08002072 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002073 overrides: []string{"foo_test"},
2074 targetVariant: "android_common_bar",
2075 packageFlag: "com.android.bar.test",
2076 targetPackageFlag: "com.android.bar",
2077 },
2078 }
2079 for _, expected := range expectedVariants {
2080 variant := ctx.ModuleForTests("foo_test", expected.variantName)
2081
2082 // Check the final apk name
2083 outputs := variant.AllOutputs()
2084 expectedApkPath := buildDir + expected.apkPath
2085 found := false
2086 for _, o := range outputs {
2087 if o == expectedApkPath {
2088 found = true
2089 break
2090 }
2091 }
2092 if !found {
2093 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
2094 }
2095
2096 // Check if the overrides field values are correctly aggregated.
2097 mod := variant.Module().(*AndroidTest)
2098 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
2099 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
2100 expected.overrides, mod.appProperties.Overrides)
2101 }
2102
2103 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
2104 javac := variant.Rule("javac")
2105 turbine := filepath.Join(buildDir, ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
2106 if !strings.Contains(javac.Args["classpath"], turbine) {
2107 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
2108 }
2109
2110 // Check aapt2 flags.
2111 res := variant.Output("package-res.apk")
2112 aapt2Flags := res.Args["flags"]
2113 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
Liz Kammer9f9fd022020-06-18 19:44:06 +00002114 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002115 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
2116 }
2117}
2118
Jaewoong Jung39982342020-01-14 10:27:18 -08002119func TestAndroidTest_FixTestConfig(t *testing.T) {
2120 ctx, _ := testJava(t, `
2121 android_app {
2122 name: "foo",
2123 srcs: ["a.java"],
2124 package_name: "com.android.foo",
2125 sdk_version: "current",
2126 }
2127
2128 android_test {
2129 name: "foo_test",
2130 srcs: ["b.java"],
2131 instrumentation_for: "foo",
2132 }
2133
2134 android_test {
2135 name: "bar_test",
2136 srcs: ["b.java"],
2137 package_name: "com.android.bar.test",
2138 instrumentation_for: "foo",
2139 }
2140
2141 override_android_test {
2142 name: "baz_test",
2143 base: "foo_test",
2144 package_name: "com.android.baz.test",
2145 }
2146 `)
2147
2148 testCases := []struct {
2149 moduleName string
2150 variantName string
2151 expectedFlags []string
2152 }{
2153 {
2154 moduleName: "foo_test",
2155 variantName: "android_common",
2156 },
2157 {
2158 moduleName: "bar_test",
2159 variantName: "android_common",
2160 expectedFlags: []string{
2161 "--manifest " + buildDir + "/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
2162 "--package-name com.android.bar.test",
2163 },
2164 },
2165 {
2166 moduleName: "foo_test",
2167 variantName: "android_common_baz_test",
2168 expectedFlags: []string{
2169 "--manifest " + buildDir +
2170 "/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
2171 "--package-name com.android.baz.test",
2172 "--test-file-name baz_test.apk",
2173 },
2174 },
2175 }
2176
2177 for _, test := range testCases {
2178 variant := ctx.ModuleForTests(test.moduleName, test.variantName)
2179 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
2180
2181 if len(test.expectedFlags) > 0 {
2182 if params.Rule == nil {
2183 t.Errorf("test_config_fixer was expected to run, but didn't")
2184 } else {
2185 for _, flag := range test.expectedFlags {
2186 if !strings.Contains(params.RuleParams.Command, flag) {
2187 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
2188 }
2189 }
2190 }
2191 } else {
2192 if params.Rule != nil {
2193 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
2194 }
2195 }
2196
2197 }
2198}
2199
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002200func TestStl(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002201 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002202 cc_library {
2203 name: "libjni",
Peter Collingbournead84f972019-12-17 16:46:18 -08002204 sdk_version: "current",
2205 stl: "c++_shared",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002206 }
2207
2208 android_test {
2209 name: "stl",
2210 jni_libs: ["libjni"],
2211 compile_multilib: "both",
2212 sdk_version: "current",
2213 stl: "c++_shared",
2214 }
2215
2216 android_test {
2217 name: "system",
2218 jni_libs: ["libjni"],
2219 compile_multilib: "both",
2220 sdk_version: "current",
2221 }
2222 `)
2223
2224 testCases := []struct {
2225 name string
2226 jnis []string
2227 }{
2228 {"stl",
2229 []string{
2230 "libjni.so",
Jaewoong Jung710756a2019-06-04 11:53:47 -07002231 "libc++_shared.so",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002232 },
2233 },
2234 {"system",
2235 []string{
2236 "libjni.so",
2237 },
2238 },
2239 }
2240
2241 for _, test := range testCases {
2242 t.Run(test.name, func(t *testing.T) {
2243 app := ctx.ModuleForTests(test.name, "android_common")
2244 jniLibZip := app.Output("jnilibs.zip")
2245 var jnis []string
2246 args := strings.Fields(jniLibZip.Args["jarArgs"])
2247 for i := 0; i < len(args); i++ {
2248 if args[i] == "-f" {
2249 jnis = append(jnis, args[i+1])
2250 i += 1
2251 }
2252 }
2253 jnisJoined := strings.Join(jnis, " ")
2254 for _, jni := range test.jnis {
2255 if !strings.Contains(jnisJoined, jni) {
2256 t.Errorf("missing jni %q in %q", jni, jnis)
2257 }
2258 }
2259 })
2260 }
2261}
Colin Cross50ddcc42019-05-16 12:28:22 -07002262
2263func TestUsesLibraries(t *testing.T) {
2264 bp := `
2265 java_sdk_library {
2266 name: "foo",
2267 srcs: ["a.java"],
2268 api_packages: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002269 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002270 }
2271
2272 java_sdk_library {
Paul Duffin859fe962020-05-15 10:20:31 +01002273 name: "qux",
2274 srcs: ["a.java"],
2275 api_packages: ["qux"],
2276 sdk_version: "current",
2277 }
2278
2279 java_sdk_library {
2280 name: "quuz",
2281 srcs: ["a.java"],
2282 api_packages: ["quuz"],
2283 sdk_version: "current",
2284 }
2285
2286 java_sdk_library {
Ulya Trafimovich65b03192020-12-03 16:50:22 +00002287 name: "fred",
2288 srcs: ["a.java"],
2289 api_packages: ["fred"],
2290 sdk_version: "current",
2291 }
2292
2293 java_sdk_library {
Colin Cross50ddcc42019-05-16 12:28:22 -07002294 name: "bar",
2295 srcs: ["a.java"],
2296 api_packages: ["bar"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002297 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002298 }
2299
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01002300 java_sdk_library {
2301 name: "runtime-library",
2302 srcs: ["a.java"],
2303 sdk_version: "current",
2304 }
2305
2306 java_library {
2307 name: "static-runtime-helper",
2308 srcs: ["a.java"],
2309 libs: ["runtime-library"],
2310 sdk_version: "current",
2311 }
2312
Ulya Trafimovich861a8962021-02-26 14:49:07 +00002313 // A library that has to use "provides_uses_lib", because:
2314 // - it is not an SDK library
2315 // - its library name is different from its module name
2316 java_library {
2317 name: "non-sdk-lib",
2318 provides_uses_lib: "com.non.sdk.lib",
2319 installable: true,
2320 srcs: ["a.java"],
2321 }
2322
Colin Cross50ddcc42019-05-16 12:28:22 -07002323 android_app {
2324 name: "app",
2325 srcs: ["a.java"],
Ulya Trafimovich861a8962021-02-26 14:49:07 +00002326 libs: [
2327 "qux",
2328 "quuz.stubs"
2329 ],
Ulya Trafimovich65b03192020-12-03 16:50:22 +00002330 static_libs: [
2331 "static-runtime-helper",
2332 // statically linked component libraries should not pull their SDK libraries,
2333 // so "fred" should not be added to class loader context
2334 "fred.stubs",
2335 ],
Ulya Trafimovich861a8962021-02-26 14:49:07 +00002336 uses_libs: [
2337 "foo",
2338 "non-sdk-lib"
2339 ],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002340 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002341 optional_uses_libs: [
2342 "bar",
2343 "baz",
2344 ],
2345 }
2346
2347 android_app_import {
2348 name: "prebuilt",
2349 apk: "prebuilts/apk/app.apk",
2350 certificate: "platform",
Ulya Trafimovich861a8962021-02-26 14:49:07 +00002351 uses_libs: [
2352 "foo",
2353 "non-sdk-lib",
2354 "android.test.runner"
2355 ],
Colin Cross50ddcc42019-05-16 12:28:22 -07002356 optional_uses_libs: [
2357 "bar",
2358 "baz",
2359 ],
2360 }
2361 `
2362
Paul Duffind234b412021-03-12 23:04:46 +00002363 result := javaFixtureFactory.Extend(
2364 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2365 variables.MissingUsesLibraries = []string{"baz"}
2366 }),
2367 ).RunTestWithBp(t, bp)
Colin Cross50ddcc42019-05-16 12:28:22 -07002368
Paul Duffind234b412021-03-12 23:04:46 +00002369 app := result.ModuleForTests("app", "android_common")
2370 prebuilt := result.ModuleForTests("prebuilt", "android_common")
Colin Cross50ddcc42019-05-16 12:28:22 -07002371
Paul Duffin859fe962020-05-15 10:20:31 +01002372 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00002373 // This should not include explicit `uses_libs`/`optional_uses_libs` entries.
2374 actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
2375 expectManifestFixerArgs := `--extract-native-libs=true ` +
2376 `--uses-library qux ` +
2377 `--uses-library quuz ` +
2378 `--uses-library foo ` + // TODO(b/132357300): "foo" should not be passed to manifest_fixer
Ulya Trafimovicheea486a2021-02-26 11:38:21 +00002379 `--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00002380 `--uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer
Ulya Trafimovicheea486a2021-02-26 11:38:21 +00002381 `--uses-library runtime-library`
Paul Duffind234b412021-03-12 23:04:46 +00002382 android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs)
Paul Duffin859fe962020-05-15 10:20:31 +01002383
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00002384 // Test that all libraries are verified (library order matters).
2385 verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command
2386 verifyArgs := `--uses-library foo ` +
Ulya Trafimovicheea486a2021-02-26 11:38:21 +00002387 `--uses-library com.non.sdk.lib ` +
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00002388 `--uses-library qux ` +
2389 `--uses-library quuz ` +
2390 `--uses-library runtime-library ` +
2391 `--optional-uses-library bar ` +
2392 `--optional-uses-library baz `
Paul Duffind234b412021-03-12 23:04:46 +00002393 android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002394
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00002395 // Test that all libraries are verified for an APK (library order matters).
2396 verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002397 verifyApkArgs := `--uses-library foo ` +
2398 `--uses-library com.non.sdk.lib ` +
2399 `--uses-library android.test.runner ` +
2400 `--optional-uses-library bar ` +
2401 `--optional-uses-library baz `
Paul Duffind234b412021-03-12 23:04:46 +00002402 android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002403
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002404 // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00002405 cmd := app.Rule("dexpreopt").RuleParams.Command
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002406 w := `--target-context-for-sdk any ` +
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002407 `PCL[/system/framework/qux.jar]#` +
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002408 `PCL[/system/framework/quuz.jar]#` +
2409 `PCL[/system/framework/foo.jar]#` +
Ulya Trafimovich861a8962021-02-26 14:49:07 +00002410 `PCL[/system/framework/non-sdk-lib.jar]#` +
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002411 `PCL[/system/framework/bar.jar]#` +
2412 `PCL[/system/framework/runtime-library.jar]`
Paul Duffind234b412021-03-12 23:04:46 +00002413 android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w)
Colin Cross50ddcc42019-05-16 12:28:22 -07002414
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002415 // Test conditional context for target SDK version 28.
Paul Duffind234b412021-03-12 23:04:46 +00002416 android.AssertStringDoesContain(t, "dexpreopt app cmd 28", cmd,
2417 `--target-context-for-sdk 28`+
2418 ` PCL[/system/framework/org.apache.http.legacy.jar] `)
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002419
2420 // Test conditional context for target SDK version 29.
Paul Duffind234b412021-03-12 23:04:46 +00002421 android.AssertStringDoesContain(t, "dexpreopt app cmd 29", cmd,
2422 `--target-context-for-sdk 29`+
2423 ` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]`+
2424 `#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `)
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002425
2426 // Test conditional context for target SDK version 30.
Ulya Trafimovich46b3d5b2020-10-21 13:20:55 +01002427 // "android.test.mock" is absent because "android.test.runner" is not used.
Paul Duffind234b412021-03-12 23:04:46 +00002428 android.AssertStringDoesContain(t, "dexpreopt app cmd 30", cmd,
2429 `--target-context-for-sdk 30`+
2430 ` PCL[/system/framework/android.test.base.jar] `)
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002431
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002432 cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
Paul Duffind234b412021-03-12 23:04:46 +00002433 android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd", cmd,
2434 `--target-context-for-sdk any`+
2435 ` PCL[/system/framework/foo.jar]`+
2436 `#PCL[/system/framework/non-sdk-lib.jar]`+
2437 `#PCL[/system/framework/android.test.runner.jar]`+
2438 `#PCL[/system/framework/bar.jar] `)
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002439
2440 // Test conditional context for target SDK version 30.
Ulya Trafimovich46b3d5b2020-10-21 13:20:55 +01002441 // "android.test.mock" is present because "android.test.runner" is used.
Paul Duffind234b412021-03-12 23:04:46 +00002442 android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd 30", cmd,
2443 `--target-context-for-sdk 30`+
2444 ` PCL[/system/framework/android.test.base.jar]`+
2445 `#PCL[/system/framework/android.test.mock.jar] `)
Colin Cross50ddcc42019-05-16 12:28:22 -07002446}
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002447
2448func TestCodelessApp(t *testing.T) {
2449 testCases := []struct {
2450 name string
2451 bp string
2452 noCode bool
2453 }{
2454 {
2455 name: "normal",
2456 bp: `
2457 android_app {
2458 name: "foo",
2459 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002460 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002461 }
2462 `,
2463 noCode: false,
2464 },
2465 {
2466 name: "app without sources",
2467 bp: `
2468 android_app {
2469 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002470 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002471 }
2472 `,
2473 noCode: true,
2474 },
2475 {
2476 name: "app with libraries",
2477 bp: `
2478 android_app {
2479 name: "foo",
2480 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002481 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002482 }
2483
2484 java_library {
2485 name: "lib",
2486 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002487 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002488 }
2489 `,
2490 noCode: false,
2491 },
2492 {
2493 name: "app with sourceless libraries",
2494 bp: `
2495 android_app {
2496 name: "foo",
2497 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002498 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002499 }
2500
2501 java_library {
2502 name: "lib",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002503 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002504 }
2505 `,
2506 // TODO(jungjw): this should probably be true
2507 noCode: false,
2508 },
2509 }
2510
2511 for _, test := range testCases {
2512 t.Run(test.name, func(t *testing.T) {
2513 ctx := testApp(t, test.bp)
2514
2515 foo := ctx.ModuleForTests("foo", "android_common")
2516 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
2517 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
2518 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
2519 }
2520 })
2521 }
2522}
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002523
2524func TestEmbedNotice(t *testing.T) {
Colin Cross238c1f32020-06-07 16:58:18 -07002525 ctx, _ := testJavaWithFS(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002526 android_app {
2527 name: "foo",
2528 srcs: ["a.java"],
2529 static_libs: ["javalib"],
2530 jni_libs: ["libjni"],
2531 notice: "APP_NOTICE",
2532 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002533 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002534 }
2535
2536 // No embed_notice flag
2537 android_app {
2538 name: "bar",
2539 srcs: ["a.java"],
2540 jni_libs: ["libjni"],
2541 notice: "APP_NOTICE",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002542 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002543 }
2544
2545 // No NOTICE files
2546 android_app {
2547 name: "baz",
2548 srcs: ["a.java"],
2549 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002550 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002551 }
2552
2553 cc_library {
2554 name: "libjni",
2555 system_shared_libs: [],
2556 stl: "none",
2557 notice: "LIB_NOTICE",
Colin Cross094cde42020-02-15 10:38:00 -08002558 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002559 }
2560
2561 java_library {
2562 name: "javalib",
2563 srcs: [
2564 ":gen",
2565 ],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002566 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002567 }
2568
2569 genrule {
2570 name: "gen",
2571 tools: ["gentool"],
2572 out: ["gen.java"],
2573 notice: "GENRULE_NOTICE",
2574 }
2575
2576 java_binary_host {
2577 name: "gentool",
2578 srcs: ["b.java"],
2579 notice: "TOOL_NOTICE",
2580 }
Colin Cross238c1f32020-06-07 16:58:18 -07002581 `, map[string][]byte{
2582 "APP_NOTICE": nil,
2583 "GENRULE_NOTICE": nil,
2584 "LIB_NOTICE": nil,
2585 "TOOL_NOTICE": nil,
2586 })
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002587
2588 // foo has NOTICE files to process, and embed_notices is true.
2589 foo := ctx.ModuleForTests("foo", "android_common")
2590 // verify merge notices rule.
2591 mergeNotices := foo.Rule("mergeNoticesRule")
2592 noticeInputs := mergeNotices.Inputs.Strings()
2593 // TOOL_NOTICE should be excluded as it's a host module.
2594 if len(mergeNotices.Inputs) != 3 {
2595 t.Errorf("number of input notice files: expected = 3, actual = %q", noticeInputs)
2596 }
2597 if !inList("APP_NOTICE", noticeInputs) {
2598 t.Errorf("APP_NOTICE is missing from notice files, %q", noticeInputs)
2599 }
2600 if !inList("LIB_NOTICE", noticeInputs) {
2601 t.Errorf("LIB_NOTICE is missing from notice files, %q", noticeInputs)
2602 }
2603 if !inList("GENRULE_NOTICE", noticeInputs) {
2604 t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs)
2605 }
2606 // aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets.
2607 res := foo.Output("package-res.apk")
2608 aapt2Flags := res.Args["flags"]
2609 e := "-A " + buildDir + "/.intermediates/foo/android_common/NOTICE"
2610 if !strings.Contains(aapt2Flags, e) {
2611 t.Errorf("asset dir flag for NOTICE, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
2612 }
2613
2614 // bar has NOTICE files to process, but embed_notices is not set.
2615 bar := ctx.ModuleForTests("bar", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07002616 res = bar.Output("package-res.apk")
2617 aapt2Flags = res.Args["flags"]
2618 e = "-A " + buildDir + "/.intermediates/bar/android_common/NOTICE"
2619 if strings.Contains(aapt2Flags, e) {
2620 t.Errorf("bar shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002621 }
2622
2623 // baz's embed_notice is true, but it doesn't have any NOTICE files.
2624 baz := ctx.ModuleForTests("baz", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07002625 res = baz.Output("package-res.apk")
2626 aapt2Flags = res.Args["flags"]
2627 e = "-A " + buildDir + "/.intermediates/baz/android_common/NOTICE"
2628 if strings.Contains(aapt2Flags, e) {
2629 t.Errorf("baz shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002630 }
2631}
Colin Cross53a87f52019-06-25 13:35:30 -07002632
2633func TestUncompressDex(t *testing.T) {
2634 testCases := []struct {
2635 name string
2636 bp string
2637
2638 uncompressedPlatform bool
2639 uncompressedUnbundled bool
2640 }{
2641 {
2642 name: "normal",
2643 bp: `
2644 android_app {
2645 name: "foo",
2646 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002647 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002648 }
2649 `,
2650 uncompressedPlatform: true,
2651 uncompressedUnbundled: false,
2652 },
2653 {
2654 name: "use_embedded_dex",
2655 bp: `
2656 android_app {
2657 name: "foo",
2658 use_embedded_dex: true,
2659 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002660 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002661 }
2662 `,
2663 uncompressedPlatform: true,
2664 uncompressedUnbundled: true,
2665 },
2666 {
2667 name: "privileged",
2668 bp: `
2669 android_app {
2670 name: "foo",
2671 privileged: true,
2672 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002673 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002674 }
2675 `,
2676 uncompressedPlatform: true,
2677 uncompressedUnbundled: true,
2678 },
David Srbeckye033cba2020-05-20 22:20:28 +01002679 {
2680 name: "normal_uncompress_dex_true",
2681 bp: `
2682 android_app {
2683 name: "foo",
2684 srcs: ["a.java"],
2685 sdk_version: "current",
2686 uncompress_dex: true,
2687 }
2688 `,
2689 uncompressedPlatform: true,
2690 uncompressedUnbundled: true,
2691 },
2692 {
2693 name: "normal_uncompress_dex_false",
2694 bp: `
2695 android_app {
2696 name: "foo",
2697 srcs: ["a.java"],
2698 sdk_version: "current",
2699 uncompress_dex: false,
2700 }
2701 `,
2702 uncompressedPlatform: false,
2703 uncompressedUnbundled: false,
2704 },
Colin Cross53a87f52019-06-25 13:35:30 -07002705 }
2706
2707 test := func(t *testing.T, bp string, want bool, unbundled bool) {
2708 t.Helper()
2709
Colin Cross98be1bb2019-12-13 20:41:13 -08002710 config := testAppConfig(nil, bp, nil)
Colin Cross53a87f52019-06-25 13:35:30 -07002711 if unbundled {
2712 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
Jeongik Cha816a23a2020-07-08 01:09:23 +09002713 config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
Colin Cross53a87f52019-06-25 13:35:30 -07002714 }
2715
Colin Crossae8600b2020-10-29 17:09:13 -07002716 ctx := testContext(config)
Colin Cross53a87f52019-06-25 13:35:30 -07002717
2718 run(t, ctx, config)
2719
2720 foo := ctx.ModuleForTests("foo", "android_common")
2721 dex := foo.Rule("r8")
2722 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
2723 aligned := foo.MaybeRule("zipalign").Rule != nil
2724
2725 if uncompressedInDexJar != want {
2726 t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar)
2727 }
2728
2729 if aligned != want {
2730 t.Errorf("want aligned %v, got %v", want, aligned)
2731 }
2732 }
2733
2734 for _, tt := range testCases {
2735 t.Run(tt.name, func(t *testing.T) {
2736 t.Run("platform", func(t *testing.T) {
2737 test(t, tt.bp, tt.uncompressedPlatform, false)
2738 })
2739 t.Run("unbundled", func(t *testing.T) {
2740 test(t, tt.bp, tt.uncompressedUnbundled, true)
2741 })
2742 })
2743 }
2744}
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002745
2746func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
2747 if expectedValue != "" {
2748 expectedFlag := "--" + flagName + " " + expectedValue
2749 if !strings.Contains(aapt2Flags, expectedFlag) {
2750 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
2751 }
2752 } else {
2753 unexpectedFlag := "--" + flagName
2754 if strings.Contains(aapt2Flags, unexpectedFlag) {
2755 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
2756 }
2757 }
2758}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002759
Cole Faust9a631312020-10-22 21:05:24 +00002760func TestExportedProguardFlagFiles(t *testing.T) {
2761 ctx, _ := testJava(t, `
2762 android_app {
2763 name: "foo",
2764 sdk_version: "current",
2765 static_libs: ["lib1"],
2766 }
2767
2768 android_library {
2769 name: "lib1",
2770 sdk_version: "current",
2771 optimize: {
2772 proguard_flags_files: ["lib1proguard.cfg"],
2773 }
2774 }
2775 `)
2776
2777 m := ctx.ModuleForTests("foo", "android_common")
2778 hasLib1Proguard := false
2779 for _, s := range m.Rule("java.r8").Implicits.Strings() {
2780 if s == "lib1proguard.cfg" {
2781 hasLib1Proguard = true
2782 break
2783 }
2784 }
2785
2786 if !hasLib1Proguard {
2787 t.Errorf("App does not use library proguard config")
2788 }
2789}