blob: 39460dce6a61c19c29c744569a691580d75779c7 [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"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070021 "regexp"
Colin Crossb69301e2017-12-01 10:48:26 -080022 "sort"
Colin Crossd09b0b62018-04-18 11:06:47 -070023 "strings"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080024 "testing"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070025
26 "github.com/google/blueprint/proptools"
27
28 "android/soong/android"
29 "android/soong/cc"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080030)
31
32var (
33 resourceFiles = []string{
34 "res/layout/layout.xml",
35 "res/values/strings.xml",
36 "res/values-en-rUS/strings.xml",
37 }
38
39 compiledResourceFiles = []string{
40 "aapt2/res/layout_layout.xml.flat",
41 "aapt2/res/values_strings.arsc.flat",
42 "aapt2/res/values-en-rUS_strings.arsc.flat",
43 }
44)
45
Colin Cross98be1bb2019-12-13 20:41:13 -080046func testAppConfig(env map[string]string, bp string, fs map[string][]byte) android.Config {
Colin Cross527012a2017-11-30 22:56:16 -080047 appFS := map[string][]byte{}
48 for k, v := range fs {
49 appFS[k] = v
Colin Cross3bc7ffa2017-11-22 16:19:37 -080050 }
51
Colin Cross527012a2017-11-30 22:56:16 -080052 for _, file := range resourceFiles {
53 appFS[file] = nil
54 }
55
Colin Cross98be1bb2019-12-13 20:41:13 -080056 return testConfig(env, bp, appFS)
Colin Cross527012a2017-11-30 22:56:16 -080057}
58
59func testApp(t *testing.T, bp string) *android.TestContext {
Colin Cross98be1bb2019-12-13 20:41:13 -080060 config := testAppConfig(nil, bp, nil)
Colin Cross527012a2017-11-30 22:56:16 -080061
Colin Cross98be1bb2019-12-13 20:41:13 -080062 ctx := testContext()
Colin Cross527012a2017-11-30 22:56:16 -080063
64 run(t, ctx, config)
65
66 return ctx
Colin Cross3bc7ffa2017-11-22 16:19:37 -080067}
68
69func TestApp(t *testing.T) {
Colin Crossa97c5d32018-03-28 14:58:31 -070070 for _, moduleType := range []string{"android_app", "android_library"} {
71 t.Run(moduleType, func(t *testing.T) {
72 ctx := testApp(t, moduleType+` {
73 name: "foo",
74 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +090075 sdk_version: "current"
Colin Crossa97c5d32018-03-28 14:58:31 -070076 }
77 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080078
Colin Crossa97c5d32018-03-28 14:58:31 -070079 foo := ctx.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080080
Colin Cross31656952018-05-24 16:11:20 -070081 var expectedLinkImplicits []string
82
83 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
84 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080085
Colin Crossa97c5d32018-03-28 14:58:31 -070086 frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
87 expectedLinkImplicits = append(expectedLinkImplicits,
88 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080089
Colin Crossa97c5d32018-03-28 14:58:31 -070090 // Test the mapping from input files to compiled output file names
91 compile := foo.Output(compiledResourceFiles[0])
92 if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
93 t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
94 resourceFiles, compile.Inputs.Strings())
95 }
Colin Crossb69301e2017-12-01 10:48:26 -080096
Colin Crossa97c5d32018-03-28 14:58:31 -070097 compiledResourceOutputs := compile.Outputs.Strings()
98 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -080099
Colin Crossa97c5d32018-03-28 14:58:31 -0700100 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800101
Colin Crossa97c5d32018-03-28 14:58:31 -0700102 list := foo.Output("aapt2/res.list")
103 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800104
Colin Crossa97c5d32018-03-28 14:58:31 -0700105 // Check that the link rule uses
106 res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
107 if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
108 t.Errorf("expected aapt2 link implicits expected:\n %#v\n got:\n %#v",
109 expectedLinkImplicits, res.Implicits.Strings())
110 }
111 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800112 }
113}
Colin Cross890ff552017-11-30 20:13:19 -0800114
Colin Crosse560c4a2019-03-19 16:03:11 -0700115func TestAppSplits(t *testing.T) {
116 ctx := testApp(t, `
117 android_app {
118 name: "foo",
119 srcs: ["a.java"],
120 package_splits: ["v4", "v7,hdpi"],
Jeongik Cha538c0d02019-07-11 15:54:27 +0900121 sdk_version: "current"
Colin Crosse560c4a2019-03-19 16:03:11 -0700122 }`)
123
124 foo := ctx.ModuleForTests("foo", "android_common")
125
126 expectedOutputs := []string{
127 filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
128 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
129 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
130 }
131 for _, expectedOutput := range expectedOutputs {
132 foo.Output(expectedOutput)
133 }
134
Colin Cross41955e82019-05-29 14:40:35 -0700135 outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
136 if err != nil {
137 t.Fatal(err)
138 }
139 if g, w := outputFiles.Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
140 t.Errorf(`want OutputFiles("") = %q, got %q`, w, g)
Colin Crosse560c4a2019-03-19 16:03:11 -0700141 }
142}
143
Jeongik Cha538c0d02019-07-11 15:54:27 +0900144func TestPlatformAPIs(t *testing.T) {
145 testJava(t, `
146 android_app {
147 name: "foo",
148 srcs: ["a.java"],
149 platform_apis: true,
150 }
151 `)
152
153 testJava(t, `
154 android_app {
155 name: "foo",
156 srcs: ["a.java"],
157 sdk_version: "current",
158 }
159 `)
160
161 testJavaError(t, "platform_apis must be true when sdk_version is empty.", `
162 android_app {
163 name: "bar",
164 srcs: ["b.java"],
165 }
166 `)
167
168 testJavaError(t, "platform_apis must be false when sdk_version is not empty.", `
169 android_app {
170 name: "bar",
171 srcs: ["b.java"],
172 sdk_version: "system_current",
173 platform_apis: true,
174 }
175 `)
176}
177
Jeongik Chae403e9e2019-12-07 00:16:24 +0900178func TestAndroidAppLinkType(t *testing.T) {
179 testJava(t, `
180 android_app {
181 name: "foo",
182 srcs: ["a.java"],
183 libs: ["bar"],
184 static_libs: ["baz"],
185 platform_apis: true,
186 }
187
188 java_library {
189 name: "bar",
190 sdk_version: "current",
191 srcs: ["b.java"],
192 }
193
194 android_library {
195 name: "baz",
196 sdk_version: "system_current",
197 srcs: ["c.java"],
198 }
199 `)
200
201 testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
202 android_app {
203 name: "foo",
204 srcs: ["a.java"],
205 libs: ["bar"],
206 sdk_version: "current",
207 static_libs: ["baz"],
208 }
209
210 java_library {
211 name: "bar",
212 sdk_version: "current",
213 srcs: ["b.java"],
214 }
215
216 android_library {
217 name: "baz",
218 sdk_version: "system_current",
219 srcs: ["c.java"],
220 }
221 `)
222
223 testJava(t, `
224 android_app {
225 name: "foo",
226 srcs: ["a.java"],
227 libs: ["bar"],
228 sdk_version: "system_current",
229 static_libs: ["baz"],
230 }
231
232 java_library {
233 name: "bar",
234 sdk_version: "current",
235 srcs: ["b.java"],
236 }
237
238 android_library {
239 name: "baz",
240 sdk_version: "system_current",
241 srcs: ["c.java"],
242 }
243 `)
244
245 testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
246 android_app {
247 name: "foo",
248 srcs: ["a.java"],
249 libs: ["bar"],
250 sdk_version: "system_current",
251 static_libs: ["baz"],
252 }
253
254 java_library {
255 name: "bar",
256 sdk_version: "current",
257 srcs: ["b.java"],
258 }
259
260 android_library {
261 name: "baz",
262 srcs: ["c.java"],
263 }
264 `)
265}
266
Artur Satayeve5ac15a2020-04-08 19:09:30 +0100267func TestUpdatableApps(t *testing.T) {
268 testCases := []struct {
269 name string
270 bp string
271 expectedError string
272 }{
273 {
274 name: "Stable public SDK",
275 bp: `android_app {
276 name: "foo",
277 srcs: ["a.java"],
278 sdk_version: "29",
279 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",
288 updatable: true,
289 }`,
290 },
291 {
292 name: "Current public SDK",
293 bp: `android_app {
294 name: "foo",
295 srcs: ["a.java"],
296 sdk_version: "current",
297 updatable: true,
298 }`,
299 },
300 {
301 name: "Current system SDK",
302 bp: `android_app {
303 name: "foo",
304 srcs: ["a.java"],
305 sdk_version: "system_current",
306 updatable: true,
307 }`,
308 },
309 {
310 name: "Current module SDK",
311 bp: `android_app {
312 name: "foo",
313 srcs: ["a.java"],
314 sdk_version: "module_current",
315 updatable: true,
316 }`,
317 },
318 {
319 name: "Current core SDK",
320 bp: `android_app {
321 name: "foo",
322 srcs: ["a.java"],
323 sdk_version: "core_current",
324 updatable: true,
325 }`,
326 },
327 {
328 name: "No Platform APIs",
329 bp: `android_app {
330 name: "foo",
331 srcs: ["a.java"],
332 platform_apis: true,
333 updatable: true,
334 }`,
335 expectedError: "Updatable apps must use stable SDKs",
336 },
337 {
338 name: "No Core Platform APIs",
339 bp: `android_app {
340 name: "foo",
341 srcs: ["a.java"],
342 sdk_version: "core_platform",
343 updatable: true,
344 }`,
345 expectedError: "Updatable apps must use stable SDKs",
346 },
347 {
348 name: "No unspecified APIs",
349 bp: `android_app {
350 name: "foo",
351 srcs: ["a.java"],
352 updatable: true,
353 }`,
354 expectedError: "Updatable apps must use stable SDK",
355 },
356 }
357
358 for _, test := range testCases {
359 t.Run(test.name, func(t *testing.T) {
360 if test.expectedError == "" {
361 testJava(t, test.bp)
362 } else {
363 testJavaError(t, test.expectedError, test.bp)
364 }
365 })
366 }
367}
368
Colin Cross0ddae7f2019-02-07 15:30:01 -0800369func TestResourceDirs(t *testing.T) {
370 testCases := []struct {
371 name string
372 prop string
373 resources []string
374 }{
375 {
376 name: "no resource_dirs",
377 prop: "",
378 resources: []string{"res/res/values/strings.xml"},
379 },
380 {
381 name: "resource_dirs",
382 prop: `resource_dirs: ["res"]`,
383 resources: []string{"res/res/values/strings.xml"},
384 },
385 {
386 name: "empty resource_dirs",
387 prop: `resource_dirs: []`,
388 resources: nil,
389 },
390 }
391
392 fs := map[string][]byte{
393 "res/res/values/strings.xml": nil,
394 }
395
396 bp := `
397 android_app {
398 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900399 sdk_version: "current",
Colin Cross0ddae7f2019-02-07 15:30:01 -0800400 %s
401 }
402 `
403
404 for _, testCase := range testCases {
405 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800406 config := testConfig(nil, fmt.Sprintf(bp, testCase.prop), fs)
407 ctx := testContext()
Colin Cross0ddae7f2019-02-07 15:30:01 -0800408 run(t, ctx, config)
409
410 module := ctx.ModuleForTests("foo", "android_common")
411 resourceList := module.MaybeOutput("aapt2/res.list")
412
413 var resources []string
414 if resourceList.Rule != nil {
415 for _, compiledResource := range resourceList.Inputs.Strings() {
416 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
417 }
418 }
419
420 if !reflect.DeepEqual(resources, testCase.resources) {
421 t.Errorf("expected resource files %q, got %q",
422 testCase.resources, resources)
423 }
424 })
425 }
426}
427
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800428func TestLibraryAssets(t *testing.T) {
429 bp := `
430 android_app {
431 name: "foo",
432 sdk_version: "current",
433 static_libs: ["lib1", "lib2", "lib3"],
434 }
435
436 android_library {
437 name: "lib1",
438 sdk_version: "current",
439 asset_dirs: ["assets_a"],
440 }
441
442 android_library {
443 name: "lib2",
444 sdk_version: "current",
445 }
446
447 android_library {
448 name: "lib3",
449 sdk_version: "current",
450 static_libs: ["lib4"],
451 }
452
453 android_library {
454 name: "lib4",
455 sdk_version: "current",
456 asset_dirs: ["assets_b"],
457 }
458 `
459
460 testCases := []struct {
461 name string
462 assetFlag string
463 assetPackages []string
464 }{
465 {
466 name: "foo",
467 // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
468 assetPackages: []string{
469 buildDir + "/.intermediates/foo/android_common/aapt2/package-res.apk",
470 buildDir + "/.intermediates/lib1/android_common/assets.zip",
471 buildDir + "/.intermediates/lib3/android_common/assets.zip",
472 },
473 },
474 {
475 name: "lib1",
476 assetFlag: "-A assets_a",
477 },
478 {
479 name: "lib2",
480 },
481 {
482 name: "lib3",
483 assetPackages: []string{
484 buildDir + "/.intermediates/lib3/android_common/aapt2/package-res.apk",
485 buildDir + "/.intermediates/lib4/android_common/assets.zip",
486 },
487 },
488 {
489 name: "lib4",
490 assetFlag: "-A assets_b",
491 },
492 }
493 ctx := testApp(t, bp)
494
495 for _, test := range testCases {
496 t.Run(test.name, func(t *testing.T) {
497 m := ctx.ModuleForTests(test.name, "android_common")
498
499 // Check asset flag in aapt2 link flags
500 var aapt2link android.TestingBuildParams
501 if len(test.assetPackages) > 0 {
502 aapt2link = m.Output("aapt2/package-res.apk")
503 } else {
504 aapt2link = m.Output("package-res.apk")
505 }
506 aapt2Flags := aapt2link.Args["flags"]
507 if test.assetFlag != "" {
508 if !strings.Contains(aapt2Flags, test.assetFlag) {
509 t.Errorf("Can't find asset flag %q in aapt2 link flags %q", test.assetFlag, aapt2Flags)
510 }
511 } else {
512 if strings.Contains(aapt2Flags, " -A ") {
513 t.Errorf("aapt2 link flags %q contain unexpected asset flag", aapt2Flags)
514 }
515 }
516
517 // Check asset merge rule.
518 if len(test.assetPackages) > 0 {
519 mergeAssets := m.Output("package-res.apk")
520 if !reflect.DeepEqual(test.assetPackages, mergeAssets.Inputs.Strings()) {
521 t.Errorf("Unexpected mergeAssets inputs: %v, expected: %v",
522 mergeAssets.Inputs.Strings(), test.assetPackages)
523 }
524 }
525 })
526 }
527}
528
Colin Crossbec85302019-02-13 13:15:46 -0800529func TestAndroidResources(t *testing.T) {
Colin Cross5c4791c2019-02-01 11:44:44 -0800530 testCases := []struct {
531 name string
532 enforceRROTargets []string
533 enforceRROExcludedOverlays []string
Colin Crossbec85302019-02-13 13:15:46 -0800534 resourceFiles map[string][]string
Colin Cross5c4791c2019-02-01 11:44:44 -0800535 overlayFiles map[string][]string
536 rroDirs map[string][]string
537 }{
538 {
539 name: "no RRO",
540 enforceRROTargets: nil,
541 enforceRROExcludedOverlays: nil,
Colin Crossbec85302019-02-13 13:15:46 -0800542 resourceFiles: map[string][]string{
543 "foo": nil,
544 "bar": {"bar/res/res/values/strings.xml"},
545 "lib": nil,
546 "lib2": {"lib2/res/res/values/strings.xml"},
547 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800548 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800549 "foo": {
550 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800551 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000552 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800553 "foo/res/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800554 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
555 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Anton Hansson53c88442019-03-18 15:53:16 +0000556 "product/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800557 },
Colin Crossbec85302019-02-13 13:15:46 -0800558 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800559 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
560 "device/vendor/blah/overlay/bar/res/values/strings.xml",
561 },
Colin Crossbec85302019-02-13 13:15:46 -0800562 "lib": {
563 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
564 "lib/res/res/values/strings.xml",
565 "device/vendor/blah/overlay/lib/res/values/strings.xml",
566 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800567 },
568 rroDirs: map[string][]string{
569 "foo": nil,
570 "bar": nil,
571 },
572 },
573 {
574 name: "enforce RRO on foo",
575 enforceRROTargets: []string{"foo"},
576 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossbec85302019-02-13 13:15:46 -0800577 resourceFiles: map[string][]string{
578 "foo": nil,
579 "bar": {"bar/res/res/values/strings.xml"},
580 "lib": nil,
581 "lib2": {"lib2/res/res/values/strings.xml"},
582 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800583 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800584 "foo": {
585 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800586 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000587 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800588 "foo/res/res/values/strings.xml",
589 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
590 },
Colin Crossbec85302019-02-13 13:15:46 -0800591 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800592 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
593 "device/vendor/blah/overlay/bar/res/values/strings.xml",
594 },
Colin Crossbec85302019-02-13 13:15:46 -0800595 "lib": {
596 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
597 "lib/res/res/values/strings.xml",
598 "device/vendor/blah/overlay/lib/res/values/strings.xml",
599 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800600 },
Colin Crossc1c37552019-01-31 11:42:41 -0800601
Colin Cross5c4791c2019-02-01 11:44:44 -0800602 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800603 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000604 "device:device/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800605 // Enforce RRO on "foo" could imply RRO on static dependencies, but for now it doesn't.
606 // "device/vendor/blah/overlay/lib/res",
Anton Hansson53c88442019-03-18 15:53:16 +0000607 "product:product/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800608 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800609 "bar": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800610 "lib": nil,
Colin Cross5c4791c2019-02-01 11:44:44 -0800611 },
612 },
613 {
614 name: "enforce RRO on all",
615 enforceRROTargets: []string{"*"},
616 enforceRROExcludedOverlays: []string{
617 // Excluding specific apps/res directories also allowed.
618 "device/vendor/blah/static_overlay/foo",
619 "device/vendor/blah/static_overlay/bar/res",
620 },
Colin Crossbec85302019-02-13 13:15:46 -0800621 resourceFiles: map[string][]string{
622 "foo": nil,
623 "bar": {"bar/res/res/values/strings.xml"},
624 "lib": nil,
625 "lib2": {"lib2/res/res/values/strings.xml"},
626 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800627 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800628 "foo": {
629 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800630 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000631 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800632 "foo/res/res/values/strings.xml",
633 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
634 },
Colin Crossbec85302019-02-13 13:15:46 -0800635 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
636 "lib": {
637 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
638 "lib/res/res/values/strings.xml",
639 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800640 },
641 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800642 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000643 "device:device/vendor/blah/overlay/foo/res",
644 "product:product/vendor/blah/overlay/foo/res",
645 // Lib dep comes after the direct deps
646 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800647 },
Anton Hansson53c88442019-03-18 15:53:16 +0000648 "bar": {"device:device/vendor/blah/overlay/bar/res"},
649 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800650 },
651 },
652 }
653
Anton Hansson53c88442019-03-18 15:53:16 +0000654 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -0800655 "device/vendor/blah/overlay",
656 "device/vendor/blah/overlay2",
657 "device/vendor/blah/static_overlay",
658 }
659
Anton Hansson53c88442019-03-18 15:53:16 +0000660 productResourceOverlays := []string{
661 "product/vendor/blah/overlay",
662 }
663
Colin Cross890ff552017-11-30 20:13:19 -0800664 fs := map[string][]byte{
665 "foo/res/res/values/strings.xml": nil,
666 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800667 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800668 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800669 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
670 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800671 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800672 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
673 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
674 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +0000675 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800676 }
677
678 bp := `
679 android_app {
680 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900681 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800682 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +0000683 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -0800684 }
685
686 android_app {
687 name: "bar",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900688 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800689 resource_dirs: ["bar/res"],
690 }
Colin Cross6ed7dea2019-01-31 14:44:30 -0800691
692 android_library {
693 name: "lib",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900694 sdk_version: "current",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800695 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -0800696 static_libs: ["lib2"],
697 }
698
699 android_library {
700 name: "lib2",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900701 sdk_version: "current",
Colin Crossbec85302019-02-13 13:15:46 -0800702 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -0800703 }
Anton Hansson53c88442019-03-18 15:53:16 +0000704
705 // This library has the same resources as lib (should not lead to dupe RROs)
706 android_library {
707 name: "lib3",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900708 sdk_version: "current",
Anton Hansson53c88442019-03-18 15:53:16 +0000709 resource_dirs: ["lib/res"]
710 }
Colin Cross890ff552017-11-30 20:13:19 -0800711 `
712
Colin Cross5c4791c2019-02-01 11:44:44 -0800713 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -0800714 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800715 config := testAppConfig(nil, bp, fs)
Anton Hansson53c88442019-03-18 15:53:16 +0000716 config.TestProductVariables.DeviceResourceOverlays = deviceResourceOverlays
717 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800718 if testCase.enforceRROTargets != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800719 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800720 }
721 if testCase.enforceRROExcludedOverlays != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800722 config.TestProductVariables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800723 }
724
Colin Cross98be1bb2019-12-13 20:41:13 -0800725 ctx := testContext()
Colin Cross890ff552017-11-30 20:13:19 -0800726 run(t, ctx, config)
727
Colin Crossbec85302019-02-13 13:15:46 -0800728 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
729 for _, o := range list {
730 res := module.MaybeOutput(o)
731 if res.Rule != nil {
732 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
733 // verify the inputs to the .arsc.flat rule.
734 files = append(files, res.Inputs.Strings()...)
735 } else {
736 // Otherwise, verify the full path to the output of the other module
737 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +0000738 }
Colin Cross890ff552017-11-30 20:13:19 -0800739 }
Colin Crossbec85302019-02-13 13:15:46 -0800740 return files
Colin Cross890ff552017-11-30 20:13:19 -0800741 }
742
Colin Crossbec85302019-02-13 13:15:46 -0800743 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
744 module := ctx.ModuleForTests(moduleName, "android_common")
745 resourceList := module.MaybeOutput("aapt2/res.list")
746 if resourceList.Rule != nil {
747 resourceFiles = resourceListToFiles(module, resourceList.Inputs.Strings())
Anton Hansson0375a4f2019-01-24 14:39:19 +0000748 }
Colin Crossbec85302019-02-13 13:15:46 -0800749 overlayList := module.MaybeOutput("aapt2/overlay.list")
750 if overlayList.Rule != nil {
751 overlayFiles = resourceListToFiles(module, overlayList.Inputs.Strings())
752 }
753
Anton Hansson53c88442019-03-18 15:53:16 +0000754 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
755 var prefix string
756 if d.overlayType == device {
757 prefix = "device:"
758 } else if d.overlayType == product {
759 prefix = "product:"
760 } else {
761 t.Fatalf("Unexpected overlayType %d", d.overlayType)
762 }
763 rroDirs = append(rroDirs, prefix+d.path.String())
764 }
Colin Crossbec85302019-02-13 13:15:46 -0800765
766 return resourceFiles, overlayFiles, rroDirs
767 }
768
769 modules := []string{"foo", "bar", "lib", "lib2"}
770 for _, module := range modules {
771 resourceFiles, overlayFiles, rroDirs := getResources(module)
772
773 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
774 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
775 module, testCase.resourceFiles[module], resourceFiles)
776 }
777 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
778 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
779 module, testCase.overlayFiles[module], overlayFiles)
780 }
781 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +0000782 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossbec85302019-02-13 13:15:46 -0800783 module, testCase.rroDirs[module], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +0000784 }
Colin Cross890ff552017-11-30 20:13:19 -0800785 }
Colin Cross890ff552017-11-30 20:13:19 -0800786 })
787 }
788}
Colin Crossd09b0b62018-04-18 11:06:47 -0700789
790func TestAppSdkVersion(t *testing.T) {
791 testCases := []struct {
792 name string
793 sdkVersion string
794 platformSdkInt int
795 platformSdkCodename string
796 platformSdkFinal bool
797 expectedMinSdkVersion string
Jeongik Cha538c0d02019-07-11 15:54:27 +0900798 platformApis bool
Colin Crossd09b0b62018-04-18 11:06:47 -0700799 }{
800 {
801 name: "current final SDK",
802 sdkVersion: "current",
803 platformSdkInt: 27,
804 platformSdkCodename: "REL",
805 platformSdkFinal: true,
806 expectedMinSdkVersion: "27",
807 },
808 {
809 name: "current non-final SDK",
810 sdkVersion: "current",
811 platformSdkInt: 27,
812 platformSdkCodename: "OMR1",
813 platformSdkFinal: false,
814 expectedMinSdkVersion: "OMR1",
815 },
816 {
817 name: "default final SDK",
818 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900819 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -0700820 platformSdkInt: 27,
821 platformSdkCodename: "REL",
822 platformSdkFinal: true,
823 expectedMinSdkVersion: "27",
824 },
825 {
826 name: "default non-final SDK",
827 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900828 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -0700829 platformSdkInt: 27,
830 platformSdkCodename: "OMR1",
831 platformSdkFinal: false,
832 expectedMinSdkVersion: "OMR1",
833 },
834 {
835 name: "14",
836 sdkVersion: "14",
837 expectedMinSdkVersion: "14",
838 },
839 }
840
841 for _, moduleType := range []string{"android_app", "android_library"} {
842 for _, test := range testCases {
843 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Jeongik Cha538c0d02019-07-11 15:54:27 +0900844 platformApiProp := ""
845 if test.platformApis {
846 platformApiProp = "platform_apis: true,"
847 }
Colin Crossd09b0b62018-04-18 11:06:47 -0700848 bp := fmt.Sprintf(`%s {
849 name: "foo",
850 srcs: ["a.java"],
851 sdk_version: "%s",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900852 %s
853 }`, moduleType, test.sdkVersion, platformApiProp)
Colin Crossd09b0b62018-04-18 11:06:47 -0700854
Colin Cross98be1bb2019-12-13 20:41:13 -0800855 config := testAppConfig(nil, bp, nil)
Colin Crossd09b0b62018-04-18 11:06:47 -0700856 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
857 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
858 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
859
Colin Cross98be1bb2019-12-13 20:41:13 -0800860 ctx := testContext()
Colin Crossd09b0b62018-04-18 11:06:47 -0700861
862 run(t, ctx, config)
863
864 foo := ctx.ModuleForTests("foo", "android_common")
865 link := foo.Output("package-res.apk")
866 linkFlags := strings.Split(link.Args["flags"], " ")
867 min := android.IndexList("--min-sdk-version", linkFlags)
868 target := android.IndexList("--target-sdk-version", linkFlags)
869
870 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
871 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
872 }
873
874 gotMinSdkVersion := linkFlags[min+1]
875 gotTargetSdkVersion := linkFlags[target+1]
876
877 if gotMinSdkVersion != test.expectedMinSdkVersion {
878 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
879 test.expectedMinSdkVersion, gotMinSdkVersion)
880 }
881
882 if gotTargetSdkVersion != test.expectedMinSdkVersion {
883 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
884 test.expectedMinSdkVersion, gotTargetSdkVersion)
885 }
886 })
887 }
888 }
889}
Colin Crossa4f08812018-10-02 22:03:40 -0700890
Paul Duffin50c217c2019-06-12 13:25:22 +0100891func TestJNIABI(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -0700892 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +0100893 cc_library {
894 name: "libjni",
895 system_shared_libs: [],
896 stl: "none",
897 }
898
899 android_test {
900 name: "test",
901 sdk_version: "core_platform",
902 jni_libs: ["libjni"],
903 }
904
905 android_test {
906 name: "test_first",
907 sdk_version: "core_platform",
908 compile_multilib: "first",
909 jni_libs: ["libjni"],
910 }
911
912 android_test {
913 name: "test_both",
914 sdk_version: "core_platform",
915 compile_multilib: "both",
916 jni_libs: ["libjni"],
917 }
918
919 android_test {
920 name: "test_32",
921 sdk_version: "core_platform",
922 compile_multilib: "32",
923 jni_libs: ["libjni"],
924 }
925
926 android_test {
927 name: "test_64",
928 sdk_version: "core_platform",
929 compile_multilib: "64",
930 jni_libs: ["libjni"],
931 }
932 `)
933
934 testCases := []struct {
935 name string
936 abis []string
937 }{
938 {"test", []string{"arm64-v8a"}},
939 {"test_first", []string{"arm64-v8a"}},
940 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
941 {"test_32", []string{"armeabi-v7a"}},
942 {"test_64", []string{"arm64-v8a"}},
943 }
944
945 for _, test := range testCases {
946 t.Run(test.name, func(t *testing.T) {
947 app := ctx.ModuleForTests(test.name, "android_common")
948 jniLibZip := app.Output("jnilibs.zip")
949 var abis []string
950 args := strings.Fields(jniLibZip.Args["jarArgs"])
951 for i := 0; i < len(args); i++ {
952 if args[i] == "-P" {
953 abis = append(abis, filepath.Base(args[i+1]))
954 i++
955 }
956 }
957 if !reflect.DeepEqual(abis, test.abis) {
958 t.Errorf("want abis %v, got %v", test.abis, abis)
959 }
960 })
961 }
962}
963
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900964func TestAppSdkVersionByPartition(t *testing.T) {
965 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
966 android_app {
967 name: "foo",
968 srcs: ["a.java"],
969 vendor: true,
970 platform_apis: true,
971 }
972 `)
973
974 testJava(t, `
975 android_app {
976 name: "bar",
977 srcs: ["b.java"],
978 platform_apis: true,
979 }
980 `)
981
982 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900983 bp := `
984 android_app {
985 name: "foo",
986 srcs: ["a.java"],
987 product_specific: true,
988 platform_apis: true,
989 }
990 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800991
992 config := testAppConfig(nil, bp, nil)
993 config.TestProductVariables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900994 if enforce {
Colin Cross98be1bb2019-12-13 20:41:13 -0800995 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 +0900996 } else {
Colin Cross98be1bb2019-12-13 20:41:13 -0800997 testJavaWithConfig(t, config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +0900998 }
999 }
1000}
1001
Paul Duffin50c217c2019-06-12 13:25:22 +01001002func TestJNIPackaging(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001003 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001004 cc_library {
1005 name: "libjni",
1006 system_shared_libs: [],
1007 stl: "none",
1008 }
1009
1010 android_app {
1011 name: "app",
1012 jni_libs: ["libjni"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001013 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001014 }
1015
1016 android_app {
1017 name: "app_noembed",
1018 jni_libs: ["libjni"],
1019 use_embedded_native_libs: false,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001020 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001021 }
1022
1023 android_app {
1024 name: "app_embed",
1025 jni_libs: ["libjni"],
1026 use_embedded_native_libs: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001027 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001028 }
1029
1030 android_test {
1031 name: "test",
1032 sdk_version: "core_platform",
1033 jni_libs: ["libjni"],
1034 }
1035
1036 android_test {
1037 name: "test_noembed",
1038 sdk_version: "core_platform",
1039 jni_libs: ["libjni"],
1040 use_embedded_native_libs: false,
1041 }
1042
1043 android_test_helper_app {
1044 name: "test_helper",
1045 sdk_version: "core_platform",
1046 jni_libs: ["libjni"],
1047 }
1048
1049 android_test_helper_app {
1050 name: "test_helper_noembed",
1051 sdk_version: "core_platform",
1052 jni_libs: ["libjni"],
1053 use_embedded_native_libs: false,
1054 }
1055 `)
1056
1057 testCases := []struct {
1058 name string
1059 packaged bool
1060 compressed bool
1061 }{
1062 {"app", false, false},
1063 {"app_noembed", false, false},
1064 {"app_embed", true, false},
1065 {"test", true, false},
1066 {"test_noembed", true, true},
1067 {"test_helper", true, false},
1068 {"test_helper_noembed", true, true},
1069 }
1070
1071 for _, test := range testCases {
1072 t.Run(test.name, func(t *testing.T) {
1073 app := ctx.ModuleForTests(test.name, "android_common")
1074 jniLibZip := app.MaybeOutput("jnilibs.zip")
1075 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
1076 t.Errorf("expected jni packaged %v, got %v", w, g)
1077 }
1078
1079 if jniLibZip.Rule != nil {
1080 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
1081 t.Errorf("expected jni compressed %v, got %v", w, g)
1082 }
1083 }
1084 })
1085 }
Colin Cross47fa9d32019-03-26 10:51:39 -07001086}
1087
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001088func TestCertificates(t *testing.T) {
1089 testCases := []struct {
1090 name string
1091 bp string
1092 certificateOverride string
1093 expected string
1094 }{
1095 {
1096 name: "default",
1097 bp: `
1098 android_app {
1099 name: "foo",
1100 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001101 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001102 }
1103 `,
1104 certificateOverride: "",
Dan Willemsen412160e2019-04-09 21:36:26 -07001105 expected: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001106 },
1107 {
1108 name: "module certificate property",
1109 bp: `
1110 android_app {
1111 name: "foo",
1112 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001113 certificate: ":new_certificate",
1114 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001115 }
1116
1117 android_app_certificate {
1118 name: "new_certificate",
1119 certificate: "cert/new_cert",
1120 }
1121 `,
1122 certificateOverride: "",
1123 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
1124 },
1125 {
1126 name: "path certificate property",
1127 bp: `
1128 android_app {
1129 name: "foo",
1130 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001131 certificate: "expiredkey",
1132 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001133 }
1134 `,
1135 certificateOverride: "",
Dan Willemsen412160e2019-04-09 21:36:26 -07001136 expected: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001137 },
1138 {
1139 name: "certificate overrides",
1140 bp: `
1141 android_app {
1142 name: "foo",
1143 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001144 certificate: "expiredkey",
1145 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001146 }
1147
1148 android_app_certificate {
1149 name: "new_certificate",
1150 certificate: "cert/new_cert",
1151 }
1152 `,
1153 certificateOverride: "foo:new_certificate",
1154 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
1155 },
1156 }
1157
1158 for _, test := range testCases {
1159 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001160 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001161 if test.certificateOverride != "" {
1162 config.TestProductVariables.CertificateOverrides = []string{test.certificateOverride}
1163 }
Colin Cross98be1bb2019-12-13 20:41:13 -08001164 ctx := testContext()
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001165
1166 run(t, ctx, config)
1167 foo := ctx.ModuleForTests("foo", "android_common")
1168
1169 signapk := foo.Output("foo.apk")
1170 signFlags := signapk.Args["certificates"]
1171 if test.expected != signFlags {
1172 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
1173 }
1174 })
1175 }
1176}
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001177
Songchun Fan688de9a2020-03-24 20:32:24 -07001178func TestRequestV4SigningFlag(t *testing.T) {
1179 testCases := []struct {
1180 name string
1181 bp string
1182 expected string
1183 }{
1184 {
1185 name: "default",
1186 bp: `
1187 android_app {
1188 name: "foo",
1189 srcs: ["a.java"],
1190 sdk_version: "current",
1191 }
1192 `,
1193 expected: "",
1194 },
1195 {
1196 name: "default",
1197 bp: `
1198 android_app {
1199 name: "foo",
1200 srcs: ["a.java"],
1201 sdk_version: "current",
1202 v4_signature: false,
1203 }
1204 `,
1205 expected: "",
1206 },
1207 {
1208 name: "module certificate property",
1209 bp: `
1210 android_app {
1211 name: "foo",
1212 srcs: ["a.java"],
1213 sdk_version: "current",
1214 v4_signature: true,
1215 }
1216 `,
1217 expected: "--enable-v4",
1218 },
1219 }
1220
1221 for _, test := range testCases {
1222 t.Run(test.name, func(t *testing.T) {
1223 config := testAppConfig(nil, test.bp, nil)
1224 ctx := testContext()
1225
1226 run(t, ctx, config)
1227 foo := ctx.ModuleForTests("foo", "android_common")
1228
1229 signapk := foo.Output("foo.apk")
1230 signFlags := signapk.Args["flags"]
1231 if test.expected != signFlags {
1232 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
1233 }
1234 })
1235 }
1236}
1237
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001238func TestPackageNameOverride(t *testing.T) {
1239 testCases := []struct {
1240 name string
1241 bp string
1242 packageNameOverride string
1243 expected []string
1244 }{
1245 {
1246 name: "default",
1247 bp: `
1248 android_app {
1249 name: "foo",
1250 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001251 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001252 }
1253 `,
1254 packageNameOverride: "",
1255 expected: []string{
1256 buildDir + "/.intermediates/foo/android_common/foo.apk",
1257 buildDir + "/target/product/test_device/system/app/foo/foo.apk",
1258 },
1259 },
1260 {
1261 name: "overridden",
1262 bp: `
1263 android_app {
1264 name: "foo",
1265 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001266 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001267 }
1268 `,
1269 packageNameOverride: "foo:bar",
1270 expected: []string{
1271 // The package apk should be still be the original name for test dependencies.
Jaewoong Jung5a498812019-11-07 14:14:38 -08001272 buildDir + "/.intermediates/foo/android_common/bar.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001273 buildDir + "/target/product/test_device/system/app/bar/bar.apk",
1274 },
1275 },
1276 }
1277
1278 for _, test := range testCases {
1279 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001280 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001281 if test.packageNameOverride != "" {
1282 config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
1283 }
Colin Cross98be1bb2019-12-13 20:41:13 -08001284 ctx := testContext()
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001285
1286 run(t, ctx, config)
1287 foo := ctx.ModuleForTests("foo", "android_common")
1288
1289 outputs := foo.AllOutputs()
1290 outputMap := make(map[string]bool)
1291 for _, o := range outputs {
1292 outputMap[o] = true
1293 }
1294 for _, e := range test.expected {
1295 if _, exist := outputMap[e]; !exist {
1296 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
1297 }
1298 }
1299 })
1300 }
1301}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001302
1303func TestInstrumentationTargetOverridden(t *testing.T) {
1304 bp := `
1305 android_app {
1306 name: "foo",
1307 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001308 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001309 }
1310
1311 android_test {
1312 name: "bar",
1313 instrumentation_for: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001314 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001315 }
1316 `
Colin Cross98be1bb2019-12-13 20:41:13 -08001317 config := testAppConfig(nil, bp, nil)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001318 config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
Colin Cross98be1bb2019-12-13 20:41:13 -08001319 ctx := testContext()
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001320
1321 run(t, ctx, config)
1322
1323 bar := ctx.ModuleForTests("bar", "android_common")
1324 res := bar.Output("package-res.apk")
1325 aapt2Flags := res.Args["flags"]
1326 e := "--rename-instrumentation-target-package org.dandroid.bp"
1327 if !strings.Contains(aapt2Flags, e) {
1328 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
1329 }
1330}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001331
1332func TestOverrideAndroidApp(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001333 ctx, _ := testJava(t, `
Jaewoong Jung525443a2019-02-28 15:35:54 -08001334 android_app {
1335 name: "foo",
1336 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -07001337 certificate: "expiredkey",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001338 overrides: ["qux"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001339 sdk_version: "current",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001340 }
1341
1342 override_android_app {
1343 name: "bar",
1344 base: "foo",
1345 certificate: ":new_certificate",
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001346 logging_parent: "bah",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001347 }
1348
1349 android_app_certificate {
1350 name: "new_certificate",
1351 certificate: "cert/new_cert",
1352 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001353
1354 override_android_app {
1355 name: "baz",
1356 base: "foo",
1357 package_name: "org.dandroid.bp",
1358 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001359 `)
1360
1361 expectedVariants := []struct {
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001362 moduleName string
1363 variantName string
1364 apkName string
1365 apkPath string
1366 signFlag string
1367 overrides []string
1368 aaptFlag string
1369 logging_parent string
Jaewoong Jung525443a2019-02-28 15:35:54 -08001370 }{
1371 {
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001372 moduleName: "foo",
1373 variantName: "android_common",
1374 apkPath: "/target/product/test_device/system/app/foo/foo.apk",
1375 signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1376 overrides: []string{"qux"},
1377 aaptFlag: "",
1378 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001379 },
1380 {
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001381 moduleName: "bar",
1382 variantName: "android_common_bar",
1383 apkPath: "/target/product/test_device/system/app/bar/bar.apk",
1384 signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
1385 overrides: []string{"qux", "foo"},
1386 aaptFlag: "",
1387 logging_parent: "bah",
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001388 },
1389 {
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001390 moduleName: "baz",
1391 variantName: "android_common_baz",
1392 apkPath: "/target/product/test_device/system/app/baz/baz.apk",
1393 signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1394 overrides: []string{"qux", "foo"},
1395 aaptFlag: "--rename-manifest-package org.dandroid.bp",
1396 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001397 },
1398 }
1399 for _, expected := range expectedVariants {
1400 variant := ctx.ModuleForTests("foo", expected.variantName)
1401
1402 // Check the final apk name
1403 outputs := variant.AllOutputs()
1404 expectedApkPath := buildDir + expected.apkPath
1405 found := false
1406 for _, o := range outputs {
1407 if o == expectedApkPath {
1408 found = true
1409 break
1410 }
1411 }
1412 if !found {
1413 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
1414 }
1415
1416 // Check the certificate paths
Jaewoong Jung5a498812019-11-07 14:14:38 -08001417 signapk := variant.Output(expected.moduleName + ".apk")
Jaewoong Jung525443a2019-02-28 15:35:54 -08001418 signFlag := signapk.Args["certificates"]
1419 if expected.signFlag != signFlag {
1420 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.signFlag, signFlag)
1421 }
1422
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001423 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -08001424 mod := variant.Module().(*AndroidApp)
1425 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
1426 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
1427 expected.overrides, mod.appProperties.Overrides)
1428 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001429
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001430 // Test Overridable property: Logging_parent
1431 logging_parent := mod.aapt.LoggingParent
1432 if expected.logging_parent != logging_parent {
1433 t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q",
1434 expected.logging_parent, logging_parent)
1435 }
1436
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001437 // Check the package renaming flag, if exists.
1438 res := variant.Output("package-res.apk")
1439 aapt2Flags := res.Args["flags"]
1440 if !strings.Contains(aapt2Flags, expected.aaptFlag) {
1441 t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", expected.aaptFlag, aapt2Flags)
1442 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001443 }
1444}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001445
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001446func TestOverrideAndroidAppDependency(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001447 ctx, _ := testJava(t, `
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001448 android_app {
1449 name: "foo",
1450 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001451 sdk_version: "current",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001452 }
1453
1454 override_android_app {
1455 name: "bar",
1456 base: "foo",
1457 package_name: "org.dandroid.bp",
1458 }
1459
1460 android_test {
1461 name: "baz",
1462 srcs: ["b.java"],
1463 instrumentation_for: "foo",
1464 }
1465
1466 android_test {
1467 name: "qux",
1468 srcs: ["b.java"],
1469 instrumentation_for: "bar",
1470 }
1471 `)
1472
1473 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
1474 javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
1475 fooTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
1476 if !strings.Contains(javac.Args["classpath"], fooTurbine) {
1477 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
1478 }
1479
1480 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
1481 javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
1482 barTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common_bar", "turbine-combined", "foo.jar")
1483 if !strings.Contains(javac.Args["classpath"], barTurbine) {
1484 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
1485 }
1486}
1487
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001488func TestOverrideAndroidTest(t *testing.T) {
1489 ctx, _ := testJava(t, `
1490 android_app {
1491 name: "foo",
1492 srcs: ["a.java"],
1493 package_name: "com.android.foo",
1494 sdk_version: "current",
1495 }
1496
1497 override_android_app {
1498 name: "bar",
1499 base: "foo",
1500 package_name: "com.android.bar",
1501 }
1502
1503 android_test {
1504 name: "foo_test",
1505 srcs: ["b.java"],
1506 instrumentation_for: "foo",
1507 }
1508
1509 override_android_test {
1510 name: "bar_test",
1511 base: "foo_test",
1512 package_name: "com.android.bar.test",
1513 instrumentation_for: "bar",
1514 instrumentation_target_package: "com.android.bar",
1515 }
1516 `)
1517
1518 expectedVariants := []struct {
1519 moduleName string
1520 variantName string
1521 apkPath string
1522 overrides []string
1523 targetVariant string
1524 packageFlag string
1525 targetPackageFlag string
1526 }{
1527 {
1528 variantName: "android_common",
Jaewoong Jung326a9412019-11-21 10:41:00 -08001529 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001530 overrides: nil,
1531 targetVariant: "android_common",
1532 packageFlag: "",
1533 targetPackageFlag: "",
1534 },
1535 {
1536 variantName: "android_common_bar_test",
Jaewoong Jung326a9412019-11-21 10:41:00 -08001537 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001538 overrides: []string{"foo_test"},
1539 targetVariant: "android_common_bar",
1540 packageFlag: "com.android.bar.test",
1541 targetPackageFlag: "com.android.bar",
1542 },
1543 }
1544 for _, expected := range expectedVariants {
1545 variant := ctx.ModuleForTests("foo_test", expected.variantName)
1546
1547 // Check the final apk name
1548 outputs := variant.AllOutputs()
1549 expectedApkPath := buildDir + expected.apkPath
1550 found := false
1551 for _, o := range outputs {
1552 if o == expectedApkPath {
1553 found = true
1554 break
1555 }
1556 }
1557 if !found {
1558 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
1559 }
1560
1561 // Check if the overrides field values are correctly aggregated.
1562 mod := variant.Module().(*AndroidTest)
1563 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
1564 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
1565 expected.overrides, mod.appProperties.Overrides)
1566 }
1567
1568 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
1569 javac := variant.Rule("javac")
1570 turbine := filepath.Join(buildDir, ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
1571 if !strings.Contains(javac.Args["classpath"], turbine) {
1572 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
1573 }
1574
1575 // Check aapt2 flags.
1576 res := variant.Output("package-res.apk")
1577 aapt2Flags := res.Args["flags"]
1578 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
1579 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
1580 }
1581}
1582
Jaewoong Jung39982342020-01-14 10:27:18 -08001583func TestAndroidTest_FixTestConfig(t *testing.T) {
1584 ctx, _ := testJava(t, `
1585 android_app {
1586 name: "foo",
1587 srcs: ["a.java"],
1588 package_name: "com.android.foo",
1589 sdk_version: "current",
1590 }
1591
1592 android_test {
1593 name: "foo_test",
1594 srcs: ["b.java"],
1595 instrumentation_for: "foo",
1596 }
1597
1598 android_test {
1599 name: "bar_test",
1600 srcs: ["b.java"],
1601 package_name: "com.android.bar.test",
1602 instrumentation_for: "foo",
1603 }
1604
1605 override_android_test {
1606 name: "baz_test",
1607 base: "foo_test",
1608 package_name: "com.android.baz.test",
1609 }
1610 `)
1611
1612 testCases := []struct {
1613 moduleName string
1614 variantName string
1615 expectedFlags []string
1616 }{
1617 {
1618 moduleName: "foo_test",
1619 variantName: "android_common",
1620 },
1621 {
1622 moduleName: "bar_test",
1623 variantName: "android_common",
1624 expectedFlags: []string{
1625 "--manifest " + buildDir + "/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
1626 "--package-name com.android.bar.test",
1627 },
1628 },
1629 {
1630 moduleName: "foo_test",
1631 variantName: "android_common_baz_test",
1632 expectedFlags: []string{
1633 "--manifest " + buildDir +
1634 "/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
1635 "--package-name com.android.baz.test",
1636 "--test-file-name baz_test.apk",
1637 },
1638 },
1639 }
1640
1641 for _, test := range testCases {
1642 variant := ctx.ModuleForTests(test.moduleName, test.variantName)
1643 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
1644
1645 if len(test.expectedFlags) > 0 {
1646 if params.Rule == nil {
1647 t.Errorf("test_config_fixer was expected to run, but didn't")
1648 } else {
1649 for _, flag := range test.expectedFlags {
1650 if !strings.Contains(params.RuleParams.Command, flag) {
1651 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
1652 }
1653 }
1654 }
1655 } else {
1656 if params.Rule != nil {
1657 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
1658 }
1659 }
1660
1661 }
1662}
1663
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001664func TestAndroidAppImport(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001665 ctx, _ := testJava(t, `
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001666 android_app_import {
1667 name: "foo",
1668 apk: "prebuilts/apk/app.apk",
1669 certificate: "platform",
1670 dex_preopt: {
1671 enabled: true,
1672 },
1673 }
1674 `)
1675
1676 variant := ctx.ModuleForTests("foo", "android_common")
1677
1678 // Check dexpreopt outputs.
1679 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
1680 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
1681 t.Errorf("can't find dexpreopt outputs")
1682 }
1683
1684 // Check cert signing flag.
1685 signedApk := variant.Output("signed/foo.apk")
1686 signingFlag := signedApk.Args["certificates"]
1687 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
1688 if expected != signingFlag {
1689 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
1690 }
1691}
1692
1693func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001694 ctx, _ := testJava(t, `
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001695 android_app_import {
1696 name: "foo",
1697 apk: "prebuilts/apk/app.apk",
1698 certificate: "platform",
1699 dex_preopt: {
1700 enabled: false,
1701 },
1702 }
1703 `)
1704
1705 variant := ctx.ModuleForTests("foo", "android_common")
1706
1707 // Check dexpreopt outputs. They shouldn't exist.
1708 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
1709 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
1710 t.Errorf("dexpreopt shouldn't have run.")
1711 }
1712}
1713
1714func TestAndroidAppImport_Presigned(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001715 ctx, _ := testJava(t, `
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001716 android_app_import {
1717 name: "foo",
1718 apk: "prebuilts/apk/app.apk",
1719 presigned: true,
1720 dex_preopt: {
1721 enabled: true,
1722 },
1723 }
1724 `)
1725
1726 variant := ctx.ModuleForTests("foo", "android_common")
1727
1728 // Check dexpreopt outputs.
1729 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
1730 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
1731 t.Errorf("can't find dexpreopt outputs")
1732 }
Nicolas Geoffrayc1bf7242019-10-18 14:51:38 +01001733 // Make sure signing was skipped and aligning was done.
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001734 if variant.MaybeOutput("signed/foo.apk").Rule != nil {
1735 t.Errorf("signing rule shouldn't be included.")
1736 }
1737 if variant.MaybeOutput("zip-aligned/foo.apk").Rule == nil {
1738 t.Errorf("can't find aligning rule")
1739 }
1740}
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07001741
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07001742func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
1743 ctx, _ := testJava(t, `
1744 android_app_import {
1745 name: "foo",
1746 apk: "prebuilts/apk/app.apk",
1747 default_dev_cert: true,
1748 dex_preopt: {
1749 enabled: true,
1750 },
1751 }
1752 `)
1753
1754 variant := ctx.ModuleForTests("foo", "android_common")
1755
1756 // Check dexpreopt outputs.
1757 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
1758 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
1759 t.Errorf("can't find dexpreopt outputs")
1760 }
1761
1762 // Check cert signing flag.
1763 signedApk := variant.Output("signed/foo.apk")
1764 signingFlag := signedApk.Args["certificates"]
1765 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
1766 if expected != signingFlag {
1767 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
1768 }
1769}
1770
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07001771func TestAndroidAppImport_DpiVariants(t *testing.T) {
1772 bp := `
1773 android_app_import {
1774 name: "foo",
1775 apk: "prebuilts/apk/app.apk",
1776 dpi_variants: {
1777 xhdpi: {
1778 apk: "prebuilts/apk/app_xhdpi.apk",
1779 },
1780 xxhdpi: {
1781 apk: "prebuilts/apk/app_xxhdpi.apk",
1782 },
1783 },
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07001784 presigned: true,
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07001785 dex_preopt: {
1786 enabled: true,
1787 },
1788 }
1789 `
1790 testCases := []struct {
1791 name string
1792 aaptPreferredConfig *string
1793 aaptPrebuiltDPI []string
1794 expected string
1795 }{
1796 {
1797 name: "no preferred",
1798 aaptPreferredConfig: nil,
1799 aaptPrebuiltDPI: []string{},
1800 expected: "prebuilts/apk/app.apk",
1801 },
1802 {
1803 name: "AAPTPreferredConfig matches",
1804 aaptPreferredConfig: proptools.StringPtr("xhdpi"),
Jaewoong Jung3e18b192019-06-11 12:25:34 -07001805 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07001806 expected: "prebuilts/apk/app_xhdpi.apk",
1807 },
1808 {
1809 name: "AAPTPrebuiltDPI matches",
1810 aaptPreferredConfig: proptools.StringPtr("mdpi"),
1811 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
1812 expected: "prebuilts/apk/app_xxhdpi.apk",
1813 },
1814 {
1815 name: "non-first AAPTPrebuiltDPI matches",
1816 aaptPreferredConfig: proptools.StringPtr("mdpi"),
1817 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
1818 expected: "prebuilts/apk/app_xhdpi.apk",
1819 },
1820 {
1821 name: "no matches",
1822 aaptPreferredConfig: proptools.StringPtr("mdpi"),
1823 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
1824 expected: "prebuilts/apk/app.apk",
1825 },
1826 }
1827
1828 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
1829 for _, test := range testCases {
Colin Cross98be1bb2019-12-13 20:41:13 -08001830 config := testAppConfig(nil, bp, nil)
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07001831 config.TestProductVariables.AAPTPreferredConfig = test.aaptPreferredConfig
1832 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
Colin Cross98be1bb2019-12-13 20:41:13 -08001833 ctx := testContext()
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07001834
1835 run(t, ctx, config)
1836
1837 variant := ctx.ModuleForTests("foo", "android_common")
1838 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
1839 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
1840 if len(matches) != 2 {
1841 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
1842 }
1843 if test.expected != matches[1] {
1844 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
1845 }
1846 }
1847}
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07001848
Jaewoong Jung8aae22e2019-07-17 10:21:49 -07001849func TestAndroidAppImport_Filename(t *testing.T) {
1850 ctx, config := testJava(t, `
1851 android_app_import {
1852 name: "foo",
1853 apk: "prebuilts/apk/app.apk",
1854 presigned: true,
1855 }
1856
1857 android_app_import {
1858 name: "bar",
1859 apk: "prebuilts/apk/app.apk",
1860 presigned: true,
1861 filename: "bar_sample.apk"
1862 }
1863 `)
1864
1865 testCases := []struct {
1866 name string
1867 expected string
1868 }{
1869 {
1870 name: "foo",
1871 expected: "foo.apk",
1872 },
1873 {
1874 name: "bar",
1875 expected: "bar_sample.apk",
1876 },
1877 }
1878
1879 for _, test := range testCases {
1880 variant := ctx.ModuleForTests(test.name, "android_common")
1881 if variant.MaybeOutput(test.expected).Rule == nil {
1882 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
1883 }
1884
1885 a := variant.Module().(*AndroidAppImport)
1886 expectedValues := []string{test.expected}
1887 actualValues := android.AndroidMkEntriesForTest(
Jiyong Park0b0e1b92019-12-03 13:24:29 +09001888 t, config, "", a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
Jaewoong Jung8aae22e2019-07-17 10:21:49 -07001889 if !reflect.DeepEqual(actualValues, expectedValues) {
1890 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
1891 actualValues, expectedValues)
1892 }
1893 }
1894}
1895
Jaewoong Jung1ce9ac62019-08-13 14:11:33 -07001896func TestAndroidAppImport_ArchVariants(t *testing.T) {
1897 // The test config's target arch is ARM64.
1898 testCases := []struct {
1899 name string
1900 bp string
1901 expected string
1902 }{
1903 {
1904 name: "matching arch",
1905 bp: `
1906 android_app_import {
1907 name: "foo",
1908 apk: "prebuilts/apk/app.apk",
1909 arch: {
1910 arm64: {
1911 apk: "prebuilts/apk/app_arm64.apk",
1912 },
1913 },
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07001914 presigned: true,
Jaewoong Jung1ce9ac62019-08-13 14:11:33 -07001915 dex_preopt: {
1916 enabled: true,
1917 },
1918 }
1919 `,
1920 expected: "prebuilts/apk/app_arm64.apk",
1921 },
1922 {
1923 name: "no matching arch",
1924 bp: `
1925 android_app_import {
1926 name: "foo",
1927 apk: "prebuilts/apk/app.apk",
1928 arch: {
1929 arm: {
1930 apk: "prebuilts/apk/app_arm.apk",
1931 },
1932 },
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07001933 presigned: true,
Jaewoong Jung1ce9ac62019-08-13 14:11:33 -07001934 dex_preopt: {
1935 enabled: true,
1936 },
1937 }
1938 `,
1939 expected: "prebuilts/apk/app.apk",
1940 },
1941 }
1942
1943 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
1944 for _, test := range testCases {
1945 ctx, _ := testJava(t, test.bp)
1946
1947 variant := ctx.ModuleForTests("foo", "android_common")
1948 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
1949 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
1950 if len(matches) != 2 {
1951 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
1952 }
1953 if test.expected != matches[1] {
1954 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
1955 }
1956 }
1957}
1958
Jaewoong Jungb28eb5f2019-08-27 15:01:50 -07001959func TestAndroidTestImport(t *testing.T) {
1960 ctx, config := testJava(t, `
1961 android_test_import {
1962 name: "foo",
1963 apk: "prebuilts/apk/app.apk",
1964 presigned: true,
1965 data: [
1966 "testdata/data",
1967 ],
1968 }
1969 `)
1970
1971 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
1972
1973 // Check android mks.
Jiyong Park0b0e1b92019-12-03 13:24:29 +09001974 entries := android.AndroidMkEntriesForTest(t, config, "", test)[0]
Jaewoong Jungb28eb5f2019-08-27 15:01:50 -07001975 expected := []string{"tests"}
1976 actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
1977 if !reflect.DeepEqual(expected, actual) {
1978 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
1979 }
1980 expected = []string{"testdata/data:testdata/data"}
1981 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
1982 if !reflect.DeepEqual(expected, actual) {
1983 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
1984 }
1985}
1986
Jaewoong Jung7c5bd832020-01-13 09:55:39 -08001987func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
1988 ctx, _ := testJava(t, `
1989 android_test_import {
1990 name: "foo",
1991 apk: "prebuilts/apk/app.apk",
1992 certificate: "cert/new_cert",
1993 data: [
1994 "testdata/data",
1995 ],
1996 }
1997
1998 android_test_import {
1999 name: "foo_presigned",
2000 apk: "prebuilts/apk/app.apk",
2001 presigned: true,
2002 data: [
2003 "testdata/data",
2004 ],
2005 }
2006 `)
2007
2008 variant := ctx.ModuleForTests("foo", "android_common")
2009 jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
2010 if !strings.HasPrefix(jniRule, "if (zipinfo") {
2011 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
2012 }
2013
2014 variant = ctx.ModuleForTests("foo_presigned", "android_common")
2015 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
2016 if jniRule != android.Cp.String() {
2017 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
2018 }
2019}
2020
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002021func TestStl(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002022 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002023 cc_library {
2024 name: "libjni",
Peter Collingbournead84f972019-12-17 16:46:18 -08002025 sdk_version: "current",
2026 stl: "c++_shared",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002027 }
2028
2029 android_test {
2030 name: "stl",
2031 jni_libs: ["libjni"],
2032 compile_multilib: "both",
2033 sdk_version: "current",
2034 stl: "c++_shared",
2035 }
2036
2037 android_test {
2038 name: "system",
2039 jni_libs: ["libjni"],
2040 compile_multilib: "both",
2041 sdk_version: "current",
2042 }
2043 `)
2044
2045 testCases := []struct {
2046 name string
2047 jnis []string
2048 }{
2049 {"stl",
2050 []string{
2051 "libjni.so",
Jaewoong Jung710756a2019-06-04 11:53:47 -07002052 "libc++_shared.so",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002053 },
2054 },
2055 {"system",
2056 []string{
2057 "libjni.so",
2058 },
2059 },
2060 }
2061
2062 for _, test := range testCases {
2063 t.Run(test.name, func(t *testing.T) {
2064 app := ctx.ModuleForTests(test.name, "android_common")
2065 jniLibZip := app.Output("jnilibs.zip")
2066 var jnis []string
2067 args := strings.Fields(jniLibZip.Args["jarArgs"])
2068 for i := 0; i < len(args); i++ {
2069 if args[i] == "-f" {
2070 jnis = append(jnis, args[i+1])
2071 i += 1
2072 }
2073 }
2074 jnisJoined := strings.Join(jnis, " ")
2075 for _, jni := range test.jnis {
2076 if !strings.Contains(jnisJoined, jni) {
2077 t.Errorf("missing jni %q in %q", jni, jnis)
2078 }
2079 }
2080 })
2081 }
2082}
Colin Cross50ddcc42019-05-16 12:28:22 -07002083
2084func TestUsesLibraries(t *testing.T) {
2085 bp := `
2086 java_sdk_library {
2087 name: "foo",
2088 srcs: ["a.java"],
2089 api_packages: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002090 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002091 }
2092
2093 java_sdk_library {
2094 name: "bar",
2095 srcs: ["a.java"],
2096 api_packages: ["bar"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002097 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002098 }
2099
2100 android_app {
2101 name: "app",
2102 srcs: ["a.java"],
2103 uses_libs: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002104 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002105 optional_uses_libs: [
2106 "bar",
2107 "baz",
2108 ],
2109 }
2110
2111 android_app_import {
2112 name: "prebuilt",
2113 apk: "prebuilts/apk/app.apk",
2114 certificate: "platform",
2115 uses_libs: ["foo"],
2116 optional_uses_libs: [
2117 "bar",
2118 "baz",
2119 ],
2120 }
2121 `
2122
Colin Cross98be1bb2019-12-13 20:41:13 -08002123 config := testAppConfig(nil, bp, nil)
Colin Cross50ddcc42019-05-16 12:28:22 -07002124 config.TestProductVariables.MissingUsesLibraries = []string{"baz"}
2125
Colin Cross98be1bb2019-12-13 20:41:13 -08002126 ctx := testContext()
Colin Cross50ddcc42019-05-16 12:28:22 -07002127
2128 run(t, ctx, config)
2129
2130 app := ctx.ModuleForTests("app", "android_common")
2131 prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
2132
2133 // Test that all libraries are verified
2134 cmd := app.Rule("verify_uses_libraries").RuleParams.Command
2135 if w := "--uses-library foo"; !strings.Contains(cmd, w) {
2136 t.Errorf("wanted %q in %q", w, cmd)
2137 }
2138
2139 if w := "--optional-uses-library bar --optional-uses-library baz"; !strings.Contains(cmd, w) {
2140 t.Errorf("wanted %q in %q", w, cmd)
2141 }
2142
2143 cmd = prebuilt.Rule("verify_uses_libraries").RuleParams.Command
2144
2145 if w := `uses_library_names="foo"`; !strings.Contains(cmd, w) {
2146 t.Errorf("wanted %q in %q", w, cmd)
2147 }
2148
2149 if w := `optional_uses_library_names="bar baz"`; !strings.Contains(cmd, w) {
2150 t.Errorf("wanted %q in %q", w, cmd)
2151 }
2152
2153 // Test that only present libraries are preopted
2154 cmd = app.Rule("dexpreopt").RuleParams.Command
2155
2156 if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
2157 t.Errorf("wanted %q in %q", w, cmd)
2158 }
2159
2160 cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
2161
2162 if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
2163 t.Errorf("wanted %q in %q", w, cmd)
2164 }
2165}
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002166
2167func TestCodelessApp(t *testing.T) {
2168 testCases := []struct {
2169 name string
2170 bp string
2171 noCode bool
2172 }{
2173 {
2174 name: "normal",
2175 bp: `
2176 android_app {
2177 name: "foo",
2178 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002179 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002180 }
2181 `,
2182 noCode: false,
2183 },
2184 {
2185 name: "app without sources",
2186 bp: `
2187 android_app {
2188 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002189 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002190 }
2191 `,
2192 noCode: true,
2193 },
2194 {
2195 name: "app with libraries",
2196 bp: `
2197 android_app {
2198 name: "foo",
2199 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002200 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002201 }
2202
2203 java_library {
2204 name: "lib",
2205 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002206 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002207 }
2208 `,
2209 noCode: false,
2210 },
2211 {
2212 name: "app with sourceless libraries",
2213 bp: `
2214 android_app {
2215 name: "foo",
2216 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002217 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002218 }
2219
2220 java_library {
2221 name: "lib",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002222 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002223 }
2224 `,
2225 // TODO(jungjw): this should probably be true
2226 noCode: false,
2227 },
2228 }
2229
2230 for _, test := range testCases {
2231 t.Run(test.name, func(t *testing.T) {
2232 ctx := testApp(t, test.bp)
2233
2234 foo := ctx.ModuleForTests("foo", "android_common")
2235 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
2236 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
2237 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
2238 }
2239 })
2240 }
2241}
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002242
2243func TestEmbedNotice(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002244 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002245 android_app {
2246 name: "foo",
2247 srcs: ["a.java"],
2248 static_libs: ["javalib"],
2249 jni_libs: ["libjni"],
2250 notice: "APP_NOTICE",
2251 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002252 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002253 }
2254
2255 // No embed_notice flag
2256 android_app {
2257 name: "bar",
2258 srcs: ["a.java"],
2259 jni_libs: ["libjni"],
2260 notice: "APP_NOTICE",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002261 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002262 }
2263
2264 // No NOTICE files
2265 android_app {
2266 name: "baz",
2267 srcs: ["a.java"],
2268 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002269 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002270 }
2271
2272 cc_library {
2273 name: "libjni",
2274 system_shared_libs: [],
2275 stl: "none",
2276 notice: "LIB_NOTICE",
2277 }
2278
2279 java_library {
2280 name: "javalib",
2281 srcs: [
2282 ":gen",
2283 ],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002284 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002285 }
2286
2287 genrule {
2288 name: "gen",
2289 tools: ["gentool"],
2290 out: ["gen.java"],
2291 notice: "GENRULE_NOTICE",
2292 }
2293
2294 java_binary_host {
2295 name: "gentool",
2296 srcs: ["b.java"],
2297 notice: "TOOL_NOTICE",
2298 }
2299 `)
2300
2301 // foo has NOTICE files to process, and embed_notices is true.
2302 foo := ctx.ModuleForTests("foo", "android_common")
2303 // verify merge notices rule.
2304 mergeNotices := foo.Rule("mergeNoticesRule")
2305 noticeInputs := mergeNotices.Inputs.Strings()
2306 // TOOL_NOTICE should be excluded as it's a host module.
2307 if len(mergeNotices.Inputs) != 3 {
2308 t.Errorf("number of input notice files: expected = 3, actual = %q", noticeInputs)
2309 }
2310 if !inList("APP_NOTICE", noticeInputs) {
2311 t.Errorf("APP_NOTICE is missing from notice files, %q", noticeInputs)
2312 }
2313 if !inList("LIB_NOTICE", noticeInputs) {
2314 t.Errorf("LIB_NOTICE is missing from notice files, %q", noticeInputs)
2315 }
2316 if !inList("GENRULE_NOTICE", noticeInputs) {
2317 t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs)
2318 }
2319 // aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets.
2320 res := foo.Output("package-res.apk")
2321 aapt2Flags := res.Args["flags"]
2322 e := "-A " + buildDir + "/.intermediates/foo/android_common/NOTICE"
2323 if !strings.Contains(aapt2Flags, e) {
2324 t.Errorf("asset dir flag for NOTICE, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
2325 }
2326
2327 // bar has NOTICE files to process, but embed_notices is not set.
2328 bar := ctx.ModuleForTests("bar", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07002329 res = bar.Output("package-res.apk")
2330 aapt2Flags = res.Args["flags"]
2331 e = "-A " + buildDir + "/.intermediates/bar/android_common/NOTICE"
2332 if strings.Contains(aapt2Flags, e) {
2333 t.Errorf("bar shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002334 }
2335
2336 // baz's embed_notice is true, but it doesn't have any NOTICE files.
2337 baz := ctx.ModuleForTests("baz", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07002338 res = baz.Output("package-res.apk")
2339 aapt2Flags = res.Args["flags"]
2340 e = "-A " + buildDir + "/.intermediates/baz/android_common/NOTICE"
2341 if strings.Contains(aapt2Flags, e) {
2342 t.Errorf("baz shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002343 }
2344}
Colin Cross53a87f52019-06-25 13:35:30 -07002345
2346func TestUncompressDex(t *testing.T) {
2347 testCases := []struct {
2348 name string
2349 bp string
2350
2351 uncompressedPlatform bool
2352 uncompressedUnbundled bool
2353 }{
2354 {
2355 name: "normal",
2356 bp: `
2357 android_app {
2358 name: "foo",
2359 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002360 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002361 }
2362 `,
2363 uncompressedPlatform: true,
2364 uncompressedUnbundled: false,
2365 },
2366 {
2367 name: "use_embedded_dex",
2368 bp: `
2369 android_app {
2370 name: "foo",
2371 use_embedded_dex: true,
2372 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002373 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002374 }
2375 `,
2376 uncompressedPlatform: true,
2377 uncompressedUnbundled: true,
2378 },
2379 {
2380 name: "privileged",
2381 bp: `
2382 android_app {
2383 name: "foo",
2384 privileged: true,
2385 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002386 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07002387 }
2388 `,
2389 uncompressedPlatform: true,
2390 uncompressedUnbundled: true,
2391 },
2392 }
2393
2394 test := func(t *testing.T, bp string, want bool, unbundled bool) {
2395 t.Helper()
2396
Colin Cross98be1bb2019-12-13 20:41:13 -08002397 config := testAppConfig(nil, bp, nil)
Colin Cross53a87f52019-06-25 13:35:30 -07002398 if unbundled {
2399 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
2400 }
2401
Colin Cross98be1bb2019-12-13 20:41:13 -08002402 ctx := testContext()
Colin Cross53a87f52019-06-25 13:35:30 -07002403
2404 run(t, ctx, config)
2405
2406 foo := ctx.ModuleForTests("foo", "android_common")
2407 dex := foo.Rule("r8")
2408 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
2409 aligned := foo.MaybeRule("zipalign").Rule != nil
2410
2411 if uncompressedInDexJar != want {
2412 t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar)
2413 }
2414
2415 if aligned != want {
2416 t.Errorf("want aligned %v, got %v", want, aligned)
2417 }
2418 }
2419
2420 for _, tt := range testCases {
2421 t.Run(tt.name, func(t *testing.T) {
2422 t.Run("platform", func(t *testing.T) {
2423 test(t, tt.bp, tt.uncompressedPlatform, false)
2424 })
2425 t.Run("unbundled", func(t *testing.T) {
2426 test(t, tt.bp, tt.uncompressedUnbundled, true)
2427 })
2428 })
2429 }
2430}
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002431
2432func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
2433 if expectedValue != "" {
2434 expectedFlag := "--" + flagName + " " + expectedValue
2435 if !strings.Contains(aapt2Flags, expectedFlag) {
2436 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
2437 }
2438 } else {
2439 unexpectedFlag := "--" + flagName
2440 if strings.Contains(aapt2Flags, unexpectedFlag) {
2441 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
2442 }
2443 }
2444}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002445
2446func TestRuntimeResourceOverlay(t *testing.T) {
Jaewoong Jungca095d72020-04-09 16:15:30 -07002447 fs := map[string][]byte{
2448 "baz/res/res/values/strings.xml": nil,
2449 "bar/res/res/values/strings.xml": nil,
2450 }
2451 bp := `
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002452 runtime_resource_overlay {
2453 name: "foo",
2454 certificate: "platform",
2455 product_specific: true,
Jaewoong Jungca095d72020-04-09 16:15:30 -07002456 static_libs: ["bar"],
2457 resource_libs: ["baz"],
Jaewoong Jungf0f747c2020-01-24 10:30:02 -08002458 aaptflags: ["--keep-raw-values"],
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002459 }
2460
2461 runtime_resource_overlay {
2462 name: "foo_themed",
2463 certificate: "platform",
2464 product_specific: true,
2465 theme: "faza",
Jaewoong Jungbfc6ac02020-04-24 15:22:40 -07002466 overrides: ["foo"],
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002467 }
Jaewoong Jungca095d72020-04-09 16:15:30 -07002468
2469 android_library {
2470 name: "bar",
2471 resource_dirs: ["bar/res"],
2472 }
2473
2474 android_app {
2475 name: "baz",
2476 sdk_version: "current",
2477 resource_dirs: ["baz/res"],
2478 }
2479 `
2480 config := testAppConfig(nil, bp, fs)
2481 ctx := testContext()
2482 run(t, ctx, config)
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002483
2484 m := ctx.ModuleForTests("foo", "android_common")
2485
Jaewoong Jungf0f747c2020-01-24 10:30:02 -08002486 // Check AAPT2 link flags.
2487 aapt2Flags := m.Output("package-res.apk").Args["flags"]
2488 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
2489 absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
2490 if len(absentFlags) > 0 {
2491 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
2492 }
2493
Jaewoong Jungca095d72020-04-09 16:15:30 -07002494 // Check overlay.list output for static_libs dependency.
2495 overlayList := m.Output("aapt2/overlay.list").Inputs.Strings()
2496 staticLibPackage := buildDir + "/.intermediates/bar/android_common/package-res.apk"
2497 if !inList(staticLibPackage, overlayList) {
2498 t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
2499 }
2500
2501 // Check AAPT2 link flags for resource_libs dependency.
2502 resourceLibFlag := "-I " + buildDir + "/.intermediates/baz/android_common/package-res.apk"
2503 if !strings.Contains(aapt2Flags, resourceLibFlag) {
2504 t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
2505 }
2506
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002507 // Check cert signing flag.
2508 signedApk := m.Output("signed/foo.apk")
2509 signingFlag := signedApk.Args["certificates"]
2510 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
2511 if expected != signingFlag {
2512 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
2513 }
Jaewoong Jungbfc6ac02020-04-24 15:22:40 -07002514 androidMkEntries := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
2515 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
Jaewoong Jung78ec5d82020-01-31 10:11:47 -08002516 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
2517 if !reflect.DeepEqual(path, expectedPath) {
2518 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
2519 }
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002520
2521 // Check device location.
Jaewoong Jungbfc6ac02020-04-24 15:22:40 -07002522 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Jaewoong Jung78ec5d82020-01-31 10:11:47 -08002523 expectedPath = []string{"/tmp/target/product/test_device/product/overlay"}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002524 if !reflect.DeepEqual(path, expectedPath) {
2525 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
2526 }
2527
2528 // A themed module has a different device location
2529 m = ctx.ModuleForTests("foo_themed", "android_common")
Jaewoong Jungbfc6ac02020-04-24 15:22:40 -07002530 androidMkEntries = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
2531 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002532 expectedPath = []string{"/tmp/target/product/test_device/product/overlay/faza"}
2533 if !reflect.DeepEqual(path, expectedPath) {
2534 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
2535 }
Jaewoong Jungbfc6ac02020-04-24 15:22:40 -07002536
2537 overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
2538 expectedOverrides := []string{"foo"}
2539 if !reflect.DeepEqual(overrides, expectedOverrides) {
2540 t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
2541 }
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08002542}
Jaewoong Jung062ed7e2020-04-26 15:10:51 -07002543
2544func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
2545 ctx, config := testJava(t, `
2546 java_defaults {
2547 name: "rro_defaults",
2548 theme: "default_theme",
2549 product_specific: true,
2550 aaptflags: ["--keep-raw-values"],
2551 }
2552
2553 runtime_resource_overlay {
2554 name: "foo_with_defaults",
2555 defaults: ["rro_defaults"],
2556 }
2557
2558 runtime_resource_overlay {
2559 name: "foo_barebones",
2560 }
2561 `)
2562
2563 //
2564 // RRO module with defaults
2565 //
2566 m := ctx.ModuleForTests("foo_with_defaults", "android_common")
2567
2568 // Check AAPT2 link flags.
2569 aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
2570 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
2571 absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
2572 if len(absentFlags) > 0 {
2573 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
2574 }
2575
2576 // Check device location.
2577 path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
2578 expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"}
2579 if !reflect.DeepEqual(path, expectedPath) {
2580 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath)
2581 }
2582
2583 //
2584 // RRO module without defaults
2585 //
2586 m = ctx.ModuleForTests("foo_barebones", "android_common")
2587
2588 // Check AAPT2 link flags.
2589 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
2590 unexpectedFlags := "--keep-raw-values"
2591 if inList(unexpectedFlags, aapt2Flags) {
2592 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
2593 }
2594
2595 // Check device location.
2596 path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
2597 expectedPath = []string{"/tmp/target/product/test_device/system/overlay"}
2598 if !reflect.DeepEqual(path, expectedPath) {
2599 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
2600 }
2601}