blob: 349579e97fbd8770aeae013eb345266b6fab06b7 [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
31var (
32 resourceFiles = []string{
33 "res/layout/layout.xml",
34 "res/values/strings.xml",
35 "res/values-en-rUS/strings.xml",
36 }
37
38 compiledResourceFiles = []string{
39 "aapt2/res/layout_layout.xml.flat",
40 "aapt2/res/values_strings.arsc.flat",
41 "aapt2/res/values-en-rUS_strings.arsc.flat",
42 }
43)
44
Colin Cross98be1bb2019-12-13 20:41:13 -080045func testAppConfig(env map[string]string, bp string, fs map[string][]byte) android.Config {
Colin Cross527012a2017-11-30 22:56:16 -080046 appFS := map[string][]byte{}
47 for k, v := range fs {
48 appFS[k] = v
Colin Cross3bc7ffa2017-11-22 16:19:37 -080049 }
50
Colin Cross527012a2017-11-30 22:56:16 -080051 for _, file := range resourceFiles {
52 appFS[file] = nil
53 }
54
Colin Cross98be1bb2019-12-13 20:41:13 -080055 return testConfig(env, bp, appFS)
Colin Cross527012a2017-11-30 22:56:16 -080056}
57
58func testApp(t *testing.T, bp string) *android.TestContext {
Colin Cross98be1bb2019-12-13 20:41:13 -080059 config := testAppConfig(nil, bp, nil)
Colin Cross527012a2017-11-30 22:56:16 -080060
Colin Crossae8600b2020-10-29 17:09:13 -070061 ctx := testContext(config)
Colin Cross527012a2017-11-30 22:56:16 -080062
63 run(t, ctx, config)
64
65 return ctx
Colin Cross3bc7ffa2017-11-22 16:19:37 -080066}
67
68func TestApp(t *testing.T) {
Colin Crossa97c5d32018-03-28 14:58:31 -070069 for _, moduleType := range []string{"android_app", "android_library"} {
70 t.Run(moduleType, func(t *testing.T) {
71 ctx := testApp(t, moduleType+` {
72 name: "foo",
73 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +090074 sdk_version: "current"
Colin Crossa97c5d32018-03-28 14:58:31 -070075 }
76 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080077
Colin Crossa97c5d32018-03-28 14:58:31 -070078 foo := ctx.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080079
Colin Cross31656952018-05-24 16:11:20 -070080 var expectedLinkImplicits []string
81
82 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
83 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080084
Colin Crossa97c5d32018-03-28 14:58:31 -070085 frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
86 expectedLinkImplicits = append(expectedLinkImplicits,
87 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080088
Colin Crossa97c5d32018-03-28 14:58:31 -070089 // Test the mapping from input files to compiled output file names
90 compile := foo.Output(compiledResourceFiles[0])
91 if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
92 t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
93 resourceFiles, compile.Inputs.Strings())
94 }
Colin Crossb69301e2017-12-01 10:48:26 -080095
Colin Crossa97c5d32018-03-28 14:58:31 -070096 compiledResourceOutputs := compile.Outputs.Strings()
97 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -080098
Colin Crossa97c5d32018-03-28 14:58:31 -070099 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800100
Colin Crossa97c5d32018-03-28 14:58:31 -0700101 list := foo.Output("aapt2/res.list")
102 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800103
Colin Crossa97c5d32018-03-28 14:58:31 -0700104 // Check that the link rule uses
105 res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
106 if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
107 t.Errorf("expected aapt2 link implicits expected:\n %#v\n got:\n %#v",
108 expectedLinkImplicits, res.Implicits.Strings())
109 }
110 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800111 }
112}
Colin Cross890ff552017-11-30 20:13:19 -0800113
Colin Crosse560c4a2019-03-19 16:03:11 -0700114func TestAppSplits(t *testing.T) {
115 ctx := testApp(t, `
116 android_app {
117 name: "foo",
118 srcs: ["a.java"],
119 package_splits: ["v4", "v7,hdpi"],
Jeongik Cha538c0d02019-07-11 15:54:27 +0900120 sdk_version: "current"
Colin Crosse560c4a2019-03-19 16:03:11 -0700121 }`)
122
123 foo := ctx.ModuleForTests("foo", "android_common")
124
125 expectedOutputs := []string{
126 filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
127 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
128 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
129 }
130 for _, expectedOutput := range expectedOutputs {
131 foo.Output(expectedOutput)
132 }
133
Colin Cross41955e82019-05-29 14:40:35 -0700134 outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
135 if err != nil {
136 t.Fatal(err)
137 }
138 if g, w := outputFiles.Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
139 t.Errorf(`want OutputFiles("") = %q, got %q`, w, g)
Colin Crosse560c4a2019-03-19 16:03:11 -0700140 }
141}
142
Jeongik Cha538c0d02019-07-11 15:54:27 +0900143func TestPlatformAPIs(t *testing.T) {
144 testJava(t, `
145 android_app {
146 name: "foo",
147 srcs: ["a.java"],
148 platform_apis: true,
149 }
150 `)
151
152 testJava(t, `
153 android_app {
154 name: "foo",
155 srcs: ["a.java"],
156 sdk_version: "current",
157 }
158 `)
159
160 testJavaError(t, "platform_apis must be true when sdk_version is empty.", `
161 android_app {
162 name: "bar",
163 srcs: ["b.java"],
164 }
165 `)
166
167 testJavaError(t, "platform_apis must be false when sdk_version is not empty.", `
168 android_app {
169 name: "bar",
170 srcs: ["b.java"],
171 sdk_version: "system_current",
172 platform_apis: true,
173 }
174 `)
175}
176
Jeongik Chae403e9e2019-12-07 00:16:24 +0900177func TestAndroidAppLinkType(t *testing.T) {
178 testJava(t, `
179 android_app {
180 name: "foo",
181 srcs: ["a.java"],
182 libs: ["bar"],
183 static_libs: ["baz"],
184 platform_apis: true,
185 }
186
187 java_library {
188 name: "bar",
189 sdk_version: "current",
190 srcs: ["b.java"],
191 }
192
193 android_library {
194 name: "baz",
195 sdk_version: "system_current",
196 srcs: ["c.java"],
197 }
198 `)
199
Steven Moreland00298982020-11-17 21:44:36 +0000200 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900201 android_app {
202 name: "foo",
203 srcs: ["a.java"],
204 libs: ["bar"],
205 sdk_version: "current",
206 static_libs: ["baz"],
207 }
208
209 java_library {
210 name: "bar",
211 sdk_version: "current",
212 srcs: ["b.java"],
213 }
214
215 android_library {
216 name: "baz",
217 sdk_version: "system_current",
218 srcs: ["c.java"],
219 }
220 `)
221
222 testJava(t, `
223 android_app {
224 name: "foo",
225 srcs: ["a.java"],
226 libs: ["bar"],
227 sdk_version: "system_current",
228 static_libs: ["baz"],
229 }
230
231 java_library {
232 name: "bar",
233 sdk_version: "current",
234 srcs: ["b.java"],
235 }
236
237 android_library {
238 name: "baz",
239 sdk_version: "system_current",
240 srcs: ["c.java"],
241 }
242 `)
243
Steven Moreland00298982020-11-17 21:44:36 +0000244 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900245 android_app {
246 name: "foo",
247 srcs: ["a.java"],
248 libs: ["bar"],
249 sdk_version: "system_current",
250 static_libs: ["baz"],
251 }
252
253 java_library {
254 name: "bar",
255 sdk_version: "current",
256 srcs: ["b.java"],
257 }
258
259 android_library {
260 name: "baz",
261 srcs: ["c.java"],
262 }
263 `)
264}
265
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100266func TestUpdatableApps(t *testing.T) {
267 testCases := []struct {
268 name string
269 bp string
270 expectedError string
271 }{
272 {
273 name: "Stable public SDK",
274 bp: `android_app {
275 name: "foo",
276 srcs: ["a.java"],
277 sdk_version: "29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100278 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100279 updatable: true,
280 }`,
281 },
282 {
283 name: "Stable system SDK",
284 bp: `android_app {
285 name: "foo",
286 srcs: ["a.java"],
287 sdk_version: "system_29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100288 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100289 updatable: true,
290 }`,
291 },
292 {
293 name: "Current public SDK",
294 bp: `android_app {
295 name: "foo",
296 srcs: ["a.java"],
297 sdk_version: "current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100298 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100299 updatable: true,
300 }`,
301 },
302 {
303 name: "Current system SDK",
304 bp: `android_app {
305 name: "foo",
306 srcs: ["a.java"],
307 sdk_version: "system_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100308 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100309 updatable: true,
310 }`,
311 },
312 {
313 name: "Current module SDK",
314 bp: `android_app {
315 name: "foo",
316 srcs: ["a.java"],
317 sdk_version: "module_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100318 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100319 updatable: true,
320 }`,
321 },
322 {
323 name: "Current core SDK",
324 bp: `android_app {
325 name: "foo",
326 srcs: ["a.java"],
327 sdk_version: "core_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100328 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100329 updatable: true,
330 }`,
331 },
332 {
333 name: "No Platform APIs",
334 bp: `android_app {
335 name: "foo",
336 srcs: ["a.java"],
337 platform_apis: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100338 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100339 updatable: true,
340 }`,
341 expectedError: "Updatable apps must use stable SDKs",
342 },
343 {
344 name: "No Core Platform APIs",
345 bp: `android_app {
346 name: "foo",
347 srcs: ["a.java"],
348 sdk_version: "core_platform",
Artur Satayevf40fc852020-04-16 13:43:02 +0100349 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100350 updatable: true,
351 }`,
352 expectedError: "Updatable apps must use stable SDKs",
353 },
354 {
355 name: "No unspecified APIs",
356 bp: `android_app {
357 name: "foo",
358 srcs: ["a.java"],
359 updatable: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100360 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100361 }`,
362 expectedError: "Updatable apps must use stable SDK",
363 },
Artur Satayevf40fc852020-04-16 13:43:02 +0100364 {
365 name: "Must specify min_sdk_version",
366 bp: `android_app {
367 name: "app_without_min_sdk_version",
368 srcs: ["a.java"],
369 sdk_version: "29",
370 updatable: true,
371 }`,
372 expectedError: "updatable apps must set min_sdk_version.",
373 },
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100374 }
375
376 for _, test := range testCases {
377 t.Run(test.name, func(t *testing.T) {
378 if test.expectedError == "" {
379 testJava(t, test.bp)
380 } else {
381 testJavaError(t, test.expectedError, test.bp)
382 }
383 })
384 }
385}
386
Jooyung Han749dc692020-04-15 11:03:39 +0900387func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
388 testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
389 android_app {
390 name: "foo",
391 srcs: ["a.java"],
392 updatable: true,
393 sdk_version: "current",
394 min_sdk_version: "29",
395 static_libs: ["bar"],
396 }
397
398 java_library {
399 name: "bar",
400 sdk_version: "current",
401 }
402 `)
403}
404
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900405func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
406 testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
407 android_app {
408 name: "foo",
409 srcs: ["a.java"],
410 updatable: true,
411 sdk_version: "current",
412 min_sdk_version: "current",
413 jni_libs: ["libjni"],
414 }
415
416 cc_library {
417 name: "libjni",
418 stl: "none",
419 system_shared_libs: [],
420 sdk_version: "current",
421 }
422 `)
423}
424
425func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
426 bp := cc.GatherRequiredDepsForTest(android.Android) + `
427 android_app {
428 name: "foo",
429 srcs: ["a.java"],
430 updatable: true,
431 sdk_version: "current",
432 min_sdk_version: "29",
433 jni_libs: ["libjni"],
434 }
435
436 cc_library {
437 name: "libjni",
438 stl: "none",
439 system_shared_libs: [],
440 sdk_version: "29",
441 }
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900442 `
443 fs := map[string][]byte{
444 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
445 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": nil,
446 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o": nil,
447 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o": nil,
448 }
449
450 ctx, _ := testJavaWithConfig(t, testConfig(nil, bp, fs))
451
452 inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
453 var crtbeginFound, crtendFound bool
Dan Albert92fe7402020-07-15 13:33:30 -0700454 expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
455 "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
456 expectedCrtEnd := ctx.ModuleForTests("crtend_so",
457 "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
458 implicits := []string{}
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900459 for _, input := range inputs {
Dan Albert92fe7402020-07-15 13:33:30 -0700460 implicits = append(implicits, input.String())
461 if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900462 crtbeginFound = true
Dan Albert92fe7402020-07-15 13:33:30 -0700463 } else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900464 crtendFound = true
465 }
466 }
Dan Albert92fe7402020-07-15 13:33:30 -0700467 if !crtbeginFound {
468 t.Error(fmt.Sprintf(
469 "expected implicit with suffix %q, have the following implicits:\n%s",
470 expectedCrtBegin, strings.Join(implicits, "\n")))
471 }
472 if !crtendFound {
473 t.Error(fmt.Sprintf(
474 "expected implicit with suffix %q, have the following implicits:\n%s",
475 expectedCrtEnd, strings.Join(implicits, "\n")))
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900476 }
477}
478
479func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
480 bp := cc.GatherRequiredDepsForTest(android.Android) + `
481 android_app {
482 name: "foo",
483 srcs: ["a.java"],
484 updatable: true,
485 sdk_version: "current",
486 min_sdk_version: "29", // this APK should support 29
487 jni_libs: ["libjni"],
488 }
489
490 cc_library {
491 name: "libjni",
492 stl: "none",
493 sdk_version: "current",
494 }
495 `
496 testJavaError(t, `"libjni" .*: sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
497}
498
499func TestUpdatableApps_ErrorIfDepSdkVersionIsHigher(t *testing.T) {
500 bp := cc.GatherRequiredDepsForTest(android.Android) + `
501 android_app {
502 name: "foo",
503 srcs: ["a.java"],
504 updatable: true,
505 sdk_version: "current",
506 min_sdk_version: "29", // this APK should support 29
507 jni_libs: ["libjni"],
508 }
509
510 cc_library {
511 name: "libjni",
512 stl: "none",
513 shared_libs: ["libbar"],
514 system_shared_libs: [],
515 sdk_version: "27",
516 }
517
518 cc_library {
519 name: "libbar",
520 stl: "none",
521 system_shared_libs: [],
522 sdk_version: "current",
523 }
524 `
525 testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp)
526}
527
Colin Cross0ddae7f2019-02-07 15:30:01 -0800528func TestResourceDirs(t *testing.T) {
529 testCases := []struct {
530 name string
531 prop string
532 resources []string
533 }{
534 {
535 name: "no resource_dirs",
536 prop: "",
537 resources: []string{"res/res/values/strings.xml"},
538 },
539 {
540 name: "resource_dirs",
541 prop: `resource_dirs: ["res"]`,
542 resources: []string{"res/res/values/strings.xml"},
543 },
544 {
545 name: "empty resource_dirs",
546 prop: `resource_dirs: []`,
547 resources: nil,
548 },
549 }
550
551 fs := map[string][]byte{
552 "res/res/values/strings.xml": nil,
553 }
554
555 bp := `
556 android_app {
557 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900558 sdk_version: "current",
Colin Cross0ddae7f2019-02-07 15:30:01 -0800559 %s
560 }
561 `
562
563 for _, testCase := range testCases {
564 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800565 config := testConfig(nil, fmt.Sprintf(bp, testCase.prop), fs)
Colin Crossae8600b2020-10-29 17:09:13 -0700566 ctx := testContext(config)
Colin Cross0ddae7f2019-02-07 15:30:01 -0800567 run(t, ctx, config)
568
569 module := ctx.ModuleForTests("foo", "android_common")
570 resourceList := module.MaybeOutput("aapt2/res.list")
571
572 var resources []string
573 if resourceList.Rule != nil {
574 for _, compiledResource := range resourceList.Inputs.Strings() {
575 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
576 }
577 }
578
579 if !reflect.DeepEqual(resources, testCase.resources) {
580 t.Errorf("expected resource files %q, got %q",
581 testCase.resources, resources)
582 }
583 })
584 }
585}
586
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800587func TestLibraryAssets(t *testing.T) {
588 bp := `
589 android_app {
590 name: "foo",
591 sdk_version: "current",
592 static_libs: ["lib1", "lib2", "lib3"],
593 }
594
595 android_library {
596 name: "lib1",
597 sdk_version: "current",
598 asset_dirs: ["assets_a"],
599 }
600
601 android_library {
602 name: "lib2",
603 sdk_version: "current",
604 }
605
606 android_library {
607 name: "lib3",
608 sdk_version: "current",
609 static_libs: ["lib4"],
610 }
611
612 android_library {
613 name: "lib4",
614 sdk_version: "current",
615 asset_dirs: ["assets_b"],
616 }
617 `
618
619 testCases := []struct {
620 name string
621 assetFlag string
622 assetPackages []string
623 }{
624 {
625 name: "foo",
626 // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
627 assetPackages: []string{
628 buildDir + "/.intermediates/foo/android_common/aapt2/package-res.apk",
629 buildDir + "/.intermediates/lib1/android_common/assets.zip",
630 buildDir + "/.intermediates/lib3/android_common/assets.zip",
631 },
632 },
633 {
634 name: "lib1",
635 assetFlag: "-A assets_a",
636 },
637 {
638 name: "lib2",
639 },
640 {
641 name: "lib3",
642 assetPackages: []string{
643 buildDir + "/.intermediates/lib3/android_common/aapt2/package-res.apk",
644 buildDir + "/.intermediates/lib4/android_common/assets.zip",
645 },
646 },
647 {
648 name: "lib4",
649 assetFlag: "-A assets_b",
650 },
651 }
652 ctx := testApp(t, bp)
653
654 for _, test := range testCases {
655 t.Run(test.name, func(t *testing.T) {
656 m := ctx.ModuleForTests(test.name, "android_common")
657
658 // Check asset flag in aapt2 link flags
659 var aapt2link android.TestingBuildParams
660 if len(test.assetPackages) > 0 {
661 aapt2link = m.Output("aapt2/package-res.apk")
662 } else {
663 aapt2link = m.Output("package-res.apk")
664 }
665 aapt2Flags := aapt2link.Args["flags"]
666 if test.assetFlag != "" {
667 if !strings.Contains(aapt2Flags, test.assetFlag) {
668 t.Errorf("Can't find asset flag %q in aapt2 link flags %q", test.assetFlag, aapt2Flags)
669 }
670 } else {
671 if strings.Contains(aapt2Flags, " -A ") {
672 t.Errorf("aapt2 link flags %q contain unexpected asset flag", aapt2Flags)
673 }
674 }
675
676 // Check asset merge rule.
677 if len(test.assetPackages) > 0 {
678 mergeAssets := m.Output("package-res.apk")
679 if !reflect.DeepEqual(test.assetPackages, mergeAssets.Inputs.Strings()) {
680 t.Errorf("Unexpected mergeAssets inputs: %v, expected: %v",
681 mergeAssets.Inputs.Strings(), test.assetPackages)
682 }
683 }
684 })
685 }
686}
687
Colin Crossb014f072021-02-26 14:54:36 -0800688func TestAppJavaResources(t *testing.T) {
689 bp := `
690 android_app {
691 name: "foo",
692 sdk_version: "current",
693 java_resources: ["resources/a"],
694 srcs: ["a.java"],
695 }
696
697 android_app {
698 name: "bar",
699 sdk_version: "current",
700 java_resources: ["resources/a"],
701 }
702 `
703
704 ctx := testApp(t, bp)
705
706 foo := ctx.ModuleForTests("foo", "android_common")
707 fooResources := foo.Output("res/foo.jar")
708 fooDexJar := foo.Output("dex-withres/foo.jar")
709 fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
710 fooApk := foo.Rule("combineApk")
711
712 if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) {
713 t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g)
714 }
715
716 if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w {
717 t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g)
718 }
719
720 if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) {
721 t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
722 }
723
724 bar := ctx.ModuleForTests("bar", "android_common")
725 barResources := bar.Output("res/bar.jar")
726 barApk := bar.Rule("combineApk")
727
728 if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) {
729 t.Errorf("expected resources jar %q in bar apk inputs %q", w, g)
730 }
731}
732
Colin Crossbec85302019-02-13 13:15:46 -0800733func TestAndroidResources(t *testing.T) {
Colin Cross5c4791c2019-02-01 11:44:44 -0800734 testCases := []struct {
735 name string
736 enforceRROTargets []string
737 enforceRROExcludedOverlays []string
Colin Crossbec85302019-02-13 13:15:46 -0800738 resourceFiles map[string][]string
Colin Cross5c4791c2019-02-01 11:44:44 -0800739 overlayFiles map[string][]string
740 rroDirs map[string][]string
741 }{
742 {
743 name: "no RRO",
744 enforceRROTargets: nil,
745 enforceRROExcludedOverlays: nil,
Colin Crossbec85302019-02-13 13:15:46 -0800746 resourceFiles: map[string][]string{
747 "foo": nil,
748 "bar": {"bar/res/res/values/strings.xml"},
749 "lib": nil,
750 "lib2": {"lib2/res/res/values/strings.xml"},
751 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800752 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800753 "foo": {
754 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800755 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000756 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800757 "foo/res/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800758 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
759 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Anton Hansson53c88442019-03-18 15:53:16 +0000760 "product/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800761 },
Colin Crossbec85302019-02-13 13:15:46 -0800762 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800763 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
764 "device/vendor/blah/overlay/bar/res/values/strings.xml",
765 },
Colin Crossbec85302019-02-13 13:15:46 -0800766 "lib": {
767 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
768 "lib/res/res/values/strings.xml",
769 "device/vendor/blah/overlay/lib/res/values/strings.xml",
770 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800771 },
772 rroDirs: map[string][]string{
773 "foo": nil,
774 "bar": nil,
775 },
776 },
777 {
778 name: "enforce RRO on foo",
779 enforceRROTargets: []string{"foo"},
780 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossbec85302019-02-13 13:15:46 -0800781 resourceFiles: map[string][]string{
782 "foo": nil,
783 "bar": {"bar/res/res/values/strings.xml"},
784 "lib": nil,
785 "lib2": {"lib2/res/res/values/strings.xml"},
786 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800787 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800788 "foo": {
789 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800790 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000791 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800792 "foo/res/res/values/strings.xml",
793 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
794 },
Colin Crossbec85302019-02-13 13:15:46 -0800795 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800796 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
797 "device/vendor/blah/overlay/bar/res/values/strings.xml",
798 },
Colin Crossbec85302019-02-13 13:15:46 -0800799 "lib": {
800 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
801 "lib/res/res/values/strings.xml",
Colin Crossbec85302019-02-13 13:15:46 -0800802 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800803 },
Colin Crossc1c37552019-01-31 11:42:41 -0800804
Colin Cross5c4791c2019-02-01 11:44:44 -0800805 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800806 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000807 "device:device/vendor/blah/overlay/foo/res",
Anton Hansson53c88442019-03-18 15:53:16 +0000808 "product:product/vendor/blah/overlay/foo/res",
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700809 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800810 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800811 "bar": nil,
Jaewoong Jungc779cd42020-10-06 18:56:10 -0700812 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800813 },
814 },
815 {
816 name: "enforce RRO on all",
817 enforceRROTargets: []string{"*"},
818 enforceRROExcludedOverlays: []string{
819 // Excluding specific apps/res directories also allowed.
820 "device/vendor/blah/static_overlay/foo",
821 "device/vendor/blah/static_overlay/bar/res",
822 },
Colin Crossbec85302019-02-13 13:15:46 -0800823 resourceFiles: map[string][]string{
824 "foo": nil,
825 "bar": {"bar/res/res/values/strings.xml"},
826 "lib": nil,
827 "lib2": {"lib2/res/res/values/strings.xml"},
828 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800829 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800830 "foo": {
831 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800832 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000833 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800834 "foo/res/res/values/strings.xml",
835 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
836 },
Colin Crossbec85302019-02-13 13:15:46 -0800837 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
838 "lib": {
839 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
840 "lib/res/res/values/strings.xml",
841 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800842 },
843 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800844 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000845 "device:device/vendor/blah/overlay/foo/res",
846 "product:product/vendor/blah/overlay/foo/res",
847 // Lib dep comes after the direct deps
848 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800849 },
Anton Hansson53c88442019-03-18 15:53:16 +0000850 "bar": {"device:device/vendor/blah/overlay/bar/res"},
851 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800852 },
853 },
854 }
855
Anton Hansson53c88442019-03-18 15:53:16 +0000856 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -0800857 "device/vendor/blah/overlay",
858 "device/vendor/blah/overlay2",
859 "device/vendor/blah/static_overlay",
860 }
861
Anton Hansson53c88442019-03-18 15:53:16 +0000862 productResourceOverlays := []string{
863 "product/vendor/blah/overlay",
864 }
865
Colin Cross890ff552017-11-30 20:13:19 -0800866 fs := map[string][]byte{
867 "foo/res/res/values/strings.xml": nil,
868 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800869 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800870 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800871 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
872 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800873 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800874 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
875 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
876 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +0000877 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800878 }
879
880 bp := `
881 android_app {
882 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900883 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800884 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +0000885 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -0800886 }
887
888 android_app {
889 name: "bar",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900890 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800891 resource_dirs: ["bar/res"],
892 }
Colin Cross6ed7dea2019-01-31 14:44:30 -0800893
894 android_library {
895 name: "lib",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900896 sdk_version: "current",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800897 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -0800898 static_libs: ["lib2"],
899 }
900
901 android_library {
902 name: "lib2",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900903 sdk_version: "current",
Colin Crossbec85302019-02-13 13:15:46 -0800904 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -0800905 }
Anton Hansson53c88442019-03-18 15:53:16 +0000906
907 // This library has the same resources as lib (should not lead to dupe RROs)
908 android_library {
909 name: "lib3",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900910 sdk_version: "current",
Anton Hansson53c88442019-03-18 15:53:16 +0000911 resource_dirs: ["lib/res"]
912 }
Colin Cross890ff552017-11-30 20:13:19 -0800913 `
914
Colin Cross5c4791c2019-02-01 11:44:44 -0800915 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -0800916 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800917 config := testAppConfig(nil, bp, fs)
Anton Hansson53c88442019-03-18 15:53:16 +0000918 config.TestProductVariables.DeviceResourceOverlays = deviceResourceOverlays
919 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800920 if testCase.enforceRROTargets != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800921 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800922 }
923 if testCase.enforceRROExcludedOverlays != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800924 config.TestProductVariables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800925 }
926
Colin Crossae8600b2020-10-29 17:09:13 -0700927 ctx := testContext(config)
Colin Cross890ff552017-11-30 20:13:19 -0800928 run(t, ctx, config)
929
Colin Crossbec85302019-02-13 13:15:46 -0800930 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
931 for _, o := range list {
932 res := module.MaybeOutput(o)
933 if res.Rule != nil {
934 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
935 // verify the inputs to the .arsc.flat rule.
936 files = append(files, res.Inputs.Strings()...)
937 } else {
938 // Otherwise, verify the full path to the output of the other module
939 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +0000940 }
Colin Cross890ff552017-11-30 20:13:19 -0800941 }
Colin Crossbec85302019-02-13 13:15:46 -0800942 return files
Colin Cross890ff552017-11-30 20:13:19 -0800943 }
944
Colin Crossbec85302019-02-13 13:15:46 -0800945 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
946 module := ctx.ModuleForTests(moduleName, "android_common")
947 resourceList := module.MaybeOutput("aapt2/res.list")
948 if resourceList.Rule != nil {
949 resourceFiles = resourceListToFiles(module, resourceList.Inputs.Strings())
Anton Hansson0375a4f2019-01-24 14:39:19 +0000950 }
Colin Crossbec85302019-02-13 13:15:46 -0800951 overlayList := module.MaybeOutput("aapt2/overlay.list")
952 if overlayList.Rule != nil {
953 overlayFiles = resourceListToFiles(module, overlayList.Inputs.Strings())
954 }
955
Anton Hansson53c88442019-03-18 15:53:16 +0000956 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
957 var prefix string
958 if d.overlayType == device {
959 prefix = "device:"
960 } else if d.overlayType == product {
961 prefix = "product:"
962 } else {
963 t.Fatalf("Unexpected overlayType %d", d.overlayType)
964 }
965 rroDirs = append(rroDirs, prefix+d.path.String())
966 }
Colin Crossbec85302019-02-13 13:15:46 -0800967
968 return resourceFiles, overlayFiles, rroDirs
969 }
970
971 modules := []string{"foo", "bar", "lib", "lib2"}
972 for _, module := range modules {
973 resourceFiles, overlayFiles, rroDirs := getResources(module)
974
975 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
976 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
977 module, testCase.resourceFiles[module], resourceFiles)
978 }
979 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
980 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
981 module, testCase.overlayFiles[module], overlayFiles)
982 }
983 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +0000984 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossbec85302019-02-13 13:15:46 -0800985 module, testCase.rroDirs[module], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +0000986 }
Colin Cross890ff552017-11-30 20:13:19 -0800987 }
Colin Cross890ff552017-11-30 20:13:19 -0800988 })
989 }
990}
Colin Crossd09b0b62018-04-18 11:06:47 -0700991
Jeongik Cha219141c2020-08-06 23:00:37 +0900992func checkSdkVersion(t *testing.T, config android.Config, expectedSdkVersion string) {
Colin Crossae8600b2020-10-29 17:09:13 -0700993 ctx := testContext(config)
Jeongik Cha219141c2020-08-06 23:00:37 +0900994
995 run(t, ctx, config)
996
997 foo := ctx.ModuleForTests("foo", "android_common")
998 link := foo.Output("package-res.apk")
999 linkFlags := strings.Split(link.Args["flags"], " ")
1000 min := android.IndexList("--min-sdk-version", linkFlags)
1001 target := android.IndexList("--target-sdk-version", linkFlags)
1002
1003 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
1004 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
1005 }
1006
1007 gotMinSdkVersion := linkFlags[min+1]
1008 gotTargetSdkVersion := linkFlags[target+1]
1009
1010 if gotMinSdkVersion != expectedSdkVersion {
1011 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
1012 expectedSdkVersion, gotMinSdkVersion)
1013 }
1014
1015 if gotTargetSdkVersion != expectedSdkVersion {
1016 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
1017 expectedSdkVersion, gotTargetSdkVersion)
1018 }
1019}
1020
Colin Crossd09b0b62018-04-18 11:06:47 -07001021func TestAppSdkVersion(t *testing.T) {
1022 testCases := []struct {
1023 name string
1024 sdkVersion string
1025 platformSdkInt int
1026 platformSdkCodename string
1027 platformSdkFinal bool
1028 expectedMinSdkVersion string
Jeongik Cha538c0d02019-07-11 15:54:27 +09001029 platformApis bool
Dan Albert4f378d72020-07-23 17:32:15 -07001030 activeCodenames []string
Colin Crossd09b0b62018-04-18 11:06:47 -07001031 }{
1032 {
1033 name: "current final SDK",
1034 sdkVersion: "current",
1035 platformSdkInt: 27,
1036 platformSdkCodename: "REL",
1037 platformSdkFinal: true,
1038 expectedMinSdkVersion: "27",
1039 },
1040 {
1041 name: "current non-final SDK",
1042 sdkVersion: "current",
1043 platformSdkInt: 27,
1044 platformSdkCodename: "OMR1",
1045 platformSdkFinal: false,
1046 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001047 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001048 },
1049 {
1050 name: "default final SDK",
1051 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001052 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001053 platformSdkInt: 27,
1054 platformSdkCodename: "REL",
1055 platformSdkFinal: true,
1056 expectedMinSdkVersion: "27",
1057 },
1058 {
1059 name: "default non-final SDK",
1060 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001061 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001062 platformSdkInt: 27,
1063 platformSdkCodename: "OMR1",
1064 platformSdkFinal: false,
1065 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001066 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001067 },
1068 {
1069 name: "14",
1070 sdkVersion: "14",
1071 expectedMinSdkVersion: "14",
Dan Albert4f378d72020-07-23 17:32:15 -07001072 platformSdkCodename: "S",
1073 activeCodenames: []string{"S"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001074 },
1075 }
1076
1077 for _, moduleType := range []string{"android_app", "android_library"} {
1078 for _, test := range testCases {
1079 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Jeongik Cha538c0d02019-07-11 15:54:27 +09001080 platformApiProp := ""
1081 if test.platformApis {
1082 platformApiProp = "platform_apis: true,"
1083 }
Colin Crossd09b0b62018-04-18 11:06:47 -07001084 bp := fmt.Sprintf(`%s {
1085 name: "foo",
1086 srcs: ["a.java"],
1087 sdk_version: "%s",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001088 %s
1089 }`, moduleType, test.sdkVersion, platformApiProp)
Colin Crossd09b0b62018-04-18 11:06:47 -07001090
Colin Cross98be1bb2019-12-13 20:41:13 -08001091 config := testAppConfig(nil, bp, nil)
Colin Crossd09b0b62018-04-18 11:06:47 -07001092 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
1093 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
Dan Albert4f378d72020-07-23 17:32:15 -07001094 config.TestProductVariables.Platform_version_active_codenames = test.activeCodenames
Colin Crossd09b0b62018-04-18 11:06:47 -07001095 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
Jeongik Cha219141c2020-08-06 23:00:37 +09001096 checkSdkVersion(t, config, test.expectedMinSdkVersion)
Colin Crossd09b0b62018-04-18 11:06:47 -07001097
Colin Crossd09b0b62018-04-18 11:06:47 -07001098 })
1099 }
1100 }
1101}
Colin Crossa4f08812018-10-02 22:03:40 -07001102
Jeongik Cha219141c2020-08-06 23:00:37 +09001103func TestVendorAppSdkVersion(t *testing.T) {
1104 testCases := []struct {
1105 name string
1106 sdkVersion string
1107 platformSdkInt int
1108 platformSdkCodename string
1109 platformSdkFinal bool
1110 deviceCurrentApiLevelForVendorModules string
1111 expectedMinSdkVersion string
1112 }{
1113 {
1114 name: "current final SDK",
1115 sdkVersion: "current",
1116 platformSdkInt: 29,
1117 platformSdkCodename: "REL",
1118 platformSdkFinal: true,
1119 deviceCurrentApiLevelForVendorModules: "29",
1120 expectedMinSdkVersion: "29",
1121 },
1122 {
1123 name: "current final SDK",
1124 sdkVersion: "current",
1125 platformSdkInt: 29,
1126 platformSdkCodename: "REL",
1127 platformSdkFinal: true,
1128 deviceCurrentApiLevelForVendorModules: "28",
1129 expectedMinSdkVersion: "28",
1130 },
1131 {
1132 name: "current final SDK",
1133 sdkVersion: "current",
1134 platformSdkInt: 29,
1135 platformSdkCodename: "Q",
1136 platformSdkFinal: false,
Jeongik Cha219141c2020-08-06 23:00:37 +09001137 deviceCurrentApiLevelForVendorModules: "28",
1138 expectedMinSdkVersion: "28",
1139 },
1140 }
1141
1142 for _, moduleType := range []string{"android_app", "android_library"} {
1143 for _, sdkKind := range []string{"", "system_"} {
1144 for _, test := range testCases {
1145 t.Run(moduleType+" "+test.name, func(t *testing.T) {
1146 bp := fmt.Sprintf(`%s {
1147 name: "foo",
1148 srcs: ["a.java"],
1149 sdk_version: "%s%s",
1150 vendor: true,
1151 }`, moduleType, sdkKind, test.sdkVersion)
1152
1153 config := testAppConfig(nil, bp, nil)
1154 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
1155 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
1156 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
1157 config.TestProductVariables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
1158 config.TestProductVariables.DeviceSystemSdkVersions = []string{"28", "29"}
1159 checkSdkVersion(t, config, test.expectedMinSdkVersion)
1160 })
1161 }
1162 }
1163 }
1164}
1165
Paul Duffin50c217c2019-06-12 13:25:22 +01001166func TestJNIABI(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001167 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001168 cc_library {
1169 name: "libjni",
1170 system_shared_libs: [],
Colin Crossc511bc52020-04-07 16:50:32 +00001171 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001172 stl: "none",
1173 }
1174
1175 android_test {
1176 name: "test",
1177 sdk_version: "core_platform",
1178 jni_libs: ["libjni"],
1179 }
1180
1181 android_test {
1182 name: "test_first",
1183 sdk_version: "core_platform",
1184 compile_multilib: "first",
1185 jni_libs: ["libjni"],
1186 }
1187
1188 android_test {
1189 name: "test_both",
1190 sdk_version: "core_platform",
1191 compile_multilib: "both",
1192 jni_libs: ["libjni"],
1193 }
1194
1195 android_test {
1196 name: "test_32",
1197 sdk_version: "core_platform",
1198 compile_multilib: "32",
1199 jni_libs: ["libjni"],
1200 }
1201
1202 android_test {
1203 name: "test_64",
1204 sdk_version: "core_platform",
1205 compile_multilib: "64",
1206 jni_libs: ["libjni"],
1207 }
1208 `)
1209
1210 testCases := []struct {
1211 name string
1212 abis []string
1213 }{
1214 {"test", []string{"arm64-v8a"}},
1215 {"test_first", []string{"arm64-v8a"}},
1216 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
1217 {"test_32", []string{"armeabi-v7a"}},
1218 {"test_64", []string{"arm64-v8a"}},
1219 }
1220
1221 for _, test := range testCases {
1222 t.Run(test.name, func(t *testing.T) {
1223 app := ctx.ModuleForTests(test.name, "android_common")
1224 jniLibZip := app.Output("jnilibs.zip")
1225 var abis []string
1226 args := strings.Fields(jniLibZip.Args["jarArgs"])
1227 for i := 0; i < len(args); i++ {
1228 if args[i] == "-P" {
1229 abis = append(abis, filepath.Base(args[i+1]))
1230 i++
1231 }
1232 }
1233 if !reflect.DeepEqual(abis, test.abis) {
1234 t.Errorf("want abis %v, got %v", test.abis, abis)
1235 }
1236 })
1237 }
1238}
1239
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001240func TestAppSdkVersionByPartition(t *testing.T) {
1241 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
1242 android_app {
1243 name: "foo",
1244 srcs: ["a.java"],
1245 vendor: true,
1246 platform_apis: true,
1247 }
1248 `)
1249
1250 testJava(t, `
1251 android_app {
1252 name: "bar",
1253 srcs: ["b.java"],
1254 platform_apis: true,
1255 }
1256 `)
1257
1258 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001259 bp := `
1260 android_app {
1261 name: "foo",
1262 srcs: ["a.java"],
1263 product_specific: true,
1264 platform_apis: true,
1265 }
1266 `
Colin Cross98be1bb2019-12-13 20:41:13 -08001267
1268 config := testAppConfig(nil, bp, nil)
1269 config.TestProductVariables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001270 if enforce {
Colin Cross98be1bb2019-12-13 20:41:13 -08001271 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 +09001272 } else {
Colin Cross98be1bb2019-12-13 20:41:13 -08001273 testJavaWithConfig(t, config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001274 }
1275 }
1276}
1277
Paul Duffin50c217c2019-06-12 13:25:22 +01001278func TestJNIPackaging(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001279 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001280 cc_library {
1281 name: "libjni",
1282 system_shared_libs: [],
1283 stl: "none",
Colin Cross094cde42020-02-15 10:38:00 -08001284 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001285 }
1286
1287 android_app {
1288 name: "app",
1289 jni_libs: ["libjni"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001290 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001291 }
1292
1293 android_app {
1294 name: "app_noembed",
1295 jni_libs: ["libjni"],
1296 use_embedded_native_libs: false,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001297 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001298 }
1299
1300 android_app {
1301 name: "app_embed",
1302 jni_libs: ["libjni"],
1303 use_embedded_native_libs: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001304 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001305 }
1306
1307 android_test {
1308 name: "test",
Colin Crossc511bc52020-04-07 16:50:32 +00001309 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001310 jni_libs: ["libjni"],
1311 }
1312
1313 android_test {
1314 name: "test_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00001315 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001316 jni_libs: ["libjni"],
1317 use_embedded_native_libs: false,
1318 }
1319
1320 android_test_helper_app {
1321 name: "test_helper",
Colin Crossc511bc52020-04-07 16:50:32 +00001322 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001323 jni_libs: ["libjni"],
1324 }
1325
1326 android_test_helper_app {
1327 name: "test_helper_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00001328 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001329 jni_libs: ["libjni"],
1330 use_embedded_native_libs: false,
1331 }
1332 `)
1333
1334 testCases := []struct {
1335 name string
1336 packaged bool
1337 compressed bool
1338 }{
1339 {"app", false, false},
1340 {"app_noembed", false, false},
1341 {"app_embed", true, false},
1342 {"test", true, false},
1343 {"test_noembed", true, true},
1344 {"test_helper", true, false},
1345 {"test_helper_noembed", true, true},
1346 }
1347
1348 for _, test := range testCases {
1349 t.Run(test.name, func(t *testing.T) {
1350 app := ctx.ModuleForTests(test.name, "android_common")
1351 jniLibZip := app.MaybeOutput("jnilibs.zip")
1352 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
1353 t.Errorf("expected jni packaged %v, got %v", w, g)
1354 }
1355
1356 if jniLibZip.Rule != nil {
1357 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
1358 t.Errorf("expected jni compressed %v, got %v", w, g)
1359 }
Colin Crossc511bc52020-04-07 16:50:32 +00001360
1361 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
1362 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
1363 }
Paul Duffin50c217c2019-06-12 13:25:22 +01001364 }
1365 })
1366 }
Colin Cross47fa9d32019-03-26 10:51:39 -07001367}
1368
Colin Cross3c007702020-05-08 11:20:24 -07001369func TestJNISDK(t *testing.T) {
1370 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
1371 cc_library {
1372 name: "libjni",
1373 system_shared_libs: [],
1374 stl: "none",
1375 sdk_version: "current",
1376 }
1377
1378 android_test {
1379 name: "app_platform",
1380 jni_libs: ["libjni"],
1381 platform_apis: true,
1382 }
1383
1384 android_test {
1385 name: "app_sdk",
1386 jni_libs: ["libjni"],
1387 sdk_version: "current",
1388 }
1389
1390 android_test {
1391 name: "app_force_platform",
1392 jni_libs: ["libjni"],
1393 sdk_version: "current",
1394 jni_uses_platform_apis: true,
1395 }
1396
1397 android_test {
1398 name: "app_force_sdk",
1399 jni_libs: ["libjni"],
1400 platform_apis: true,
1401 jni_uses_sdk_apis: true,
1402 }
Colin Crossc2d24052020-05-13 11:05:02 -07001403
1404 cc_library {
1405 name: "libvendorjni",
1406 system_shared_libs: [],
1407 stl: "none",
1408 vendor: true,
1409 }
1410
1411 android_test {
1412 name: "app_vendor",
1413 jni_libs: ["libvendorjni"],
1414 sdk_version: "current",
1415 vendor: true,
1416 }
Colin Cross3c007702020-05-08 11:20:24 -07001417 `)
1418
1419 testCases := []struct {
Colin Crossc2d24052020-05-13 11:05:02 -07001420 name string
1421 sdkJNI bool
1422 vendorJNI bool
Colin Cross3c007702020-05-08 11:20:24 -07001423 }{
Colin Crossc2d24052020-05-13 11:05:02 -07001424 {name: "app_platform"},
1425 {name: "app_sdk", sdkJNI: true},
1426 {name: "app_force_platform"},
1427 {name: "app_force_sdk", sdkJNI: true},
1428 {name: "app_vendor", vendorJNI: true},
Colin Cross3c007702020-05-08 11:20:24 -07001429 }
1430
Colin Crossc2d24052020-05-13 11:05:02 -07001431 platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared").
1432 Output("libjni.so").Output.String()
1433 sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
1434 Output("libjni.so").Output.String()
1435 vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared").
1436 Output("libvendorjni.so").Output.String()
1437
Colin Cross3c007702020-05-08 11:20:24 -07001438 for _, test := range testCases {
1439 t.Run(test.name, func(t *testing.T) {
1440 app := ctx.ModuleForTests(test.name, "android_common")
Colin Cross3c007702020-05-08 11:20:24 -07001441
1442 jniLibZip := app.MaybeOutput("jnilibs.zip")
1443 if len(jniLibZip.Implicits) != 1 {
1444 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
1445 }
1446 gotJNI := jniLibZip.Implicits[0].String()
1447
1448 if test.sdkJNI {
1449 if gotJNI != sdkJNI {
1450 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI)
1451 }
Colin Crossc2d24052020-05-13 11:05:02 -07001452 } else if test.vendorJNI {
1453 if gotJNI != vendorJNI {
1454 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI)
1455 }
Colin Cross3c007702020-05-08 11:20:24 -07001456 } else {
1457 if gotJNI != platformJNI {
1458 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI)
1459 }
1460 }
1461 })
1462 }
1463
1464 t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
1465 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
1466 android_test {
1467 name: "app_platform",
1468 platform_apis: true,
1469 jni_uses_platform_apis: true,
1470 }
1471 `)
1472 })
1473
1474 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
1475 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
1476 android_test {
1477 name: "app_sdk",
1478 sdk_version: "current",
1479 jni_uses_sdk_apis: true,
1480 }
1481 `)
1482 })
1483
1484}
1485
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001486func TestCertificates(t *testing.T) {
1487 testCases := []struct {
1488 name string
1489 bp string
1490 certificateOverride string
Liz Kammere2b27f42020-05-07 13:24:05 -07001491 expectedLineage string
1492 expectedCertificate string
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001493 }{
1494 {
1495 name: "default",
1496 bp: `
1497 android_app {
1498 name: "foo",
1499 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001500 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001501 }
1502 `,
1503 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001504 expectedLineage: "",
1505 expectedCertificate: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001506 },
1507 {
1508 name: "module certificate property",
1509 bp: `
1510 android_app {
1511 name: "foo",
1512 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001513 certificate: ":new_certificate",
1514 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001515 }
1516
1517 android_app_certificate {
1518 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07001519 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001520 }
1521 `,
1522 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001523 expectedLineage: "",
1524 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001525 },
1526 {
1527 name: "path certificate property",
1528 bp: `
1529 android_app {
1530 name: "foo",
1531 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001532 certificate: "expiredkey",
1533 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001534 }
1535 `,
1536 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001537 expectedLineage: "",
1538 expectedCertificate: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001539 },
1540 {
1541 name: "certificate overrides",
1542 bp: `
1543 android_app {
1544 name: "foo",
1545 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001546 certificate: "expiredkey",
1547 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001548 }
1549
1550 android_app_certificate {
1551 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07001552 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001553 }
1554 `,
1555 certificateOverride: "foo:new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07001556 expectedLineage: "",
1557 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
1558 },
1559 {
1560 name: "certificate lineage",
1561 bp: `
1562 android_app {
1563 name: "foo",
1564 srcs: ["a.java"],
1565 certificate: ":new_certificate",
1566 lineage: "lineage.bin",
1567 sdk_version: "current",
1568 }
1569
1570 android_app_certificate {
1571 name: "new_certificate",
1572 certificate: "cert/new_cert",
1573 }
1574 `,
1575 certificateOverride: "",
1576 expectedLineage: "--lineage lineage.bin",
1577 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001578 },
1579 }
1580
1581 for _, test := range testCases {
1582 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001583 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001584 if test.certificateOverride != "" {
1585 config.TestProductVariables.CertificateOverrides = []string{test.certificateOverride}
1586 }
Colin Crossae8600b2020-10-29 17:09:13 -07001587 ctx := testContext(config)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001588
1589 run(t, ctx, config)
1590 foo := ctx.ModuleForTests("foo", "android_common")
1591
1592 signapk := foo.Output("foo.apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07001593 signCertificateFlags := signapk.Args["certificates"]
1594 if test.expectedCertificate != signCertificateFlags {
1595 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedCertificate, signCertificateFlags)
1596 }
1597
1598 signFlags := signapk.Args["flags"]
1599 if test.expectedLineage != signFlags {
1600 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedLineage, signFlags)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001601 }
1602 })
1603 }
1604}
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001605
Songchun Fan688de9a2020-03-24 20:32:24 -07001606func TestRequestV4SigningFlag(t *testing.T) {
1607 testCases := []struct {
1608 name string
1609 bp string
1610 expected string
1611 }{
1612 {
1613 name: "default",
1614 bp: `
1615 android_app {
1616 name: "foo",
1617 srcs: ["a.java"],
1618 sdk_version: "current",
1619 }
1620 `,
1621 expected: "",
1622 },
1623 {
1624 name: "default",
1625 bp: `
1626 android_app {
1627 name: "foo",
1628 srcs: ["a.java"],
1629 sdk_version: "current",
1630 v4_signature: false,
1631 }
1632 `,
1633 expected: "",
1634 },
1635 {
1636 name: "module certificate property",
1637 bp: `
1638 android_app {
1639 name: "foo",
1640 srcs: ["a.java"],
1641 sdk_version: "current",
1642 v4_signature: true,
1643 }
1644 `,
1645 expected: "--enable-v4",
1646 },
1647 }
1648
1649 for _, test := range testCases {
1650 t.Run(test.name, func(t *testing.T) {
1651 config := testAppConfig(nil, test.bp, nil)
Colin Crossae8600b2020-10-29 17:09:13 -07001652 ctx := testContext(config)
Songchun Fan688de9a2020-03-24 20:32:24 -07001653
1654 run(t, ctx, config)
1655 foo := ctx.ModuleForTests("foo", "android_common")
1656
1657 signapk := foo.Output("foo.apk")
1658 signFlags := signapk.Args["flags"]
1659 if test.expected != signFlags {
1660 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
1661 }
1662 })
1663 }
1664}
1665
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001666func TestPackageNameOverride(t *testing.T) {
1667 testCases := []struct {
1668 name string
1669 bp string
1670 packageNameOverride string
1671 expected []string
1672 }{
1673 {
1674 name: "default",
1675 bp: `
1676 android_app {
1677 name: "foo",
1678 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001679 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001680 }
1681 `,
1682 packageNameOverride: "",
1683 expected: []string{
1684 buildDir + "/.intermediates/foo/android_common/foo.apk",
1685 buildDir + "/target/product/test_device/system/app/foo/foo.apk",
1686 },
1687 },
1688 {
1689 name: "overridden",
1690 bp: `
1691 android_app {
1692 name: "foo",
1693 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001694 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001695 }
1696 `,
1697 packageNameOverride: "foo:bar",
1698 expected: []string{
1699 // The package apk should be still be the original name for test dependencies.
Jaewoong Jung5a498812019-11-07 14:14:38 -08001700 buildDir + "/.intermediates/foo/android_common/bar.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001701 buildDir + "/target/product/test_device/system/app/bar/bar.apk",
1702 },
1703 },
1704 }
1705
1706 for _, test := range testCases {
1707 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001708 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001709 if test.packageNameOverride != "" {
1710 config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
1711 }
Colin Crossae8600b2020-10-29 17:09:13 -07001712 ctx := testContext(config)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001713
1714 run(t, ctx, config)
1715 foo := ctx.ModuleForTests("foo", "android_common")
1716
1717 outputs := foo.AllOutputs()
1718 outputMap := make(map[string]bool)
1719 for _, o := range outputs {
1720 outputMap[o] = true
1721 }
1722 for _, e := range test.expected {
1723 if _, exist := outputMap[e]; !exist {
1724 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
1725 }
1726 }
1727 })
1728 }
1729}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001730
1731func TestInstrumentationTargetOverridden(t *testing.T) {
1732 bp := `
1733 android_app {
1734 name: "foo",
1735 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001736 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001737 }
1738
1739 android_test {
1740 name: "bar",
1741 instrumentation_for: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001742 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001743 }
1744 `
Colin Cross98be1bb2019-12-13 20:41:13 -08001745 config := testAppConfig(nil, bp, nil)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001746 config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
Colin Crossae8600b2020-10-29 17:09:13 -07001747 ctx := testContext(config)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001748
1749 run(t, ctx, config)
1750
1751 bar := ctx.ModuleForTests("bar", "android_common")
1752 res := bar.Output("package-res.apk")
1753 aapt2Flags := res.Args["flags"]
1754 e := "--rename-instrumentation-target-package org.dandroid.bp"
1755 if !strings.Contains(aapt2Flags, e) {
1756 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
1757 }
1758}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001759
1760func TestOverrideAndroidApp(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001761 ctx, _ := testJava(t, `
Jaewoong Jung525443a2019-02-28 15:35:54 -08001762 android_app {
1763 name: "foo",
1764 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -07001765 certificate: "expiredkey",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001766 overrides: ["qux"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001767 sdk_version: "current",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001768 }
1769
1770 override_android_app {
1771 name: "bar",
1772 base: "foo",
1773 certificate: ":new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07001774 lineage: "lineage.bin",
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001775 logging_parent: "bah",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001776 }
1777
1778 android_app_certificate {
1779 name: "new_certificate",
1780 certificate: "cert/new_cert",
1781 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001782
1783 override_android_app {
1784 name: "baz",
1785 base: "foo",
1786 package_name: "org.dandroid.bp",
1787 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00001788
1789 override_android_app {
1790 name: "baz_no_rename_resources",
1791 base: "foo",
1792 package_name: "org.dandroid.bp",
1793 rename_resources_package: false,
1794 }
1795
1796 android_app {
1797 name: "foo_no_rename_resources",
1798 srcs: ["a.java"],
1799 certificate: "expiredkey",
1800 overrides: ["qux"],
1801 rename_resources_package: false,
1802 sdk_version: "current",
1803 }
1804
1805 override_android_app {
1806 name: "baz_base_no_rename_resources",
1807 base: "foo_no_rename_resources",
1808 package_name: "org.dandroid.bp",
1809 }
1810
1811 override_android_app {
1812 name: "baz_override_base_rename_resources",
1813 base: "foo_no_rename_resources",
1814 package_name: "org.dandroid.bp",
1815 rename_resources_package: true,
1816 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001817 `)
1818
1819 expectedVariants := []struct {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001820 name string
1821 moduleName string
1822 variantName string
1823 apkName string
1824 apkPath string
1825 certFlag string
1826 lineageFlag string
1827 overrides []string
1828 packageFlag string
1829 renameResources bool
1830 logging_parent string
Jaewoong Jung525443a2019-02-28 15:35:54 -08001831 }{
1832 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001833 name: "foo",
1834 moduleName: "foo",
1835 variantName: "android_common",
1836 apkPath: "/target/product/test_device/system/app/foo/foo.apk",
1837 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1838 lineageFlag: "",
1839 overrides: []string{"qux"},
1840 packageFlag: "",
1841 renameResources: false,
1842 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001843 },
1844 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001845 name: "foo",
1846 moduleName: "bar",
1847 variantName: "android_common_bar",
1848 apkPath: "/target/product/test_device/system/app/bar/bar.apk",
1849 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
1850 lineageFlag: "--lineage lineage.bin",
1851 overrides: []string{"qux", "foo"},
1852 packageFlag: "",
1853 renameResources: false,
1854 logging_parent: "bah",
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001855 },
1856 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001857 name: "foo",
1858 moduleName: "baz",
1859 variantName: "android_common_baz",
1860 apkPath: "/target/product/test_device/system/app/baz/baz.apk",
1861 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1862 lineageFlag: "",
1863 overrides: []string{"qux", "foo"},
1864 packageFlag: "org.dandroid.bp",
1865 renameResources: true,
1866 logging_parent: "",
1867 },
1868 {
1869 name: "foo",
1870 moduleName: "baz_no_rename_resources",
1871 variantName: "android_common_baz_no_rename_resources",
1872 apkPath: "/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
1873 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1874 lineageFlag: "",
1875 overrides: []string{"qux", "foo"},
1876 packageFlag: "org.dandroid.bp",
1877 renameResources: false,
1878 logging_parent: "",
1879 },
1880 {
1881 name: "foo_no_rename_resources",
1882 moduleName: "baz_base_no_rename_resources",
1883 variantName: "android_common_baz_base_no_rename_resources",
1884 apkPath: "/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
1885 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1886 lineageFlag: "",
1887 overrides: []string{"qux", "foo_no_rename_resources"},
1888 packageFlag: "org.dandroid.bp",
1889 renameResources: false,
1890 logging_parent: "",
1891 },
1892 {
1893 name: "foo_no_rename_resources",
1894 moduleName: "baz_override_base_rename_resources",
1895 variantName: "android_common_baz_override_base_rename_resources",
1896 apkPath: "/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
1897 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1898 lineageFlag: "",
1899 overrides: []string{"qux", "foo_no_rename_resources"},
1900 packageFlag: "org.dandroid.bp",
1901 renameResources: true,
1902 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001903 },
1904 }
1905 for _, expected := range expectedVariants {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001906 variant := ctx.ModuleForTests(expected.name, expected.variantName)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001907
1908 // Check the final apk name
1909 outputs := variant.AllOutputs()
1910 expectedApkPath := buildDir + expected.apkPath
1911 found := false
1912 for _, o := range outputs {
1913 if o == expectedApkPath {
1914 found = true
1915 break
1916 }
1917 }
1918 if !found {
1919 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
1920 }
1921
1922 // Check the certificate paths
Jaewoong Jung5a498812019-11-07 14:14:38 -08001923 signapk := variant.Output(expected.moduleName + ".apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07001924 certFlag := signapk.Args["certificates"]
1925 if expected.certFlag != certFlag {
1926 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.certFlag, certFlag)
1927 }
1928
1929 // Check the lineage flags
1930 lineageFlag := signapk.Args["flags"]
1931 if expected.lineageFlag != lineageFlag {
1932 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.lineageFlag, lineageFlag)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001933 }
1934
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001935 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -08001936 mod := variant.Module().(*AndroidApp)
1937 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
1938 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
1939 expected.overrides, mod.appProperties.Overrides)
1940 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001941
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001942 // Test Overridable property: Logging_parent
1943 logging_parent := mod.aapt.LoggingParent
1944 if expected.logging_parent != logging_parent {
1945 t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q",
1946 expected.logging_parent, logging_parent)
1947 }
1948
Liz Kammer1d5983b2020-05-19 19:15:37 +00001949 // Check the package renaming flag, if exists.
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001950 res := variant.Output("package-res.apk")
1951 aapt2Flags := res.Args["flags"]
Liz Kammer9f9fd022020-06-18 19:44:06 +00001952 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
1953 expectedPackage := expected.packageFlag
1954 if !expected.renameResources {
1955 expectedPackage = ""
Liz Kammer1d5983b2020-05-19 19:15:37 +00001956 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00001957 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001958 }
1959}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001960
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001961func TestOverrideAndroidAppDependency(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001962 ctx, _ := testJava(t, `
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001963 android_app {
1964 name: "foo",
1965 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001966 sdk_version: "current",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001967 }
1968
1969 override_android_app {
1970 name: "bar",
1971 base: "foo",
1972 package_name: "org.dandroid.bp",
1973 }
1974
1975 android_test {
1976 name: "baz",
1977 srcs: ["b.java"],
1978 instrumentation_for: "foo",
1979 }
1980
1981 android_test {
1982 name: "qux",
1983 srcs: ["b.java"],
1984 instrumentation_for: "bar",
1985 }
1986 `)
1987
1988 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
1989 javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
1990 fooTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
1991 if !strings.Contains(javac.Args["classpath"], fooTurbine) {
1992 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
1993 }
1994
1995 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
1996 javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
1997 barTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common_bar", "turbine-combined", "foo.jar")
1998 if !strings.Contains(javac.Args["classpath"], barTurbine) {
1999 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
2000 }
2001}
2002
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002003func TestOverrideAndroidTest(t *testing.T) {
2004 ctx, _ := testJava(t, `
2005 android_app {
2006 name: "foo",
2007 srcs: ["a.java"],
2008 package_name: "com.android.foo",
2009 sdk_version: "current",
2010 }
2011
2012 override_android_app {
2013 name: "bar",
2014 base: "foo",
2015 package_name: "com.android.bar",
2016 }
2017
2018 android_test {
2019 name: "foo_test",
2020 srcs: ["b.java"],
2021 instrumentation_for: "foo",
2022 }
2023
2024 override_android_test {
2025 name: "bar_test",
2026 base: "foo_test",
2027 package_name: "com.android.bar.test",
2028 instrumentation_for: "bar",
2029 instrumentation_target_package: "com.android.bar",
2030 }
2031 `)
2032
2033 expectedVariants := []struct {
2034 moduleName string
2035 variantName string
2036 apkPath string
2037 overrides []string
2038 targetVariant string
2039 packageFlag string
2040 targetPackageFlag string
2041 }{
2042 {
2043 variantName: "android_common",
Jaewoong Jung326a9412019-11-21 10:41:00 -08002044 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002045 overrides: nil,
2046 targetVariant: "android_common",
2047 packageFlag: "",
2048 targetPackageFlag: "",
2049 },
2050 {
2051 variantName: "android_common_bar_test",
Jaewoong Jung326a9412019-11-21 10:41:00 -08002052 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002053 overrides: []string{"foo_test"},
2054 targetVariant: "android_common_bar",
2055 packageFlag: "com.android.bar.test",
2056 targetPackageFlag: "com.android.bar",
2057 },
2058 }
2059 for _, expected := range expectedVariants {
2060 variant := ctx.ModuleForTests("foo_test", expected.variantName)
2061
2062 // Check the final apk name
2063 outputs := variant.AllOutputs()
2064 expectedApkPath := buildDir + expected.apkPath
2065 found := false
2066 for _, o := range outputs {
2067 if o == expectedApkPath {
2068 found = true
2069 break
2070 }
2071 }
2072 if !found {
2073 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
2074 }
2075
2076 // Check if the overrides field values are correctly aggregated.
2077 mod := variant.Module().(*AndroidTest)
2078 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
2079 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
2080 expected.overrides, mod.appProperties.Overrides)
2081 }
2082
2083 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
2084 javac := variant.Rule("javac")
2085 turbine := filepath.Join(buildDir, ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
2086 if !strings.Contains(javac.Args["classpath"], turbine) {
2087 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
2088 }
2089
2090 // Check aapt2 flags.
2091 res := variant.Output("package-res.apk")
2092 aapt2Flags := res.Args["flags"]
2093 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
Liz Kammer9f9fd022020-06-18 19:44:06 +00002094 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002095 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
2096 }
2097}
2098
Jaewoong Jung39982342020-01-14 10:27:18 -08002099func TestAndroidTest_FixTestConfig(t *testing.T) {
2100 ctx, _ := testJava(t, `
2101 android_app {
2102 name: "foo",
2103 srcs: ["a.java"],
2104 package_name: "com.android.foo",
2105 sdk_version: "current",
2106 }
2107
2108 android_test {
2109 name: "foo_test",
2110 srcs: ["b.java"],
2111 instrumentation_for: "foo",
2112 }
2113
2114 android_test {
2115 name: "bar_test",
2116 srcs: ["b.java"],
2117 package_name: "com.android.bar.test",
2118 instrumentation_for: "foo",
2119 }
2120
2121 override_android_test {
2122 name: "baz_test",
2123 base: "foo_test",
2124 package_name: "com.android.baz.test",
2125 }
2126 `)
2127
2128 testCases := []struct {
2129 moduleName string
2130 variantName string
2131 expectedFlags []string
2132 }{
2133 {
2134 moduleName: "foo_test",
2135 variantName: "android_common",
2136 },
2137 {
2138 moduleName: "bar_test",
2139 variantName: "android_common",
2140 expectedFlags: []string{
2141 "--manifest " + buildDir + "/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
2142 "--package-name com.android.bar.test",
2143 },
2144 },
2145 {
2146 moduleName: "foo_test",
2147 variantName: "android_common_baz_test",
2148 expectedFlags: []string{
2149 "--manifest " + buildDir +
2150 "/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
2151 "--package-name com.android.baz.test",
2152 "--test-file-name baz_test.apk",
2153 },
2154 },
2155 }
2156
2157 for _, test := range testCases {
2158 variant := ctx.ModuleForTests(test.moduleName, test.variantName)
2159 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
2160
2161 if len(test.expectedFlags) > 0 {
2162 if params.Rule == nil {
2163 t.Errorf("test_config_fixer was expected to run, but didn't")
2164 } else {
2165 for _, flag := range test.expectedFlags {
2166 if !strings.Contains(params.RuleParams.Command, flag) {
2167 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
2168 }
2169 }
2170 }
2171 } else {
2172 if params.Rule != nil {
2173 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
2174 }
2175 }
2176
2177 }
2178}
2179
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002180func TestStl(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002181 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002182 cc_library {
2183 name: "libjni",
Peter Collingbournead84f972019-12-17 16:46:18 -08002184 sdk_version: "current",
2185 stl: "c++_shared",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002186 }
2187
2188 android_test {
2189 name: "stl",
2190 jni_libs: ["libjni"],
2191 compile_multilib: "both",
2192 sdk_version: "current",
2193 stl: "c++_shared",
2194 }
2195
2196 android_test {
2197 name: "system",
2198 jni_libs: ["libjni"],
2199 compile_multilib: "both",
2200 sdk_version: "current",
2201 }
2202 `)
2203
2204 testCases := []struct {
2205 name string
2206 jnis []string
2207 }{
2208 {"stl",
2209 []string{
2210 "libjni.so",
Jaewoong Jung710756a2019-06-04 11:53:47 -07002211 "libc++_shared.so",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002212 },
2213 },
2214 {"system",
2215 []string{
2216 "libjni.so",
2217 },
2218 },
2219 }
2220
2221 for _, test := range testCases {
2222 t.Run(test.name, func(t *testing.T) {
2223 app := ctx.ModuleForTests(test.name, "android_common")
2224 jniLibZip := app.Output("jnilibs.zip")
2225 var jnis []string
2226 args := strings.Fields(jniLibZip.Args["jarArgs"])
2227 for i := 0; i < len(args); i++ {
2228 if args[i] == "-f" {
2229 jnis = append(jnis, args[i+1])
2230 i += 1
2231 }
2232 }
2233 jnisJoined := strings.Join(jnis, " ")
2234 for _, jni := range test.jnis {
2235 if !strings.Contains(jnisJoined, jni) {
2236 t.Errorf("missing jni %q in %q", jni, jnis)
2237 }
2238 }
2239 })
2240 }
2241}
Colin Cross50ddcc42019-05-16 12:28:22 -07002242
2243func TestUsesLibraries(t *testing.T) {
2244 bp := `
2245 java_sdk_library {
2246 name: "foo",
2247 srcs: ["a.java"],
2248 api_packages: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002249 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002250 }
2251
2252 java_sdk_library {
Paul Duffin859fe962020-05-15 10:20:31 +01002253 name: "qux",
2254 srcs: ["a.java"],
2255 api_packages: ["qux"],
2256 sdk_version: "current",
2257 }
2258
2259 java_sdk_library {
2260 name: "quuz",
2261 srcs: ["a.java"],
2262 api_packages: ["quuz"],
2263 sdk_version: "current",
2264 }
2265
2266 java_sdk_library {
Ulya Trafimovich65b03192020-12-03 16:50:22 +00002267 name: "fred",
2268 srcs: ["a.java"],
2269 api_packages: ["fred"],
2270 sdk_version: "current",
2271 }
2272
2273 java_sdk_library {
Colin Cross50ddcc42019-05-16 12:28:22 -07002274 name: "bar",
2275 srcs: ["a.java"],
2276 api_packages: ["bar"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002277 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002278 }
2279
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01002280 java_sdk_library {
2281 name: "runtime-library",
2282 srcs: ["a.java"],
2283 sdk_version: "current",
2284 }
2285
2286 java_library {
2287 name: "static-runtime-helper",
2288 srcs: ["a.java"],
2289 libs: ["runtime-library"],
2290 sdk_version: "current",
2291 }
2292
Colin Cross50ddcc42019-05-16 12:28:22 -07002293 android_app {
2294 name: "app",
2295 srcs: ["a.java"],
Paul Duffin859fe962020-05-15 10:20:31 +01002296 libs: ["qux", "quuz.stubs"],
Ulya Trafimovich65b03192020-12-03 16:50:22 +00002297 static_libs: [
2298 "static-runtime-helper",
2299 // statically linked component libraries should not pull their SDK libraries,
2300 // so "fred" should not be added to class loader context
2301 "fred.stubs",
2302 ],
Colin Cross50ddcc42019-05-16 12:28:22 -07002303 uses_libs: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002304 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002305 optional_uses_libs: [
2306 "bar",
2307 "baz",
2308 ],
2309 }
2310
2311 android_app_import {
2312 name: "prebuilt",
2313 apk: "prebuilts/apk/app.apk",
2314 certificate: "platform",
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002315 uses_libs: ["foo", "android.test.runner"],
Colin Cross50ddcc42019-05-16 12:28:22 -07002316 optional_uses_libs: [
2317 "bar",
2318 "baz",
2319 ],
2320 }
2321 `
2322
Colin Cross98be1bb2019-12-13 20:41:13 -08002323 config := testAppConfig(nil, bp, nil)
Colin Cross50ddcc42019-05-16 12:28:22 -07002324 config.TestProductVariables.MissingUsesLibraries = []string{"baz"}
2325
Colin Crossae8600b2020-10-29 17:09:13 -07002326 ctx := testContext(config)
Colin Cross50ddcc42019-05-16 12:28:22 -07002327
2328 run(t, ctx, config)
2329
2330 app := ctx.ModuleForTests("app", "android_common")
2331 prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
2332
Paul Duffin859fe962020-05-15 10:20:31 +01002333 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
2334 manifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01002335 for _, w := range []string{"qux", "quuz", "runtime-library"} {
2336 if !strings.Contains(manifestFixerArgs, "--uses-library "+w) {
2337 t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
2338 }
Paul Duffin859fe962020-05-15 10:20:31 +01002339 }
2340
Colin Cross50ddcc42019-05-16 12:28:22 -07002341 // Test that all libraries are verified
2342 cmd := app.Rule("verify_uses_libraries").RuleParams.Command
2343 if w := "--uses-library foo"; !strings.Contains(cmd, w) {
2344 t.Errorf("wanted %q in %q", w, cmd)
2345 }
2346
2347 if w := "--optional-uses-library bar --optional-uses-library baz"; !strings.Contains(cmd, w) {
2348 t.Errorf("wanted %q in %q", w, cmd)
2349 }
2350
2351 cmd = prebuilt.Rule("verify_uses_libraries").RuleParams.Command
2352
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002353 if w := `uses_library_names="foo android.test.runner"`; !strings.Contains(cmd, w) {
Colin Cross50ddcc42019-05-16 12:28:22 -07002354 t.Errorf("wanted %q in %q", w, cmd)
2355 }
2356
2357 if w := `optional_uses_library_names="bar baz"`; !strings.Contains(cmd, w) {
2358 t.Errorf("wanted %q in %q", w, cmd)
2359 }
2360
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002361 // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs
Colin Cross50ddcc42019-05-16 12:28:22 -07002362 cmd = app.Rule("dexpreopt").RuleParams.Command
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002363 w := `--target-context-for-sdk any ` +
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002364 `PCL[/system/framework/qux.jar]#` +
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002365 `PCL[/system/framework/quuz.jar]#` +
2366 `PCL[/system/framework/foo.jar]#` +
2367 `PCL[/system/framework/bar.jar]#` +
2368 `PCL[/system/framework/runtime-library.jar]`
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002369 if !strings.Contains(cmd, w) {
Colin Cross50ddcc42019-05-16 12:28:22 -07002370 t.Errorf("wanted %q in %q", w, cmd)
2371 }
2372
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002373 // Test conditional context for target SDK version 28.
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002374 if w := `--target-context-for-sdk 28` +
2375 ` PCL[/system/framework/org.apache.http.legacy.jar] `; !strings.Contains(cmd, w) {
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002376 t.Errorf("wanted %q in %q", w, cmd)
2377 }
2378
2379 // Test conditional context for target SDK version 29.
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002380 if w := `--target-context-for-sdk 29` +
Ulya Trafimovichc9f2b942020-12-23 15:41:29 +00002381 ` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]` +
2382 `#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `; !strings.Contains(cmd, w) {
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002383 t.Errorf("wanted %q in %q", w, cmd)
2384 }
2385
2386 // Test conditional context for target SDK version 30.
Ulya Trafimovich46b3d5b2020-10-21 13:20:55 +01002387 // "android.test.mock" is absent because "android.test.runner" is not used.
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002388 if w := `--target-context-for-sdk 30` +
2389 ` PCL[/system/framework/android.test.base.jar] `; !strings.Contains(cmd, w) {
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002390 t.Errorf("wanted %q in %q", w, cmd)
2391 }
2392
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002393 cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002394 if w := `--target-context-for-sdk any` +
2395 ` PCL[/system/framework/foo.jar]` +
2396 `#PCL[/system/framework/android.test.runner.jar]` +
2397 `#PCL[/system/framework/bar.jar] `; !strings.Contains(cmd, w) {
Ulya Trafimovich24813e12020-10-07 15:05:21 +01002398 t.Errorf("wanted %q in %q", w, cmd)
2399 }
2400
2401 // Test conditional context for target SDK version 30.
Ulya Trafimovich46b3d5b2020-10-21 13:20:55 +01002402 // "android.test.mock" is present because "android.test.runner" is used.
Ulya Trafimovich8130c482020-10-07 15:17:13 +01002403 if w := `--target-context-for-sdk 30` +
2404 ` PCL[/system/framework/android.test.base.jar]` +
2405 `#PCL[/system/framework/android.test.mock.jar] `; !strings.Contains(cmd, w) {
Colin Cross50ddcc42019-05-16 12:28:22 -07002406 t.Errorf("wanted %q in %q", w, cmd)
2407 }
2408}
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002409
2410func TestCodelessApp(t *testing.T) {
2411 testCases := []struct {
2412 name string
2413 bp string
2414 noCode bool
2415 }{
2416 {
2417 name: "normal",
2418 bp: `
2419 android_app {
2420 name: "foo",
2421 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002422 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002423 }
2424 `,
2425 noCode: false,
2426 },
2427 {
2428 name: "app without sources",
2429 bp: `
2430 android_app {
2431 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002432 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002433 }
2434 `,
2435 noCode: true,
2436 },
2437 {
2438 name: "app with libraries",
2439 bp: `
2440 android_app {
2441 name: "foo",
2442 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002443 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002444 }
2445
2446 java_library {
2447 name: "lib",
2448 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002449 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002450 }
2451 `,
2452 noCode: false,
2453 },
2454 {
2455 name: "app with sourceless libraries",
2456 bp: `
2457 android_app {
2458 name: "foo",
2459 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002460 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002461 }
2462
2463 java_library {
2464 name: "lib",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002465 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002466 }
2467 `,
2468 // TODO(jungjw): this should probably be true
2469 noCode: false,
2470 },
2471 }
2472
2473 for _, test := range testCases {
2474 t.Run(test.name, func(t *testing.T) {
2475 ctx := testApp(t, test.bp)
2476
2477 foo := ctx.ModuleForTests("foo", "android_common")
2478 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
2479 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
2480 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
2481 }
2482 })
2483 }
2484}
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002485
2486func TestEmbedNotice(t *testing.T) {
Colin Cross238c1f32020-06-07 16:58:18 -07002487 ctx, _ := testJavaWithFS(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002488 android_app {
2489 name: "foo",
2490 srcs: ["a.java"],
2491 static_libs: ["javalib"],
2492 jni_libs: ["libjni"],
2493 notice: "APP_NOTICE",
2494 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002495 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002496 }
2497
2498 // No embed_notice flag
2499 android_app {
2500 name: "bar",
2501 srcs: ["a.java"],
2502 jni_libs: ["libjni"],
2503 notice: "APP_NOTICE",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002504 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002505 }
2506
2507 // No NOTICE files
2508 android_app {
2509 name: "baz",
2510 srcs: ["a.java"],
2511 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002512 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002513 }
2514
2515 cc_library {
2516 name: "libjni",
2517 system_shared_libs: [],
2518 stl: "none",
2519 notice: "LIB_NOTICE",
Colin Cross094cde42020-02-15 10:38:00 -08002520 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002521 }
2522
2523 java_library {
2524 name: "javalib",
2525 srcs: [
2526 ":gen",
2527 ],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002528 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002529 }
2530
2531 genrule {
2532 name: "gen",
2533 tools: ["gentool"],
2534 out: ["gen.java"],
2535 notice: "GENRULE_NOTICE",
2536 }
2537
2538 java_binary_host {
2539 name: "gentool",
2540 srcs: ["b.java"],
2541 notice: "TOOL_NOTICE",
2542 }
Colin Cross238c1f32020-06-07 16:58:18 -07002543 `, map[string][]byte{
2544 "APP_NOTICE": nil,
2545 "GENRULE_NOTICE": nil,
2546 "LIB_NOTICE": nil,
2547 "TOOL_NOTICE": nil,
2548 })
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002549
2550 // foo has NOTICE files to process, and embed_notices is true.
2551 foo := ctx.ModuleForTests("foo", "android_common")
2552 // verify merge notices rule.
2553 mergeNotices := foo.Rule("mergeNoticesRule")
2554 noticeInputs := mergeNotices.Inputs.Strings()
2555 // TOOL_NOTICE should be excluded as it's a host module.
2556 if len(mergeNotices.Inputs) != 3 {
2557 t.Errorf("number of input notice files: expected = 3, actual = %q", noticeInputs)
2558 }
2559 if !inList("APP_NOTICE", noticeInputs) {
2560 t.Errorf("APP_NOTICE is missing from notice files, %q", noticeInputs)
2561 }
2562 if !inList("LIB_NOTICE", noticeInputs) {
2563 t.Errorf("LIB_NOTICE is missing from notice files, %q", noticeInputs)
2564 }
2565 if !inList("GENRULE_NOTICE", noticeInputs) {
2566 t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs)
2567 }
2568 // aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets.
2569 res := foo.Output("package-res.apk")
2570 aapt2Flags := res.Args["flags"]
2571 e := "-A " + buildDir + "/.intermediates/foo/android_common/NOTICE"
2572 if !strings.Contains(aapt2Flags, e) {
2573 t.Errorf("asset dir flag for NOTICE, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
2574 }
2575
2576 // bar has NOTICE files to process, but embed_notices is not set.
2577 bar := ctx.ModuleForTests("bar", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07002578 res = bar.Output("package-res.apk")
2579 aapt2Flags = res.Args["flags"]
2580 e = "-A " + buildDir + "/.intermediates/bar/android_common/NOTICE"
2581 if strings.Contains(aapt2Flags, e) {
2582 t.Errorf("bar shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002583 }
2584
2585 // baz's embed_notice is true, but it doesn't have any NOTICE files.
2586 baz := ctx.ModuleForTests("baz", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07002587 res = baz.Output("package-res.apk")
2588 aapt2Flags = res.Args["flags"]
2589 e = "-A " + buildDir + "/.intermediates/baz/android_common/NOTICE"
2590 if strings.Contains(aapt2Flags, e) {
2591 t.Errorf("baz shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002592 }
2593}
Colin Cross53a87f52019-06-25 13:35:30 -07002594
2595func TestUncompressDex(t *testing.T) {
2596 testCases := []struct {
2597 name string
2598 bp string
2599
2600 uncompressedPlatform bool
2601 uncompressedUnbundled bool
2602 }{
2603 {
2604 name: "normal",
2605 bp: `
2606 android_app {
2607 name: "foo",
2608 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002609 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002610 }
2611 `,
2612 uncompressedPlatform: true,
2613 uncompressedUnbundled: false,
2614 },
2615 {
2616 name: "use_embedded_dex",
2617 bp: `
2618 android_app {
2619 name: "foo",
2620 use_embedded_dex: true,
2621 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002622 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002623 }
2624 `,
2625 uncompressedPlatform: true,
2626 uncompressedUnbundled: true,
2627 },
2628 {
2629 name: "privileged",
2630 bp: `
2631 android_app {
2632 name: "foo",
2633 privileged: true,
2634 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002635 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002636 }
2637 `,
2638 uncompressedPlatform: true,
2639 uncompressedUnbundled: true,
2640 },
David Srbeckye033cba2020-05-20 22:20:28 +01002641 {
2642 name: "normal_uncompress_dex_true",
2643 bp: `
2644 android_app {
2645 name: "foo",
2646 srcs: ["a.java"],
2647 sdk_version: "current",
2648 uncompress_dex: true,
2649 }
2650 `,
2651 uncompressedPlatform: true,
2652 uncompressedUnbundled: true,
2653 },
2654 {
2655 name: "normal_uncompress_dex_false",
2656 bp: `
2657 android_app {
2658 name: "foo",
2659 srcs: ["a.java"],
2660 sdk_version: "current",
2661 uncompress_dex: false,
2662 }
2663 `,
2664 uncompressedPlatform: false,
2665 uncompressedUnbundled: false,
2666 },
Colin Cross53a87f52019-06-25 13:35:30 -07002667 }
2668
2669 test := func(t *testing.T, bp string, want bool, unbundled bool) {
2670 t.Helper()
2671
Colin Cross98be1bb2019-12-13 20:41:13 -08002672 config := testAppConfig(nil, bp, nil)
Colin Cross53a87f52019-06-25 13:35:30 -07002673 if unbundled {
2674 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
Jeongik Cha816a23a2020-07-08 01:09:23 +09002675 config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
Colin Cross53a87f52019-06-25 13:35:30 -07002676 }
2677
Colin Crossae8600b2020-10-29 17:09:13 -07002678 ctx := testContext(config)
Colin Cross53a87f52019-06-25 13:35:30 -07002679
2680 run(t, ctx, config)
2681
2682 foo := ctx.ModuleForTests("foo", "android_common")
2683 dex := foo.Rule("r8")
2684 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
2685 aligned := foo.MaybeRule("zipalign").Rule != nil
2686
2687 if uncompressedInDexJar != want {
2688 t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar)
2689 }
2690
2691 if aligned != want {
2692 t.Errorf("want aligned %v, got %v", want, aligned)
2693 }
2694 }
2695
2696 for _, tt := range testCases {
2697 t.Run(tt.name, func(t *testing.T) {
2698 t.Run("platform", func(t *testing.T) {
2699 test(t, tt.bp, tt.uncompressedPlatform, false)
2700 })
2701 t.Run("unbundled", func(t *testing.T) {
2702 test(t, tt.bp, tt.uncompressedUnbundled, true)
2703 })
2704 })
2705 }
2706}
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002707
2708func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
2709 if expectedValue != "" {
2710 expectedFlag := "--" + flagName + " " + expectedValue
2711 if !strings.Contains(aapt2Flags, expectedFlag) {
2712 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
2713 }
2714 } else {
2715 unexpectedFlag := "--" + flagName
2716 if strings.Contains(aapt2Flags, unexpectedFlag) {
2717 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
2718 }
2719 }
2720}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002721
Cole Faust9a631312020-10-22 21:05:24 +00002722func TestExportedProguardFlagFiles(t *testing.T) {
2723 ctx, _ := testJava(t, `
2724 android_app {
2725 name: "foo",
2726 sdk_version: "current",
2727 static_libs: ["lib1"],
2728 }
2729
2730 android_library {
2731 name: "lib1",
2732 sdk_version: "current",
2733 optimize: {
2734 proguard_flags_files: ["lib1proguard.cfg"],
2735 }
2736 }
2737 `)
2738
2739 m := ctx.ModuleForTests("foo", "android_common")
2740 hasLib1Proguard := false
2741 for _, s := range m.Rule("java.r8").Implicits.Strings() {
2742 if s == "lib1proguard.cfg" {
2743 hasLib1Proguard = true
2744 break
2745 }
2746 }
2747
2748 if !hasLib1Proguard {
2749 t.Errorf("App does not use library proguard config")
2750 }
2751}