blob: f8943798b000d8cca895925bac542928e9c1de62 [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 Cross323dc602020-09-18 14:25:31 -070070 t.Parallel()
Colin Crossa97c5d32018-03-28 14:58:31 -070071 for _, moduleType := range []string{"android_app", "android_library"} {
72 t.Run(moduleType, func(t *testing.T) {
73 ctx := testApp(t, moduleType+` {
74 name: "foo",
75 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +090076 sdk_version: "current"
Colin Crossa97c5d32018-03-28 14:58:31 -070077 }
78 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080079
Colin Crossa97c5d32018-03-28 14:58:31 -070080 foo := ctx.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080081
Colin Cross31656952018-05-24 16:11:20 -070082 var expectedLinkImplicits []string
83
84 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
85 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080086
Colin Crossa97c5d32018-03-28 14:58:31 -070087 frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
88 expectedLinkImplicits = append(expectedLinkImplicits,
89 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080090
Colin Crossa97c5d32018-03-28 14:58:31 -070091 // Test the mapping from input files to compiled output file names
92 compile := foo.Output(compiledResourceFiles[0])
93 if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
94 t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
95 resourceFiles, compile.Inputs.Strings())
96 }
Colin Crossb69301e2017-12-01 10:48:26 -080097
Colin Crossa97c5d32018-03-28 14:58:31 -070098 compiledResourceOutputs := compile.Outputs.Strings()
99 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -0800100
Colin Crossa97c5d32018-03-28 14:58:31 -0700101 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800102
Colin Crossa97c5d32018-03-28 14:58:31 -0700103 list := foo.Output("aapt2/res.list")
104 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800105
Colin Crossa97c5d32018-03-28 14:58:31 -0700106 // Check that the link rule uses
107 res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
108 if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
109 t.Errorf("expected aapt2 link implicits expected:\n %#v\n got:\n %#v",
110 expectedLinkImplicits, res.Implicits.Strings())
111 }
112 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800113 }
114}
Colin Cross890ff552017-11-30 20:13:19 -0800115
Colin Crosse560c4a2019-03-19 16:03:11 -0700116func TestAppSplits(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700117 t.Parallel()
Colin Crosse560c4a2019-03-19 16:03:11 -0700118 ctx := testApp(t, `
119 android_app {
120 name: "foo",
121 srcs: ["a.java"],
122 package_splits: ["v4", "v7,hdpi"],
Jeongik Cha538c0d02019-07-11 15:54:27 +0900123 sdk_version: "current"
Colin Crosse560c4a2019-03-19 16:03:11 -0700124 }`)
125
126 foo := ctx.ModuleForTests("foo", "android_common")
127
128 expectedOutputs := []string{
129 filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
130 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
131 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
132 }
133 for _, expectedOutput := range expectedOutputs {
134 foo.Output(expectedOutput)
135 }
136
Colin Cross41955e82019-05-29 14:40:35 -0700137 outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
138 if err != nil {
139 t.Fatal(err)
140 }
141 if g, w := outputFiles.Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
142 t.Errorf(`want OutputFiles("") = %q, got %q`, w, g)
Colin Crosse560c4a2019-03-19 16:03:11 -0700143 }
144}
145
Sasha Smundaka7856c02020-04-23 09:49:59 -0700146func TestAndroidAppSet(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700147 t.Parallel()
Sasha Smundaka7856c02020-04-23 09:49:59 -0700148 ctx, config := testJava(t, `
149 android_app_set {
150 name: "foo",
151 set: "prebuilts/apks/app.apks",
152 prerelease: true,
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700153 }`)
Sasha Smundaka7856c02020-04-23 09:49:59 -0700154 module := ctx.ModuleForTests("foo", "android_common")
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700155 const packedSplitApks = "foo.zip"
Sasha Smundaka7856c02020-04-23 09:49:59 -0700156 params := module.Output(packedSplitApks)
157 if params.Rule == nil {
158 t.Errorf("expected output %s is missing", packedSplitApks)
159 }
160 if s := params.Args["allow-prereleased"]; s != "true" {
161 t.Errorf("wrong allow-prereleased value: '%s', expected 'true'", s)
162 }
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700163 if s := params.Args["partition"]; s != "system" {
164 t.Errorf("wrong partition value: '%s', expected 'system'", s)
165 }
Sasha Smundaka7856c02020-04-23 09:49:59 -0700166 mkEntries := android.AndroidMkEntriesForTest(t, config, "", module.Module())[0]
Liz Kammercada8072020-07-28 15:47:38 -0700167 actualInstallFile := mkEntries.EntryMap["LOCAL_APK_SET_INSTALL_FILE"]
168 expectedInstallFile := []string{"foo.apk"}
169 if !reflect.DeepEqual(actualInstallFile, expectedInstallFile) {
170 t.Errorf("Unexpected LOCAL_APK_SET_INSTALL_FILE value: '%s', expected: '%s',",
171 actualInstallFile, expectedInstallFile)
Sasha Smundaka7856c02020-04-23 09:49:59 -0700172 }
173}
174
175func TestAndroidAppSet_Variants(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700176 t.Parallel()
Sasha Smundaka7856c02020-04-23 09:49:59 -0700177 bp := `
178 android_app_set {
179 name: "foo",
180 set: "prebuilts/apks/app.apks",
181 }`
182 testCases := []struct {
Jaewoong Jung829b7132020-06-10 12:23:32 -0700183 name string
184 targets []android.Target
185 aaptPrebuiltDPI []string
186 sdkVersion int
187 expected map[string]string
Sasha Smundaka7856c02020-04-23 09:49:59 -0700188 }{
189 {
Jaewoong Jung829b7132020-06-10 12:23:32 -0700190 name: "One",
191 targets: []android.Target{
192 {Os: android.Android, Arch: android.Arch{ArchType: android.X86}},
193 },
Sasha Smundaka7856c02020-04-23 09:49:59 -0700194 aaptPrebuiltDPI: []string{"ldpi", "xxhdpi"},
195 sdkVersion: 29,
196 expected: map[string]string{
197 "abis": "X86",
198 "allow-prereleased": "false",
199 "screen-densities": "LDPI,XXHDPI",
200 "sdk-version": "29",
201 "stem": "foo",
202 },
203 },
204 {
Jaewoong Jung829b7132020-06-10 12:23:32 -0700205 name: "Two",
206 targets: []android.Target{
207 {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64}},
208 {Os: android.Android, Arch: android.Arch{ArchType: android.X86}},
209 },
210 aaptPrebuiltDPI: nil,
211 sdkVersion: 30,
Sasha Smundaka7856c02020-04-23 09:49:59 -0700212 expected: map[string]string{
213 "abis": "X86_64,X86",
214 "allow-prereleased": "false",
215 "screen-densities": "all",
216 "sdk-version": "30",
217 "stem": "foo",
218 },
219 },
220 }
221
222 for _, test := range testCases {
223 config := testAppConfig(nil, bp, nil)
224 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
225 config.TestProductVariables.Platform_sdk_version = &test.sdkVersion
Jaewoong Jung829b7132020-06-10 12:23:32 -0700226 config.Targets[android.Android] = test.targets
Sasha Smundaka7856c02020-04-23 09:49:59 -0700227 ctx := testContext()
228 run(t, ctx, config)
229 module := ctx.ModuleForTests("foo", "android_common")
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700230 const packedSplitApks = "foo.zip"
Sasha Smundaka7856c02020-04-23 09:49:59 -0700231 params := module.Output(packedSplitApks)
232 for k, v := range test.expected {
233 if actual := params.Args[k]; actual != v {
234 t.Errorf("%s: bad build arg value for '%s': '%s', expected '%s'",
235 test.name, k, actual, v)
236 }
237 }
238 }
239}
240
Jeongik Cha538c0d02019-07-11 15:54:27 +0900241func TestPlatformAPIs(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700242 t.Parallel()
Jeongik Cha538c0d02019-07-11 15:54:27 +0900243 testJava(t, `
244 android_app {
245 name: "foo",
246 srcs: ["a.java"],
247 platform_apis: true,
248 }
249 `)
250
251 testJava(t, `
252 android_app {
253 name: "foo",
254 srcs: ["a.java"],
255 sdk_version: "current",
256 }
257 `)
258
259 testJavaError(t, "platform_apis must be true when sdk_version is empty.", `
260 android_app {
261 name: "bar",
262 srcs: ["b.java"],
263 }
264 `)
265
266 testJavaError(t, "platform_apis must be false when sdk_version is not empty.", `
267 android_app {
268 name: "bar",
269 srcs: ["b.java"],
270 sdk_version: "system_current",
271 platform_apis: true,
272 }
273 `)
274}
275
Jeongik Chae403e9e2019-12-07 00:16:24 +0900276func TestAndroidAppLinkType(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700277 t.Parallel()
Jeongik Chae403e9e2019-12-07 00:16:24 +0900278 testJava(t, `
279 android_app {
280 name: "foo",
281 srcs: ["a.java"],
282 libs: ["bar"],
283 static_libs: ["baz"],
284 platform_apis: true,
285 }
286
287 java_library {
288 name: "bar",
289 sdk_version: "current",
290 srcs: ["b.java"],
291 }
292
293 android_library {
294 name: "baz",
295 sdk_version: "system_current",
296 srcs: ["c.java"],
297 }
298 `)
299
300 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.", `
301 android_app {
302 name: "foo",
303 srcs: ["a.java"],
304 libs: ["bar"],
305 sdk_version: "current",
306 static_libs: ["baz"],
307 }
308
309 java_library {
310 name: "bar",
311 sdk_version: "current",
312 srcs: ["b.java"],
313 }
314
315 android_library {
316 name: "baz",
317 sdk_version: "system_current",
318 srcs: ["c.java"],
319 }
320 `)
321
322 testJava(t, `
323 android_app {
324 name: "foo",
325 srcs: ["a.java"],
326 libs: ["bar"],
327 sdk_version: "system_current",
328 static_libs: ["baz"],
329 }
330
331 java_library {
332 name: "bar",
333 sdk_version: "current",
334 srcs: ["b.java"],
335 }
336
337 android_library {
338 name: "baz",
339 sdk_version: "system_current",
340 srcs: ["c.java"],
341 }
342 `)
343
344 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.", `
345 android_app {
346 name: "foo",
347 srcs: ["a.java"],
348 libs: ["bar"],
349 sdk_version: "system_current",
350 static_libs: ["baz"],
351 }
352
353 java_library {
354 name: "bar",
355 sdk_version: "current",
356 srcs: ["b.java"],
357 }
358
359 android_library {
360 name: "baz",
361 srcs: ["c.java"],
362 }
363 `)
364}
365
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100366func TestUpdatableApps(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700367 t.Parallel()
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100368 testCases := []struct {
369 name string
370 bp string
371 expectedError string
372 }{
373 {
374 name: "Stable public SDK",
375 bp: `android_app {
376 name: "foo",
377 srcs: ["a.java"],
378 sdk_version: "29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100379 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100380 updatable: true,
381 }`,
382 },
383 {
384 name: "Stable system SDK",
385 bp: `android_app {
386 name: "foo",
387 srcs: ["a.java"],
388 sdk_version: "system_29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100389 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100390 updatable: true,
391 }`,
392 },
393 {
394 name: "Current public SDK",
395 bp: `android_app {
396 name: "foo",
397 srcs: ["a.java"],
398 sdk_version: "current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100399 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100400 updatable: true,
401 }`,
402 },
403 {
404 name: "Current system SDK",
405 bp: `android_app {
406 name: "foo",
407 srcs: ["a.java"],
408 sdk_version: "system_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100409 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100410 updatable: true,
411 }`,
412 },
413 {
414 name: "Current module SDK",
415 bp: `android_app {
416 name: "foo",
417 srcs: ["a.java"],
418 sdk_version: "module_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100419 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100420 updatable: true,
421 }`,
422 },
423 {
424 name: "Current core SDK",
425 bp: `android_app {
426 name: "foo",
427 srcs: ["a.java"],
428 sdk_version: "core_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100429 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100430 updatable: true,
431 }`,
432 },
433 {
434 name: "No Platform APIs",
435 bp: `android_app {
436 name: "foo",
437 srcs: ["a.java"],
438 platform_apis: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100439 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100440 updatable: true,
441 }`,
442 expectedError: "Updatable apps must use stable SDKs",
443 },
444 {
445 name: "No Core Platform APIs",
446 bp: `android_app {
447 name: "foo",
448 srcs: ["a.java"],
449 sdk_version: "core_platform",
Artur Satayevf40fc852020-04-16 13:43:02 +0100450 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100451 updatable: true,
452 }`,
453 expectedError: "Updatable apps must use stable SDKs",
454 },
455 {
456 name: "No unspecified APIs",
457 bp: `android_app {
458 name: "foo",
459 srcs: ["a.java"],
460 updatable: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100461 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100462 }`,
463 expectedError: "Updatable apps must use stable SDK",
464 },
Artur Satayevf40fc852020-04-16 13:43:02 +0100465 {
466 name: "Must specify min_sdk_version",
467 bp: `android_app {
468 name: "app_without_min_sdk_version",
469 srcs: ["a.java"],
470 sdk_version: "29",
471 updatable: true,
472 }`,
473 expectedError: "updatable apps must set min_sdk_version.",
474 },
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100475 }
476
477 for _, test := range testCases {
478 t.Run(test.name, func(t *testing.T) {
479 if test.expectedError == "" {
480 testJava(t, test.bp)
481 } else {
482 testJavaError(t, test.expectedError, test.bp)
483 }
484 })
485 }
486}
487
Jooyung Han749dc692020-04-15 11:03:39 +0900488func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700489 t.Parallel()
Jooyung Han749dc692020-04-15 11:03:39 +0900490 testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
491 android_app {
492 name: "foo",
493 srcs: ["a.java"],
494 updatable: true,
495 sdk_version: "current",
496 min_sdk_version: "29",
497 static_libs: ["bar"],
498 }
499
500 java_library {
501 name: "bar",
502 sdk_version: "current",
503 }
504 `)
505}
506
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900507func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700508 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900509 testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
510 android_app {
511 name: "foo",
512 srcs: ["a.java"],
513 updatable: true,
514 sdk_version: "current",
515 min_sdk_version: "current",
516 jni_libs: ["libjni"],
517 }
518
519 cc_library {
520 name: "libjni",
521 stl: "none",
522 system_shared_libs: [],
523 sdk_version: "current",
524 }
525 `)
526}
527
528func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700529 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900530 bp := cc.GatherRequiredDepsForTest(android.Android) + `
531 android_app {
532 name: "foo",
533 srcs: ["a.java"],
534 updatable: true,
535 sdk_version: "current",
536 min_sdk_version: "29",
537 jni_libs: ["libjni"],
538 }
539
540 cc_library {
541 name: "libjni",
542 stl: "none",
543 system_shared_libs: [],
544 sdk_version: "29",
545 }
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900546 `
547 fs := map[string][]byte{
548 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
549 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": nil,
550 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o": nil,
551 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o": nil,
552 }
553
554 ctx, _ := testJavaWithConfig(t, testConfig(nil, bp, fs))
555
556 inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
557 var crtbeginFound, crtendFound bool
Dan Albert92fe7402020-07-15 13:33:30 -0700558 expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
559 "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
560 expectedCrtEnd := ctx.ModuleForTests("crtend_so",
561 "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
562 implicits := []string{}
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900563 for _, input := range inputs {
Dan Albert92fe7402020-07-15 13:33:30 -0700564 implicits = append(implicits, input.String())
565 if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900566 crtbeginFound = true
Dan Albert92fe7402020-07-15 13:33:30 -0700567 } else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900568 crtendFound = true
569 }
570 }
Dan Albert92fe7402020-07-15 13:33:30 -0700571 if !crtbeginFound {
572 t.Error(fmt.Sprintf(
573 "expected implicit with suffix %q, have the following implicits:\n%s",
574 expectedCrtBegin, strings.Join(implicits, "\n")))
575 }
576 if !crtendFound {
577 t.Error(fmt.Sprintf(
578 "expected implicit with suffix %q, have the following implicits:\n%s",
579 expectedCrtEnd, strings.Join(implicits, "\n")))
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900580 }
581}
582
583func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700584 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900585 bp := cc.GatherRequiredDepsForTest(android.Android) + `
586 android_app {
587 name: "foo",
588 srcs: ["a.java"],
589 updatable: true,
590 sdk_version: "current",
591 min_sdk_version: "29", // this APK should support 29
592 jni_libs: ["libjni"],
593 }
594
595 cc_library {
596 name: "libjni",
597 stl: "none",
598 sdk_version: "current",
599 }
600 `
601 testJavaError(t, `"libjni" .*: sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
602}
603
604func TestUpdatableApps_ErrorIfDepSdkVersionIsHigher(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700605 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900606 bp := cc.GatherRequiredDepsForTest(android.Android) + `
607 android_app {
608 name: "foo",
609 srcs: ["a.java"],
610 updatable: true,
611 sdk_version: "current",
612 min_sdk_version: "29", // this APK should support 29
613 jni_libs: ["libjni"],
614 }
615
616 cc_library {
617 name: "libjni",
618 stl: "none",
619 shared_libs: ["libbar"],
620 system_shared_libs: [],
621 sdk_version: "27",
622 }
623
624 cc_library {
625 name: "libbar",
626 stl: "none",
627 system_shared_libs: [],
628 sdk_version: "current",
629 }
630 `
631 testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp)
632}
633
Colin Cross0ddae7f2019-02-07 15:30:01 -0800634func TestResourceDirs(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700635 t.Parallel()
Colin Cross0ddae7f2019-02-07 15:30:01 -0800636 testCases := []struct {
637 name string
638 prop string
639 resources []string
640 }{
641 {
642 name: "no resource_dirs",
643 prop: "",
644 resources: []string{"res/res/values/strings.xml"},
645 },
646 {
647 name: "resource_dirs",
648 prop: `resource_dirs: ["res"]`,
649 resources: []string{"res/res/values/strings.xml"},
650 },
651 {
652 name: "empty resource_dirs",
653 prop: `resource_dirs: []`,
654 resources: nil,
655 },
656 }
657
658 fs := map[string][]byte{
659 "res/res/values/strings.xml": nil,
660 }
661
662 bp := `
663 android_app {
664 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900665 sdk_version: "current",
Colin Cross0ddae7f2019-02-07 15:30:01 -0800666 %s
667 }
668 `
669
670 for _, testCase := range testCases {
671 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800672 config := testConfig(nil, fmt.Sprintf(bp, testCase.prop), fs)
673 ctx := testContext()
Colin Cross0ddae7f2019-02-07 15:30:01 -0800674 run(t, ctx, config)
675
676 module := ctx.ModuleForTests("foo", "android_common")
677 resourceList := module.MaybeOutput("aapt2/res.list")
678
679 var resources []string
680 if resourceList.Rule != nil {
681 for _, compiledResource := range resourceList.Inputs.Strings() {
682 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
683 }
684 }
685
686 if !reflect.DeepEqual(resources, testCase.resources) {
687 t.Errorf("expected resource files %q, got %q",
688 testCase.resources, resources)
689 }
690 })
691 }
692}
693
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800694func TestLibraryAssets(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700695 t.Parallel()
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800696 bp := `
697 android_app {
698 name: "foo",
699 sdk_version: "current",
700 static_libs: ["lib1", "lib2", "lib3"],
701 }
702
703 android_library {
704 name: "lib1",
705 sdk_version: "current",
706 asset_dirs: ["assets_a"],
707 }
708
709 android_library {
710 name: "lib2",
711 sdk_version: "current",
712 }
713
714 android_library {
715 name: "lib3",
716 sdk_version: "current",
717 static_libs: ["lib4"],
718 }
719
720 android_library {
721 name: "lib4",
722 sdk_version: "current",
723 asset_dirs: ["assets_b"],
724 }
725 `
726
727 testCases := []struct {
728 name string
729 assetFlag string
730 assetPackages []string
731 }{
732 {
733 name: "foo",
734 // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
735 assetPackages: []string{
736 buildDir + "/.intermediates/foo/android_common/aapt2/package-res.apk",
737 buildDir + "/.intermediates/lib1/android_common/assets.zip",
738 buildDir + "/.intermediates/lib3/android_common/assets.zip",
739 },
740 },
741 {
742 name: "lib1",
743 assetFlag: "-A assets_a",
744 },
745 {
746 name: "lib2",
747 },
748 {
749 name: "lib3",
750 assetPackages: []string{
751 buildDir + "/.intermediates/lib3/android_common/aapt2/package-res.apk",
752 buildDir + "/.intermediates/lib4/android_common/assets.zip",
753 },
754 },
755 {
756 name: "lib4",
757 assetFlag: "-A assets_b",
758 },
759 }
760 ctx := testApp(t, bp)
761
762 for _, test := range testCases {
763 t.Run(test.name, func(t *testing.T) {
764 m := ctx.ModuleForTests(test.name, "android_common")
765
766 // Check asset flag in aapt2 link flags
767 var aapt2link android.TestingBuildParams
768 if len(test.assetPackages) > 0 {
769 aapt2link = m.Output("aapt2/package-res.apk")
770 } else {
771 aapt2link = m.Output("package-res.apk")
772 }
773 aapt2Flags := aapt2link.Args["flags"]
774 if test.assetFlag != "" {
775 if !strings.Contains(aapt2Flags, test.assetFlag) {
776 t.Errorf("Can't find asset flag %q in aapt2 link flags %q", test.assetFlag, aapt2Flags)
777 }
778 } else {
779 if strings.Contains(aapt2Flags, " -A ") {
780 t.Errorf("aapt2 link flags %q contain unexpected asset flag", aapt2Flags)
781 }
782 }
783
784 // Check asset merge rule.
785 if len(test.assetPackages) > 0 {
786 mergeAssets := m.Output("package-res.apk")
787 if !reflect.DeepEqual(test.assetPackages, mergeAssets.Inputs.Strings()) {
788 t.Errorf("Unexpected mergeAssets inputs: %v, expected: %v",
789 mergeAssets.Inputs.Strings(), test.assetPackages)
790 }
791 }
792 })
793 }
794}
795
Colin Crossbec85302019-02-13 13:15:46 -0800796func TestAndroidResources(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700797 t.Parallel()
Colin Cross5c4791c2019-02-01 11:44:44 -0800798 testCases := []struct {
799 name string
800 enforceRROTargets []string
801 enforceRROExcludedOverlays []string
Colin Crossbec85302019-02-13 13:15:46 -0800802 resourceFiles map[string][]string
Colin Cross5c4791c2019-02-01 11:44:44 -0800803 overlayFiles map[string][]string
804 rroDirs map[string][]string
805 }{
806 {
807 name: "no RRO",
808 enforceRROTargets: nil,
809 enforceRROExcludedOverlays: nil,
Colin Crossbec85302019-02-13 13:15:46 -0800810 resourceFiles: map[string][]string{
811 "foo": nil,
812 "bar": {"bar/res/res/values/strings.xml"},
813 "lib": nil,
814 "lib2": {"lib2/res/res/values/strings.xml"},
815 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800816 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800817 "foo": {
818 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800819 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000820 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800821 "foo/res/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800822 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
823 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Anton Hansson53c88442019-03-18 15:53:16 +0000824 "product/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800825 },
Colin Crossbec85302019-02-13 13:15:46 -0800826 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800827 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
828 "device/vendor/blah/overlay/bar/res/values/strings.xml",
829 },
Colin Crossbec85302019-02-13 13:15:46 -0800830 "lib": {
831 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
832 "lib/res/res/values/strings.xml",
833 "device/vendor/blah/overlay/lib/res/values/strings.xml",
834 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800835 },
836 rroDirs: map[string][]string{
837 "foo": nil,
838 "bar": nil,
839 },
840 },
841 {
842 name: "enforce RRO on foo",
843 enforceRROTargets: []string{"foo"},
844 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossbec85302019-02-13 13:15:46 -0800845 resourceFiles: map[string][]string{
846 "foo": nil,
847 "bar": {"bar/res/res/values/strings.xml"},
848 "lib": nil,
849 "lib2": {"lib2/res/res/values/strings.xml"},
850 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800851 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800852 "foo": {
853 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800854 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000855 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800856 "foo/res/res/values/strings.xml",
857 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
858 },
Colin Crossbec85302019-02-13 13:15:46 -0800859 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800860 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
861 "device/vendor/blah/overlay/bar/res/values/strings.xml",
862 },
Colin Crossbec85302019-02-13 13:15:46 -0800863 "lib": {
864 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
865 "lib/res/res/values/strings.xml",
866 "device/vendor/blah/overlay/lib/res/values/strings.xml",
867 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800868 },
Colin Crossc1c37552019-01-31 11:42:41 -0800869
Colin Cross5c4791c2019-02-01 11:44:44 -0800870 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800871 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000872 "device:device/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800873 // Enforce RRO on "foo" could imply RRO on static dependencies, but for now it doesn't.
874 // "device/vendor/blah/overlay/lib/res",
Anton Hansson53c88442019-03-18 15:53:16 +0000875 "product:product/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800876 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800877 "bar": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800878 "lib": nil,
Colin Cross5c4791c2019-02-01 11:44:44 -0800879 },
880 },
881 {
882 name: "enforce RRO on all",
883 enforceRROTargets: []string{"*"},
884 enforceRROExcludedOverlays: []string{
885 // Excluding specific apps/res directories also allowed.
886 "device/vendor/blah/static_overlay/foo",
887 "device/vendor/blah/static_overlay/bar/res",
888 },
Colin Crossbec85302019-02-13 13:15:46 -0800889 resourceFiles: map[string][]string{
890 "foo": nil,
891 "bar": {"bar/res/res/values/strings.xml"},
892 "lib": nil,
893 "lib2": {"lib2/res/res/values/strings.xml"},
894 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800895 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800896 "foo": {
897 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800898 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000899 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800900 "foo/res/res/values/strings.xml",
901 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
902 },
Colin Crossbec85302019-02-13 13:15:46 -0800903 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
904 "lib": {
905 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
906 "lib/res/res/values/strings.xml",
907 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800908 },
909 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800910 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000911 "device:device/vendor/blah/overlay/foo/res",
912 "product:product/vendor/blah/overlay/foo/res",
913 // Lib dep comes after the direct deps
914 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800915 },
Anton Hansson53c88442019-03-18 15:53:16 +0000916 "bar": {"device:device/vendor/blah/overlay/bar/res"},
917 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800918 },
919 },
920 }
921
Anton Hansson53c88442019-03-18 15:53:16 +0000922 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -0800923 "device/vendor/blah/overlay",
924 "device/vendor/blah/overlay2",
925 "device/vendor/blah/static_overlay",
926 }
927
Anton Hansson53c88442019-03-18 15:53:16 +0000928 productResourceOverlays := []string{
929 "product/vendor/blah/overlay",
930 }
931
Colin Cross890ff552017-11-30 20:13:19 -0800932 fs := map[string][]byte{
933 "foo/res/res/values/strings.xml": nil,
934 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800935 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800936 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800937 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
938 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800939 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800940 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
941 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
942 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +0000943 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800944 }
945
946 bp := `
947 android_app {
948 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900949 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800950 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +0000951 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -0800952 }
953
954 android_app {
955 name: "bar",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900956 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -0800957 resource_dirs: ["bar/res"],
958 }
Colin Cross6ed7dea2019-01-31 14:44:30 -0800959
960 android_library {
961 name: "lib",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900962 sdk_version: "current",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800963 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -0800964 static_libs: ["lib2"],
965 }
966
967 android_library {
968 name: "lib2",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900969 sdk_version: "current",
Colin Crossbec85302019-02-13 13:15:46 -0800970 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -0800971 }
Anton Hansson53c88442019-03-18 15:53:16 +0000972
973 // This library has the same resources as lib (should not lead to dupe RROs)
974 android_library {
975 name: "lib3",
Jeongik Cha75b83b02019-11-01 15:28:00 +0900976 sdk_version: "current",
Anton Hansson53c88442019-03-18 15:53:16 +0000977 resource_dirs: ["lib/res"]
978 }
Colin Cross890ff552017-11-30 20:13:19 -0800979 `
980
Colin Cross5c4791c2019-02-01 11:44:44 -0800981 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -0800982 t.Run(testCase.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -0800983 config := testAppConfig(nil, bp, fs)
Anton Hansson53c88442019-03-18 15:53:16 +0000984 config.TestProductVariables.DeviceResourceOverlays = deviceResourceOverlays
985 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800986 if testCase.enforceRROTargets != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800987 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800988 }
989 if testCase.enforceRROExcludedOverlays != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800990 config.TestProductVariables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800991 }
992
Colin Cross98be1bb2019-12-13 20:41:13 -0800993 ctx := testContext()
Colin Cross890ff552017-11-30 20:13:19 -0800994 run(t, ctx, config)
995
Colin Crossbec85302019-02-13 13:15:46 -0800996 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
997 for _, o := range list {
998 res := module.MaybeOutput(o)
999 if res.Rule != nil {
1000 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
1001 // verify the inputs to the .arsc.flat rule.
1002 files = append(files, res.Inputs.Strings()...)
1003 } else {
1004 // Otherwise, verify the full path to the output of the other module
1005 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +00001006 }
Colin Cross890ff552017-11-30 20:13:19 -08001007 }
Colin Crossbec85302019-02-13 13:15:46 -08001008 return files
Colin Cross890ff552017-11-30 20:13:19 -08001009 }
1010
Colin Crossbec85302019-02-13 13:15:46 -08001011 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
1012 module := ctx.ModuleForTests(moduleName, "android_common")
1013 resourceList := module.MaybeOutput("aapt2/res.list")
1014 if resourceList.Rule != nil {
1015 resourceFiles = resourceListToFiles(module, resourceList.Inputs.Strings())
Anton Hansson0375a4f2019-01-24 14:39:19 +00001016 }
Colin Crossbec85302019-02-13 13:15:46 -08001017 overlayList := module.MaybeOutput("aapt2/overlay.list")
1018 if overlayList.Rule != nil {
1019 overlayFiles = resourceListToFiles(module, overlayList.Inputs.Strings())
1020 }
1021
Anton Hansson53c88442019-03-18 15:53:16 +00001022 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
1023 var prefix string
1024 if d.overlayType == device {
1025 prefix = "device:"
1026 } else if d.overlayType == product {
1027 prefix = "product:"
1028 } else {
1029 t.Fatalf("Unexpected overlayType %d", d.overlayType)
1030 }
1031 rroDirs = append(rroDirs, prefix+d.path.String())
1032 }
Colin Crossbec85302019-02-13 13:15:46 -08001033
1034 return resourceFiles, overlayFiles, rroDirs
1035 }
1036
1037 modules := []string{"foo", "bar", "lib", "lib2"}
1038 for _, module := range modules {
1039 resourceFiles, overlayFiles, rroDirs := getResources(module)
1040
1041 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
1042 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
1043 module, testCase.resourceFiles[module], resourceFiles)
1044 }
1045 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
1046 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
1047 module, testCase.overlayFiles[module], overlayFiles)
1048 }
1049 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +00001050 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossbec85302019-02-13 13:15:46 -08001051 module, testCase.rroDirs[module], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +00001052 }
Colin Cross890ff552017-11-30 20:13:19 -08001053 }
Colin Cross890ff552017-11-30 20:13:19 -08001054 })
1055 }
1056}
Colin Crossd09b0b62018-04-18 11:06:47 -07001057
Jeongik Cha219141c2020-08-06 23:00:37 +09001058func checkSdkVersion(t *testing.T, config android.Config, expectedSdkVersion string) {
1059 ctx := testContext()
1060
1061 run(t, ctx, config)
1062
1063 foo := ctx.ModuleForTests("foo", "android_common")
1064 link := foo.Output("package-res.apk")
1065 linkFlags := strings.Split(link.Args["flags"], " ")
1066 min := android.IndexList("--min-sdk-version", linkFlags)
1067 target := android.IndexList("--target-sdk-version", linkFlags)
1068
1069 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
1070 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
1071 }
1072
1073 gotMinSdkVersion := linkFlags[min+1]
1074 gotTargetSdkVersion := linkFlags[target+1]
1075
1076 if gotMinSdkVersion != expectedSdkVersion {
1077 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
1078 expectedSdkVersion, gotMinSdkVersion)
1079 }
1080
1081 if gotTargetSdkVersion != expectedSdkVersion {
1082 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
1083 expectedSdkVersion, gotTargetSdkVersion)
1084 }
1085}
1086
Colin Crossd09b0b62018-04-18 11:06:47 -07001087func TestAppSdkVersion(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001088 t.Parallel()
Colin Crossd09b0b62018-04-18 11:06:47 -07001089 testCases := []struct {
1090 name string
1091 sdkVersion string
1092 platformSdkInt int
1093 platformSdkCodename string
1094 platformSdkFinal bool
1095 expectedMinSdkVersion string
Jeongik Cha538c0d02019-07-11 15:54:27 +09001096 platformApis bool
Dan Albert4f378d72020-07-23 17:32:15 -07001097 activeCodenames []string
Colin Crossd09b0b62018-04-18 11:06:47 -07001098 }{
1099 {
1100 name: "current final SDK",
1101 sdkVersion: "current",
1102 platformSdkInt: 27,
1103 platformSdkCodename: "REL",
1104 platformSdkFinal: true,
1105 expectedMinSdkVersion: "27",
1106 },
1107 {
1108 name: "current non-final SDK",
1109 sdkVersion: "current",
1110 platformSdkInt: 27,
1111 platformSdkCodename: "OMR1",
1112 platformSdkFinal: false,
1113 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001114 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001115 },
1116 {
1117 name: "default final SDK",
1118 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001119 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001120 platformSdkInt: 27,
1121 platformSdkCodename: "REL",
1122 platformSdkFinal: true,
1123 expectedMinSdkVersion: "27",
1124 },
1125 {
1126 name: "default non-final SDK",
1127 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001128 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001129 platformSdkInt: 27,
1130 platformSdkCodename: "OMR1",
1131 platformSdkFinal: false,
1132 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001133 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001134 },
1135 {
1136 name: "14",
1137 sdkVersion: "14",
1138 expectedMinSdkVersion: "14",
Dan Albert4f378d72020-07-23 17:32:15 -07001139 platformSdkCodename: "S",
1140 activeCodenames: []string{"S"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001141 },
1142 }
1143
1144 for _, moduleType := range []string{"android_app", "android_library"} {
1145 for _, test := range testCases {
1146 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Jeongik Cha538c0d02019-07-11 15:54:27 +09001147 platformApiProp := ""
1148 if test.platformApis {
1149 platformApiProp = "platform_apis: true,"
1150 }
Colin Crossd09b0b62018-04-18 11:06:47 -07001151 bp := fmt.Sprintf(`%s {
1152 name: "foo",
1153 srcs: ["a.java"],
1154 sdk_version: "%s",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001155 %s
1156 }`, moduleType, test.sdkVersion, platformApiProp)
Colin Crossd09b0b62018-04-18 11:06:47 -07001157
Colin Cross98be1bb2019-12-13 20:41:13 -08001158 config := testAppConfig(nil, bp, nil)
Colin Crossd09b0b62018-04-18 11:06:47 -07001159 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
1160 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
Dan Albert4f378d72020-07-23 17:32:15 -07001161 config.TestProductVariables.Platform_version_active_codenames = test.activeCodenames
Colin Crossd09b0b62018-04-18 11:06:47 -07001162 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
Jeongik Cha219141c2020-08-06 23:00:37 +09001163 checkSdkVersion(t, config, test.expectedMinSdkVersion)
Colin Crossd09b0b62018-04-18 11:06:47 -07001164
Colin Crossd09b0b62018-04-18 11:06:47 -07001165 })
1166 }
1167 }
1168}
Colin Crossa4f08812018-10-02 22:03:40 -07001169
Jeongik Cha219141c2020-08-06 23:00:37 +09001170func TestVendorAppSdkVersion(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001171 t.Parallel()
Jeongik Cha219141c2020-08-06 23:00:37 +09001172 testCases := []struct {
1173 name string
1174 sdkVersion string
1175 platformSdkInt int
1176 platformSdkCodename string
1177 platformSdkFinal bool
1178 deviceCurrentApiLevelForVendorModules string
1179 expectedMinSdkVersion string
1180 }{
1181 {
1182 name: "current final SDK",
1183 sdkVersion: "current",
1184 platformSdkInt: 29,
1185 platformSdkCodename: "REL",
1186 platformSdkFinal: true,
1187 deviceCurrentApiLevelForVendorModules: "29",
1188 expectedMinSdkVersion: "29",
1189 },
1190 {
1191 name: "current final SDK",
1192 sdkVersion: "current",
1193 platformSdkInt: 29,
1194 platformSdkCodename: "REL",
1195 platformSdkFinal: true,
1196 deviceCurrentApiLevelForVendorModules: "28",
1197 expectedMinSdkVersion: "28",
1198 },
1199 {
1200 name: "current final SDK",
1201 sdkVersion: "current",
1202 platformSdkInt: 29,
1203 platformSdkCodename: "Q",
1204 platformSdkFinal: false,
Jeongik Cha219141c2020-08-06 23:00:37 +09001205 deviceCurrentApiLevelForVendorModules: "28",
1206 expectedMinSdkVersion: "28",
1207 },
1208 }
1209
1210 for _, moduleType := range []string{"android_app", "android_library"} {
1211 for _, sdkKind := range []string{"", "system_"} {
1212 for _, test := range testCases {
1213 t.Run(moduleType+" "+test.name, func(t *testing.T) {
1214 bp := fmt.Sprintf(`%s {
1215 name: "foo",
1216 srcs: ["a.java"],
1217 sdk_version: "%s%s",
1218 vendor: true,
1219 }`, moduleType, sdkKind, test.sdkVersion)
1220
1221 config := testAppConfig(nil, bp, nil)
1222 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
1223 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
1224 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
1225 config.TestProductVariables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
1226 config.TestProductVariables.DeviceSystemSdkVersions = []string{"28", "29"}
1227 checkSdkVersion(t, config, test.expectedMinSdkVersion)
1228 })
1229 }
1230 }
1231 }
1232}
1233
Paul Duffin50c217c2019-06-12 13:25:22 +01001234func TestJNIABI(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001235 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001236 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001237 cc_library {
1238 name: "libjni",
1239 system_shared_libs: [],
Colin Crossc511bc52020-04-07 16:50:32 +00001240 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001241 stl: "none",
1242 }
1243
1244 android_test {
1245 name: "test",
1246 sdk_version: "core_platform",
1247 jni_libs: ["libjni"],
1248 }
1249
1250 android_test {
1251 name: "test_first",
1252 sdk_version: "core_platform",
1253 compile_multilib: "first",
1254 jni_libs: ["libjni"],
1255 }
1256
1257 android_test {
1258 name: "test_both",
1259 sdk_version: "core_platform",
1260 compile_multilib: "both",
1261 jni_libs: ["libjni"],
1262 }
1263
1264 android_test {
1265 name: "test_32",
1266 sdk_version: "core_platform",
1267 compile_multilib: "32",
1268 jni_libs: ["libjni"],
1269 }
1270
1271 android_test {
1272 name: "test_64",
1273 sdk_version: "core_platform",
1274 compile_multilib: "64",
1275 jni_libs: ["libjni"],
1276 }
1277 `)
1278
1279 testCases := []struct {
1280 name string
1281 abis []string
1282 }{
1283 {"test", []string{"arm64-v8a"}},
1284 {"test_first", []string{"arm64-v8a"}},
1285 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
1286 {"test_32", []string{"armeabi-v7a"}},
1287 {"test_64", []string{"arm64-v8a"}},
1288 }
1289
1290 for _, test := range testCases {
1291 t.Run(test.name, func(t *testing.T) {
1292 app := ctx.ModuleForTests(test.name, "android_common")
1293 jniLibZip := app.Output("jnilibs.zip")
1294 var abis []string
1295 args := strings.Fields(jniLibZip.Args["jarArgs"])
1296 for i := 0; i < len(args); i++ {
1297 if args[i] == "-P" {
1298 abis = append(abis, filepath.Base(args[i+1]))
1299 i++
1300 }
1301 }
1302 if !reflect.DeepEqual(abis, test.abis) {
1303 t.Errorf("want abis %v, got %v", test.abis, abis)
1304 }
1305 })
1306 }
1307}
1308
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001309func TestAppSdkVersionByPartition(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001310 t.Parallel()
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001311 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
1312 android_app {
1313 name: "foo",
1314 srcs: ["a.java"],
1315 vendor: true,
1316 platform_apis: true,
1317 }
1318 `)
1319
1320 testJava(t, `
1321 android_app {
1322 name: "bar",
1323 srcs: ["b.java"],
1324 platform_apis: true,
1325 }
1326 `)
1327
1328 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001329 bp := `
1330 android_app {
1331 name: "foo",
1332 srcs: ["a.java"],
1333 product_specific: true,
1334 platform_apis: true,
1335 }
1336 `
Colin Cross98be1bb2019-12-13 20:41:13 -08001337
1338 config := testAppConfig(nil, bp, nil)
1339 config.TestProductVariables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001340 if enforce {
Colin Cross98be1bb2019-12-13 20:41:13 -08001341 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 +09001342 } else {
Colin Cross98be1bb2019-12-13 20:41:13 -08001343 testJavaWithConfig(t, config)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09001344 }
1345 }
1346}
1347
Paul Duffin50c217c2019-06-12 13:25:22 +01001348func TestJNIPackaging(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001349 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001350 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001351 cc_library {
1352 name: "libjni",
1353 system_shared_libs: [],
1354 stl: "none",
Colin Cross094cde42020-02-15 10:38:00 -08001355 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001356 }
1357
1358 android_app {
1359 name: "app",
1360 jni_libs: ["libjni"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001361 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001362 }
1363
1364 android_app {
1365 name: "app_noembed",
1366 jni_libs: ["libjni"],
1367 use_embedded_native_libs: false,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001368 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001369 }
1370
1371 android_app {
1372 name: "app_embed",
1373 jni_libs: ["libjni"],
1374 use_embedded_native_libs: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09001375 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001376 }
1377
1378 android_test {
1379 name: "test",
Colin Crossc511bc52020-04-07 16:50:32 +00001380 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001381 jni_libs: ["libjni"],
1382 }
1383
1384 android_test {
1385 name: "test_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00001386 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001387 jni_libs: ["libjni"],
1388 use_embedded_native_libs: false,
1389 }
1390
1391 android_test_helper_app {
1392 name: "test_helper",
Colin Crossc511bc52020-04-07 16:50:32 +00001393 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001394 jni_libs: ["libjni"],
1395 }
1396
1397 android_test_helper_app {
1398 name: "test_helper_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00001399 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001400 jni_libs: ["libjni"],
1401 use_embedded_native_libs: false,
1402 }
1403 `)
1404
1405 testCases := []struct {
1406 name string
1407 packaged bool
1408 compressed bool
1409 }{
1410 {"app", false, false},
1411 {"app_noembed", false, false},
1412 {"app_embed", true, false},
1413 {"test", true, false},
1414 {"test_noembed", true, true},
1415 {"test_helper", true, false},
1416 {"test_helper_noembed", true, true},
1417 }
1418
1419 for _, test := range testCases {
1420 t.Run(test.name, func(t *testing.T) {
1421 app := ctx.ModuleForTests(test.name, "android_common")
1422 jniLibZip := app.MaybeOutput("jnilibs.zip")
1423 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
1424 t.Errorf("expected jni packaged %v, got %v", w, g)
1425 }
1426
1427 if jniLibZip.Rule != nil {
1428 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
1429 t.Errorf("expected jni compressed %v, got %v", w, g)
1430 }
Colin Crossc511bc52020-04-07 16:50:32 +00001431
1432 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
1433 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
1434 }
Paul Duffin50c217c2019-06-12 13:25:22 +01001435 }
1436 })
1437 }
Colin Cross47fa9d32019-03-26 10:51:39 -07001438}
1439
Colin Cross3c007702020-05-08 11:20:24 -07001440func TestJNISDK(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001441 t.Parallel()
Colin Cross3c007702020-05-08 11:20:24 -07001442 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
1443 cc_library {
1444 name: "libjni",
1445 system_shared_libs: [],
1446 stl: "none",
1447 sdk_version: "current",
1448 }
1449
1450 android_test {
1451 name: "app_platform",
1452 jni_libs: ["libjni"],
1453 platform_apis: true,
1454 }
1455
1456 android_test {
1457 name: "app_sdk",
1458 jni_libs: ["libjni"],
1459 sdk_version: "current",
1460 }
1461
1462 android_test {
1463 name: "app_force_platform",
1464 jni_libs: ["libjni"],
1465 sdk_version: "current",
1466 jni_uses_platform_apis: true,
1467 }
1468
1469 android_test {
1470 name: "app_force_sdk",
1471 jni_libs: ["libjni"],
1472 platform_apis: true,
1473 jni_uses_sdk_apis: true,
1474 }
Colin Crossc2d24052020-05-13 11:05:02 -07001475
1476 cc_library {
1477 name: "libvendorjni",
1478 system_shared_libs: [],
1479 stl: "none",
1480 vendor: true,
1481 }
1482
1483 android_test {
1484 name: "app_vendor",
1485 jni_libs: ["libvendorjni"],
1486 sdk_version: "current",
1487 vendor: true,
1488 }
Colin Cross3c007702020-05-08 11:20:24 -07001489 `)
1490
1491 testCases := []struct {
Colin Crossc2d24052020-05-13 11:05:02 -07001492 name string
1493 sdkJNI bool
1494 vendorJNI bool
Colin Cross3c007702020-05-08 11:20:24 -07001495 }{
Colin Crossc2d24052020-05-13 11:05:02 -07001496 {name: "app_platform"},
1497 {name: "app_sdk", sdkJNI: true},
1498 {name: "app_force_platform"},
1499 {name: "app_force_sdk", sdkJNI: true},
1500 {name: "app_vendor", vendorJNI: true},
Colin Cross3c007702020-05-08 11:20:24 -07001501 }
1502
Colin Crossc2d24052020-05-13 11:05:02 -07001503 platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared").
1504 Output("libjni.so").Output.String()
1505 sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
1506 Output("libjni.so").Output.String()
1507 vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared").
1508 Output("libvendorjni.so").Output.String()
1509
Colin Cross3c007702020-05-08 11:20:24 -07001510 for _, test := range testCases {
1511 t.Run(test.name, func(t *testing.T) {
1512 app := ctx.ModuleForTests(test.name, "android_common")
Colin Cross3c007702020-05-08 11:20:24 -07001513
1514 jniLibZip := app.MaybeOutput("jnilibs.zip")
1515 if len(jniLibZip.Implicits) != 1 {
1516 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
1517 }
1518 gotJNI := jniLibZip.Implicits[0].String()
1519
1520 if test.sdkJNI {
1521 if gotJNI != sdkJNI {
1522 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI)
1523 }
Colin Crossc2d24052020-05-13 11:05:02 -07001524 } else if test.vendorJNI {
1525 if gotJNI != vendorJNI {
1526 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI)
1527 }
Colin Cross3c007702020-05-08 11:20:24 -07001528 } else {
1529 if gotJNI != platformJNI {
1530 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI)
1531 }
1532 }
1533 })
1534 }
1535
1536 t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
1537 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
1538 android_test {
1539 name: "app_platform",
1540 platform_apis: true,
1541 jni_uses_platform_apis: true,
1542 }
1543 `)
1544 })
1545
1546 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
1547 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
1548 android_test {
1549 name: "app_sdk",
1550 sdk_version: "current",
1551 jni_uses_sdk_apis: true,
1552 }
1553 `)
1554 })
1555
1556}
1557
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001558func TestCertificates(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001559 t.Parallel()
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001560 testCases := []struct {
1561 name string
1562 bp string
1563 certificateOverride string
Liz Kammere2b27f42020-05-07 13:24:05 -07001564 expectedLineage string
1565 expectedCertificate string
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001566 }{
1567 {
1568 name: "default",
1569 bp: `
1570 android_app {
1571 name: "foo",
1572 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001573 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001574 }
1575 `,
1576 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001577 expectedLineage: "",
1578 expectedCertificate: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001579 },
1580 {
1581 name: "module certificate property",
1582 bp: `
1583 android_app {
1584 name: "foo",
1585 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001586 certificate: ":new_certificate",
1587 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001588 }
1589
1590 android_app_certificate {
1591 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07001592 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001593 }
1594 `,
1595 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001596 expectedLineage: "",
1597 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001598 },
1599 {
1600 name: "path certificate property",
1601 bp: `
1602 android_app {
1603 name: "foo",
1604 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001605 certificate: "expiredkey",
1606 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001607 }
1608 `,
1609 certificateOverride: "",
Liz Kammere2b27f42020-05-07 13:24:05 -07001610 expectedLineage: "",
1611 expectedCertificate: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001612 },
1613 {
1614 name: "certificate overrides",
1615 bp: `
1616 android_app {
1617 name: "foo",
1618 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001619 certificate: "expiredkey",
1620 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001621 }
1622
1623 android_app_certificate {
1624 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07001625 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001626 }
1627 `,
1628 certificateOverride: "foo:new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07001629 expectedLineage: "",
1630 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
1631 },
1632 {
1633 name: "certificate lineage",
1634 bp: `
1635 android_app {
1636 name: "foo",
1637 srcs: ["a.java"],
1638 certificate: ":new_certificate",
1639 lineage: "lineage.bin",
1640 sdk_version: "current",
1641 }
1642
1643 android_app_certificate {
1644 name: "new_certificate",
1645 certificate: "cert/new_cert",
1646 }
1647 `,
1648 certificateOverride: "",
1649 expectedLineage: "--lineage lineage.bin",
1650 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001651 },
1652 }
1653
1654 for _, test := range testCases {
1655 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001656 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001657 if test.certificateOverride != "" {
1658 config.TestProductVariables.CertificateOverrides = []string{test.certificateOverride}
1659 }
Colin Cross98be1bb2019-12-13 20:41:13 -08001660 ctx := testContext()
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001661
1662 run(t, ctx, config)
1663 foo := ctx.ModuleForTests("foo", "android_common")
1664
1665 signapk := foo.Output("foo.apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07001666 signCertificateFlags := signapk.Args["certificates"]
1667 if test.expectedCertificate != signCertificateFlags {
1668 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedCertificate, signCertificateFlags)
1669 }
1670
1671 signFlags := signapk.Args["flags"]
1672 if test.expectedLineage != signFlags {
1673 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expectedLineage, signFlags)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001674 }
1675 })
1676 }
1677}
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001678
Songchun Fan688de9a2020-03-24 20:32:24 -07001679func TestRequestV4SigningFlag(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001680 t.Parallel()
Songchun Fan688de9a2020-03-24 20:32:24 -07001681 testCases := []struct {
1682 name string
1683 bp string
1684 expected string
1685 }{
1686 {
1687 name: "default",
1688 bp: `
1689 android_app {
1690 name: "foo",
1691 srcs: ["a.java"],
1692 sdk_version: "current",
1693 }
1694 `,
1695 expected: "",
1696 },
1697 {
1698 name: "default",
1699 bp: `
1700 android_app {
1701 name: "foo",
1702 srcs: ["a.java"],
1703 sdk_version: "current",
1704 v4_signature: false,
1705 }
1706 `,
1707 expected: "",
1708 },
1709 {
1710 name: "module certificate property",
1711 bp: `
1712 android_app {
1713 name: "foo",
1714 srcs: ["a.java"],
1715 sdk_version: "current",
1716 v4_signature: true,
1717 }
1718 `,
1719 expected: "--enable-v4",
1720 },
1721 }
1722
1723 for _, test := range testCases {
1724 t.Run(test.name, func(t *testing.T) {
1725 config := testAppConfig(nil, test.bp, nil)
1726 ctx := testContext()
1727
1728 run(t, ctx, config)
1729 foo := ctx.ModuleForTests("foo", "android_common")
1730
1731 signapk := foo.Output("foo.apk")
1732 signFlags := signapk.Args["flags"]
1733 if test.expected != signFlags {
1734 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
1735 }
1736 })
1737 }
1738}
1739
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001740func TestPackageNameOverride(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001741 t.Parallel()
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001742 testCases := []struct {
1743 name string
1744 bp string
1745 packageNameOverride string
1746 expected []string
1747 }{
1748 {
1749 name: "default",
1750 bp: `
1751 android_app {
1752 name: "foo",
1753 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001754 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001755 }
1756 `,
1757 packageNameOverride: "",
1758 expected: []string{
1759 buildDir + "/.intermediates/foo/android_common/foo.apk",
1760 buildDir + "/target/product/test_device/system/app/foo/foo.apk",
1761 },
1762 },
1763 {
1764 name: "overridden",
1765 bp: `
1766 android_app {
1767 name: "foo",
1768 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001769 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001770 }
1771 `,
1772 packageNameOverride: "foo:bar",
1773 expected: []string{
1774 // The package apk should be still be the original name for test dependencies.
Jaewoong Jung5a498812019-11-07 14:14:38 -08001775 buildDir + "/.intermediates/foo/android_common/bar.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001776 buildDir + "/target/product/test_device/system/app/bar/bar.apk",
1777 },
1778 },
1779 }
1780
1781 for _, test := range testCases {
1782 t.Run(test.name, func(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -08001783 config := testAppConfig(nil, test.bp, nil)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001784 if test.packageNameOverride != "" {
1785 config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
1786 }
Colin Cross98be1bb2019-12-13 20:41:13 -08001787 ctx := testContext()
Jaewoong Jung9d22a912019-01-23 16:27:47 -08001788
1789 run(t, ctx, config)
1790 foo := ctx.ModuleForTests("foo", "android_common")
1791
1792 outputs := foo.AllOutputs()
1793 outputMap := make(map[string]bool)
1794 for _, o := range outputs {
1795 outputMap[o] = true
1796 }
1797 for _, e := range test.expected {
1798 if _, exist := outputMap[e]; !exist {
1799 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
1800 }
1801 }
1802 })
1803 }
1804}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001805
1806func TestInstrumentationTargetOverridden(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001807 t.Parallel()
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001808 bp := `
1809 android_app {
1810 name: "foo",
1811 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001812 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001813 }
1814
1815 android_test {
1816 name: "bar",
1817 instrumentation_for: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001818 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001819 }
1820 `
Colin Cross98be1bb2019-12-13 20:41:13 -08001821 config := testAppConfig(nil, bp, nil)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001822 config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
Colin Cross98be1bb2019-12-13 20:41:13 -08001823 ctx := testContext()
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001824
1825 run(t, ctx, config)
1826
1827 bar := ctx.ModuleForTests("bar", "android_common")
1828 res := bar.Output("package-res.apk")
1829 aapt2Flags := res.Args["flags"]
1830 e := "--rename-instrumentation-target-package org.dandroid.bp"
1831 if !strings.Contains(aapt2Flags, e) {
1832 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
1833 }
1834}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001835
1836func TestOverrideAndroidApp(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07001837 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001838 ctx, _ := testJava(t, `
Jaewoong Jung525443a2019-02-28 15:35:54 -08001839 android_app {
1840 name: "foo",
1841 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -07001842 certificate: "expiredkey",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001843 overrides: ["qux"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09001844 sdk_version: "current",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001845 }
1846
1847 override_android_app {
1848 name: "bar",
1849 base: "foo",
1850 certificate: ":new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07001851 lineage: "lineage.bin",
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08001852 logging_parent: "bah",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001853 }
1854
1855 android_app_certificate {
1856 name: "new_certificate",
1857 certificate: "cert/new_cert",
1858 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001859
1860 override_android_app {
1861 name: "baz",
1862 base: "foo",
1863 package_name: "org.dandroid.bp",
1864 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00001865
1866 override_android_app {
1867 name: "baz_no_rename_resources",
1868 base: "foo",
1869 package_name: "org.dandroid.bp",
1870 rename_resources_package: false,
1871 }
1872
1873 android_app {
1874 name: "foo_no_rename_resources",
1875 srcs: ["a.java"],
1876 certificate: "expiredkey",
1877 overrides: ["qux"],
1878 rename_resources_package: false,
1879 sdk_version: "current",
1880 }
1881
1882 override_android_app {
1883 name: "baz_base_no_rename_resources",
1884 base: "foo_no_rename_resources",
1885 package_name: "org.dandroid.bp",
1886 }
1887
1888 override_android_app {
1889 name: "baz_override_base_rename_resources",
1890 base: "foo_no_rename_resources",
1891 package_name: "org.dandroid.bp",
1892 rename_resources_package: true,
1893 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001894 `)
1895
1896 expectedVariants := []struct {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001897 name string
1898 moduleName string
1899 variantName string
1900 apkName string
1901 apkPath string
1902 certFlag string
1903 lineageFlag string
1904 overrides []string
1905 packageFlag string
1906 renameResources bool
1907 logging_parent string
Jaewoong Jung525443a2019-02-28 15:35:54 -08001908 }{
1909 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001910 name: "foo",
1911 moduleName: "foo",
1912 variantName: "android_common",
1913 apkPath: "/target/product/test_device/system/app/foo/foo.apk",
1914 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1915 lineageFlag: "",
1916 overrides: []string{"qux"},
1917 packageFlag: "",
1918 renameResources: false,
1919 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001920 },
1921 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001922 name: "foo",
1923 moduleName: "bar",
1924 variantName: "android_common_bar",
1925 apkPath: "/target/product/test_device/system/app/bar/bar.apk",
1926 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
1927 lineageFlag: "--lineage lineage.bin",
1928 overrides: []string{"qux", "foo"},
1929 packageFlag: "",
1930 renameResources: false,
1931 logging_parent: "bah",
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001932 },
1933 {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001934 name: "foo",
1935 moduleName: "baz",
1936 variantName: "android_common_baz",
1937 apkPath: "/target/product/test_device/system/app/baz/baz.apk",
1938 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1939 lineageFlag: "",
1940 overrides: []string{"qux", "foo"},
1941 packageFlag: "org.dandroid.bp",
1942 renameResources: true,
1943 logging_parent: "",
1944 },
1945 {
1946 name: "foo",
1947 moduleName: "baz_no_rename_resources",
1948 variantName: "android_common_baz_no_rename_resources",
1949 apkPath: "/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
1950 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1951 lineageFlag: "",
1952 overrides: []string{"qux", "foo"},
1953 packageFlag: "org.dandroid.bp",
1954 renameResources: false,
1955 logging_parent: "",
1956 },
1957 {
1958 name: "foo_no_rename_resources",
1959 moduleName: "baz_base_no_rename_resources",
1960 variantName: "android_common_baz_base_no_rename_resources",
1961 apkPath: "/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
1962 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1963 lineageFlag: "",
1964 overrides: []string{"qux", "foo_no_rename_resources"},
1965 packageFlag: "org.dandroid.bp",
1966 renameResources: false,
1967 logging_parent: "",
1968 },
1969 {
1970 name: "foo_no_rename_resources",
1971 moduleName: "baz_override_base_rename_resources",
1972 variantName: "android_common_baz_override_base_rename_resources",
1973 apkPath: "/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
1974 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1975 lineageFlag: "",
1976 overrides: []string{"qux", "foo_no_rename_resources"},
1977 packageFlag: "org.dandroid.bp",
1978 renameResources: true,
1979 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001980 },
1981 }
1982 for _, expected := range expectedVariants {
Liz Kammer9f9fd022020-06-18 19:44:06 +00001983 variant := ctx.ModuleForTests(expected.name, expected.variantName)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001984
1985 // Check the final apk name
1986 outputs := variant.AllOutputs()
1987 expectedApkPath := buildDir + expected.apkPath
1988 found := false
1989 for _, o := range outputs {
1990 if o == expectedApkPath {
1991 found = true
1992 break
1993 }
1994 }
1995 if !found {
1996 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
1997 }
1998
1999 // Check the certificate paths
Jaewoong Jung5a498812019-11-07 14:14:38 -08002000 signapk := variant.Output(expected.moduleName + ".apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07002001 certFlag := signapk.Args["certificates"]
2002 if expected.certFlag != certFlag {
2003 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.certFlag, certFlag)
2004 }
2005
2006 // Check the lineage flags
2007 lineageFlag := signapk.Args["flags"]
2008 if expected.lineageFlag != lineageFlag {
2009 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.lineageFlag, lineageFlag)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002010 }
2011
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002012 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -08002013 mod := variant.Module().(*AndroidApp)
2014 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
2015 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
2016 expected.overrides, mod.appProperties.Overrides)
2017 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002018
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08002019 // Test Overridable property: Logging_parent
2020 logging_parent := mod.aapt.LoggingParent
2021 if expected.logging_parent != logging_parent {
2022 t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q",
2023 expected.logging_parent, logging_parent)
2024 }
2025
Liz Kammer1d5983b2020-05-19 19:15:37 +00002026 // Check the package renaming flag, if exists.
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002027 res := variant.Output("package-res.apk")
2028 aapt2Flags := res.Args["flags"]
Liz Kammer9f9fd022020-06-18 19:44:06 +00002029 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
2030 expectedPackage := expected.packageFlag
2031 if !expected.renameResources {
2032 expectedPackage = ""
Liz Kammer1d5983b2020-05-19 19:15:37 +00002033 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00002034 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002035 }
2036}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002037
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002038func TestOverrideAndroidAppDependency(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002039 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002040 ctx, _ := testJava(t, `
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002041 android_app {
2042 name: "foo",
2043 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002044 sdk_version: "current",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002045 }
2046
2047 override_android_app {
2048 name: "bar",
2049 base: "foo",
2050 package_name: "org.dandroid.bp",
2051 }
2052
2053 android_test {
2054 name: "baz",
2055 srcs: ["b.java"],
2056 instrumentation_for: "foo",
2057 }
2058
2059 android_test {
2060 name: "qux",
2061 srcs: ["b.java"],
2062 instrumentation_for: "bar",
2063 }
2064 `)
2065
2066 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
2067 javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
2068 fooTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
2069 if !strings.Contains(javac.Args["classpath"], fooTurbine) {
2070 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
2071 }
2072
2073 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
2074 javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
2075 barTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common_bar", "turbine-combined", "foo.jar")
2076 if !strings.Contains(javac.Args["classpath"], barTurbine) {
2077 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
2078 }
2079}
2080
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002081func TestOverrideAndroidTest(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002082 t.Parallel()
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002083 ctx, _ := testJava(t, `
2084 android_app {
2085 name: "foo",
2086 srcs: ["a.java"],
2087 package_name: "com.android.foo",
2088 sdk_version: "current",
2089 }
2090
2091 override_android_app {
2092 name: "bar",
2093 base: "foo",
2094 package_name: "com.android.bar",
2095 }
2096
2097 android_test {
2098 name: "foo_test",
2099 srcs: ["b.java"],
2100 instrumentation_for: "foo",
2101 }
2102
2103 override_android_test {
2104 name: "bar_test",
2105 base: "foo_test",
2106 package_name: "com.android.bar.test",
2107 instrumentation_for: "bar",
2108 instrumentation_target_package: "com.android.bar",
2109 }
2110 `)
2111
2112 expectedVariants := []struct {
2113 moduleName string
2114 variantName string
2115 apkPath string
2116 overrides []string
2117 targetVariant string
2118 packageFlag string
2119 targetPackageFlag string
2120 }{
2121 {
2122 variantName: "android_common",
Jaewoong Jung326a9412019-11-21 10:41:00 -08002123 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002124 overrides: nil,
2125 targetVariant: "android_common",
2126 packageFlag: "",
2127 targetPackageFlag: "",
2128 },
2129 {
2130 variantName: "android_common_bar_test",
Jaewoong Jung326a9412019-11-21 10:41:00 -08002131 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002132 overrides: []string{"foo_test"},
2133 targetVariant: "android_common_bar",
2134 packageFlag: "com.android.bar.test",
2135 targetPackageFlag: "com.android.bar",
2136 },
2137 }
2138 for _, expected := range expectedVariants {
2139 variant := ctx.ModuleForTests("foo_test", expected.variantName)
2140
2141 // Check the final apk name
2142 outputs := variant.AllOutputs()
2143 expectedApkPath := buildDir + expected.apkPath
2144 found := false
2145 for _, o := range outputs {
2146 if o == expectedApkPath {
2147 found = true
2148 break
2149 }
2150 }
2151 if !found {
2152 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
2153 }
2154
2155 // Check if the overrides field values are correctly aggregated.
2156 mod := variant.Module().(*AndroidTest)
2157 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
2158 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
2159 expected.overrides, mod.appProperties.Overrides)
2160 }
2161
2162 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
2163 javac := variant.Rule("javac")
2164 turbine := filepath.Join(buildDir, ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
2165 if !strings.Contains(javac.Args["classpath"], turbine) {
2166 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
2167 }
2168
2169 // Check aapt2 flags.
2170 res := variant.Output("package-res.apk")
2171 aapt2Flags := res.Args["flags"]
2172 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
Liz Kammer9f9fd022020-06-18 19:44:06 +00002173 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07002174 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
2175 }
2176}
2177
Jaewoong Jung39982342020-01-14 10:27:18 -08002178func TestAndroidTest_FixTestConfig(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002179 t.Parallel()
Jaewoong Jung39982342020-01-14 10:27:18 -08002180 ctx, _ := testJava(t, `
2181 android_app {
2182 name: "foo",
2183 srcs: ["a.java"],
2184 package_name: "com.android.foo",
2185 sdk_version: "current",
2186 }
2187
2188 android_test {
2189 name: "foo_test",
2190 srcs: ["b.java"],
2191 instrumentation_for: "foo",
2192 }
2193
2194 android_test {
2195 name: "bar_test",
2196 srcs: ["b.java"],
2197 package_name: "com.android.bar.test",
2198 instrumentation_for: "foo",
2199 }
2200
2201 override_android_test {
2202 name: "baz_test",
2203 base: "foo_test",
2204 package_name: "com.android.baz.test",
2205 }
2206 `)
2207
2208 testCases := []struct {
2209 moduleName string
2210 variantName string
2211 expectedFlags []string
2212 }{
2213 {
2214 moduleName: "foo_test",
2215 variantName: "android_common",
2216 },
2217 {
2218 moduleName: "bar_test",
2219 variantName: "android_common",
2220 expectedFlags: []string{
2221 "--manifest " + buildDir + "/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
2222 "--package-name com.android.bar.test",
2223 },
2224 },
2225 {
2226 moduleName: "foo_test",
2227 variantName: "android_common_baz_test",
2228 expectedFlags: []string{
2229 "--manifest " + buildDir +
2230 "/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
2231 "--package-name com.android.baz.test",
2232 "--test-file-name baz_test.apk",
2233 },
2234 },
2235 }
2236
2237 for _, test := range testCases {
2238 variant := ctx.ModuleForTests(test.moduleName, test.variantName)
2239 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
2240
2241 if len(test.expectedFlags) > 0 {
2242 if params.Rule == nil {
2243 t.Errorf("test_config_fixer was expected to run, but didn't")
2244 } else {
2245 for _, flag := range test.expectedFlags {
2246 if !strings.Contains(params.RuleParams.Command, flag) {
2247 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
2248 }
2249 }
2250 }
2251 } else {
2252 if params.Rule != nil {
2253 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
2254 }
2255 }
2256
2257 }
2258}
2259
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002260func TestAndroidAppImport(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002261 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002262 ctx, _ := testJava(t, `
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002263 android_app_import {
2264 name: "foo",
2265 apk: "prebuilts/apk/app.apk",
2266 certificate: "platform",
2267 dex_preopt: {
2268 enabled: true,
2269 },
2270 }
2271 `)
2272
2273 variant := ctx.ModuleForTests("foo", "android_common")
2274
2275 // Check dexpreopt outputs.
2276 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
2277 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
2278 t.Errorf("can't find dexpreopt outputs")
2279 }
2280
2281 // Check cert signing flag.
2282 signedApk := variant.Output("signed/foo.apk")
2283 signingFlag := signedApk.Args["certificates"]
2284 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
2285 if expected != signingFlag {
2286 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
2287 }
2288}
2289
2290func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002291 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002292 ctx, _ := testJava(t, `
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002293 android_app_import {
2294 name: "foo",
2295 apk: "prebuilts/apk/app.apk",
2296 certificate: "platform",
2297 dex_preopt: {
2298 enabled: false,
2299 },
2300 }
2301 `)
2302
2303 variant := ctx.ModuleForTests("foo", "android_common")
2304
2305 // Check dexpreopt outputs. They shouldn't exist.
2306 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
2307 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
2308 t.Errorf("dexpreopt shouldn't have run.")
2309 }
2310}
2311
2312func TestAndroidAppImport_Presigned(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002313 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002314 ctx, _ := testJava(t, `
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002315 android_app_import {
2316 name: "foo",
2317 apk: "prebuilts/apk/app.apk",
2318 presigned: true,
2319 dex_preopt: {
2320 enabled: true,
2321 },
2322 }
2323 `)
2324
2325 variant := ctx.ModuleForTests("foo", "android_common")
2326
2327 // Check dexpreopt outputs.
2328 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
2329 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
2330 t.Errorf("can't find dexpreopt outputs")
2331 }
Nicolas Geoffrayc1bf7242019-10-18 14:51:38 +01002332 // Make sure signing was skipped and aligning was done.
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002333 if variant.MaybeOutput("signed/foo.apk").Rule != nil {
2334 t.Errorf("signing rule shouldn't be included.")
2335 }
2336 if variant.MaybeOutput("zip-aligned/foo.apk").Rule == nil {
2337 t.Errorf("can't find aligning rule")
2338 }
2339}
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07002340
Liz Kammer24978992020-05-13 15:49:21 -07002341func TestAndroidAppImport_SigningLineage(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002342 t.Parallel()
Liz Kammer24978992020-05-13 15:49:21 -07002343 ctx, _ := testJava(t, `
2344 android_app_import {
2345 name: "foo",
2346 apk: "prebuilts/apk/app.apk",
2347 certificate: "platform",
2348 lineage: "lineage.bin",
2349 }
2350 `)
2351
2352 variant := ctx.ModuleForTests("foo", "android_common")
2353
2354 // Check cert signing lineage flag.
2355 signedApk := variant.Output("signed/foo.apk")
2356 signingFlag := signedApk.Args["flags"]
2357 expected := "--lineage lineage.bin"
2358 if expected != signingFlag {
2359 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
2360 }
2361}
2362
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07002363func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002364 t.Parallel()
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07002365 ctx, _ := testJava(t, `
2366 android_app_import {
2367 name: "foo",
2368 apk: "prebuilts/apk/app.apk",
2369 default_dev_cert: true,
2370 dex_preopt: {
2371 enabled: true,
2372 },
2373 }
2374 `)
2375
2376 variant := ctx.ModuleForTests("foo", "android_common")
2377
2378 // Check dexpreopt outputs.
2379 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
2380 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
2381 t.Errorf("can't find dexpreopt outputs")
2382 }
2383
2384 // Check cert signing flag.
2385 signedApk := variant.Output("signed/foo.apk")
2386 signingFlag := signedApk.Args["certificates"]
2387 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
2388 if expected != signingFlag {
2389 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
2390 }
2391}
2392
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07002393func TestAndroidAppImport_DpiVariants(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002394 t.Parallel()
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07002395 bp := `
2396 android_app_import {
2397 name: "foo",
2398 apk: "prebuilts/apk/app.apk",
2399 dpi_variants: {
2400 xhdpi: {
2401 apk: "prebuilts/apk/app_xhdpi.apk",
2402 },
2403 xxhdpi: {
2404 apk: "prebuilts/apk/app_xxhdpi.apk",
2405 },
2406 },
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07002407 presigned: true,
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07002408 dex_preopt: {
2409 enabled: true,
2410 },
2411 }
2412 `
2413 testCases := []struct {
2414 name string
2415 aaptPreferredConfig *string
2416 aaptPrebuiltDPI []string
2417 expected string
2418 }{
2419 {
2420 name: "no preferred",
2421 aaptPreferredConfig: nil,
2422 aaptPrebuiltDPI: []string{},
2423 expected: "prebuilts/apk/app.apk",
2424 },
2425 {
2426 name: "AAPTPreferredConfig matches",
2427 aaptPreferredConfig: proptools.StringPtr("xhdpi"),
Jaewoong Jung3e18b192019-06-11 12:25:34 -07002428 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07002429 expected: "prebuilts/apk/app_xhdpi.apk",
2430 },
2431 {
2432 name: "AAPTPrebuiltDPI matches",
2433 aaptPreferredConfig: proptools.StringPtr("mdpi"),
2434 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
2435 expected: "prebuilts/apk/app_xxhdpi.apk",
2436 },
2437 {
2438 name: "non-first AAPTPrebuiltDPI matches",
2439 aaptPreferredConfig: proptools.StringPtr("mdpi"),
2440 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
2441 expected: "prebuilts/apk/app_xhdpi.apk",
2442 },
2443 {
2444 name: "no matches",
2445 aaptPreferredConfig: proptools.StringPtr("mdpi"),
2446 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
2447 expected: "prebuilts/apk/app.apk",
2448 },
2449 }
2450
2451 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
2452 for _, test := range testCases {
Colin Cross98be1bb2019-12-13 20:41:13 -08002453 config := testAppConfig(nil, bp, nil)
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07002454 config.TestProductVariables.AAPTPreferredConfig = test.aaptPreferredConfig
2455 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
Colin Cross98be1bb2019-12-13 20:41:13 -08002456 ctx := testContext()
Jaewoong Junga5e5abc2019-04-26 14:31:50 -07002457
2458 run(t, ctx, config)
2459
2460 variant := ctx.ModuleForTests("foo", "android_common")
2461 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
2462 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
2463 if len(matches) != 2 {
2464 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
2465 }
2466 if test.expected != matches[1] {
2467 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
2468 }
2469 }
2470}
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002471
Jaewoong Jung8aae22e2019-07-17 10:21:49 -07002472func TestAndroidAppImport_Filename(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002473 t.Parallel()
Jaewoong Jung8aae22e2019-07-17 10:21:49 -07002474 ctx, config := testJava(t, `
2475 android_app_import {
2476 name: "foo",
2477 apk: "prebuilts/apk/app.apk",
2478 presigned: true,
2479 }
2480
2481 android_app_import {
2482 name: "bar",
2483 apk: "prebuilts/apk/app.apk",
2484 presigned: true,
2485 filename: "bar_sample.apk"
2486 }
2487 `)
2488
2489 testCases := []struct {
2490 name string
2491 expected string
2492 }{
2493 {
2494 name: "foo",
2495 expected: "foo.apk",
2496 },
2497 {
2498 name: "bar",
2499 expected: "bar_sample.apk",
2500 },
2501 }
2502
2503 for _, test := range testCases {
2504 variant := ctx.ModuleForTests(test.name, "android_common")
2505 if variant.MaybeOutput(test.expected).Rule == nil {
2506 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
2507 }
2508
2509 a := variant.Module().(*AndroidAppImport)
2510 expectedValues := []string{test.expected}
2511 actualValues := android.AndroidMkEntriesForTest(
Jiyong Park0b0e1b92019-12-03 13:24:29 +09002512 t, config, "", a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
Jaewoong Jung8aae22e2019-07-17 10:21:49 -07002513 if !reflect.DeepEqual(actualValues, expectedValues) {
2514 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
2515 actualValues, expectedValues)
2516 }
2517 }
2518}
2519
Jaewoong Jung1ce9ac62019-08-13 14:11:33 -07002520func TestAndroidAppImport_ArchVariants(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002521 t.Parallel()
Jaewoong Jung1ce9ac62019-08-13 14:11:33 -07002522 // The test config's target arch is ARM64.
2523 testCases := []struct {
2524 name string
2525 bp string
2526 expected string
2527 }{
2528 {
2529 name: "matching arch",
2530 bp: `
2531 android_app_import {
2532 name: "foo",
2533 apk: "prebuilts/apk/app.apk",
2534 arch: {
2535 arm64: {
2536 apk: "prebuilts/apk/app_arm64.apk",
2537 },
2538 },
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07002539 presigned: true,
Jaewoong Jung1ce9ac62019-08-13 14:11:33 -07002540 dex_preopt: {
2541 enabled: true,
2542 },
2543 }
2544 `,
2545 expected: "prebuilts/apk/app_arm64.apk",
2546 },
2547 {
2548 name: "no matching arch",
2549 bp: `
2550 android_app_import {
2551 name: "foo",
2552 apk: "prebuilts/apk/app.apk",
2553 arch: {
2554 arm: {
2555 apk: "prebuilts/apk/app_arm.apk",
2556 },
2557 },
Jaewoong Jung961d4fd2019-08-22 14:25:58 -07002558 presigned: true,
Jaewoong Jung1ce9ac62019-08-13 14:11:33 -07002559 dex_preopt: {
2560 enabled: true,
2561 },
2562 }
2563 `,
2564 expected: "prebuilts/apk/app.apk",
2565 },
2566 }
2567
2568 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
2569 for _, test := range testCases {
2570 ctx, _ := testJava(t, test.bp)
2571
2572 variant := ctx.ModuleForTests("foo", "android_common")
2573 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
2574 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
2575 if len(matches) != 2 {
2576 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
2577 }
2578 if test.expected != matches[1] {
2579 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
2580 }
2581 }
2582}
2583
Jaewoong Jungb28eb5f2019-08-27 15:01:50 -07002584func TestAndroidTestImport(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002585 t.Parallel()
Jaewoong Jungb28eb5f2019-08-27 15:01:50 -07002586 ctx, config := testJava(t, `
2587 android_test_import {
2588 name: "foo",
2589 apk: "prebuilts/apk/app.apk",
2590 presigned: true,
2591 data: [
2592 "testdata/data",
2593 ],
2594 }
2595 `)
2596
2597 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
2598
2599 // Check android mks.
Jiyong Park0b0e1b92019-12-03 13:24:29 +09002600 entries := android.AndroidMkEntriesForTest(t, config, "", test)[0]
Jaewoong Jungb28eb5f2019-08-27 15:01:50 -07002601 expected := []string{"tests"}
2602 actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
2603 if !reflect.DeepEqual(expected, actual) {
2604 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
2605 }
2606 expected = []string{"testdata/data:testdata/data"}
2607 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
2608 if !reflect.DeepEqual(expected, actual) {
2609 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
2610 }
2611}
2612
Jaewoong Jung7c5bd832020-01-13 09:55:39 -08002613func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002614 t.Parallel()
Jaewoong Jung7c5bd832020-01-13 09:55:39 -08002615 ctx, _ := testJava(t, `
2616 android_test_import {
2617 name: "foo",
2618 apk: "prebuilts/apk/app.apk",
2619 certificate: "cert/new_cert",
2620 data: [
2621 "testdata/data",
2622 ],
2623 }
2624
2625 android_test_import {
2626 name: "foo_presigned",
2627 apk: "prebuilts/apk/app.apk",
2628 presigned: true,
2629 data: [
2630 "testdata/data",
2631 ],
2632 }
2633 `)
2634
2635 variant := ctx.ModuleForTests("foo", "android_common")
2636 jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
2637 if !strings.HasPrefix(jniRule, "if (zipinfo") {
2638 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
2639 }
2640
2641 variant = ctx.ModuleForTests("foo_presigned", "android_common")
2642 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
2643 if jniRule != android.Cp.String() {
2644 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
2645 }
Liz Kammer3b70b3f2020-05-20 14:36:30 -07002646 if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
2647 t.Errorf("Presigned test apk should be aligned")
2648 }
2649}
2650
2651func TestAndroidTestImport_Preprocessed(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002652 t.Parallel()
Liz Kammer3b70b3f2020-05-20 14:36:30 -07002653 ctx, _ := testJava(t, `
2654 android_test_import {
2655 name: "foo",
2656 apk: "prebuilts/apk/app.apk",
2657 presigned: true,
2658 preprocessed: true,
2659 }
2660
2661 android_test_import {
2662 name: "foo_cert",
2663 apk: "prebuilts/apk/app.apk",
2664 certificate: "cert/new_cert",
2665 preprocessed: true,
2666 }
2667 `)
2668
2669 testModules := []string{"foo", "foo_cert"}
2670 for _, m := range testModules {
2671 apkName := m + ".apk"
2672 variant := ctx.ModuleForTests(m, "android_common")
2673 jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
2674 if jniRule != android.Cp.String() {
2675 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
2676 }
2677
2678 // Make sure signing and aligning were skipped.
2679 if variant.MaybeOutput("signed/"+apkName).Rule != nil {
2680 t.Errorf("signing rule shouldn't be included for preprocessed.")
2681 }
2682 if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
2683 t.Errorf("aligning rule shouldn't be for preprocessed")
2684 }
2685 }
Jaewoong Jung7c5bd832020-01-13 09:55:39 -08002686}
2687
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002688func TestStl(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002689 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002690 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002691 cc_library {
2692 name: "libjni",
Peter Collingbournead84f972019-12-17 16:46:18 -08002693 sdk_version: "current",
2694 stl: "c++_shared",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002695 }
2696
2697 android_test {
2698 name: "stl",
2699 jni_libs: ["libjni"],
2700 compile_multilib: "both",
2701 sdk_version: "current",
2702 stl: "c++_shared",
2703 }
2704
2705 android_test {
2706 name: "system",
2707 jni_libs: ["libjni"],
2708 compile_multilib: "both",
2709 sdk_version: "current",
2710 }
2711 `)
2712
2713 testCases := []struct {
2714 name string
2715 jnis []string
2716 }{
2717 {"stl",
2718 []string{
2719 "libjni.so",
Jaewoong Jung710756a2019-06-04 11:53:47 -07002720 "libc++_shared.so",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07002721 },
2722 },
2723 {"system",
2724 []string{
2725 "libjni.so",
2726 },
2727 },
2728 }
2729
2730 for _, test := range testCases {
2731 t.Run(test.name, func(t *testing.T) {
2732 app := ctx.ModuleForTests(test.name, "android_common")
2733 jniLibZip := app.Output("jnilibs.zip")
2734 var jnis []string
2735 args := strings.Fields(jniLibZip.Args["jarArgs"])
2736 for i := 0; i < len(args); i++ {
2737 if args[i] == "-f" {
2738 jnis = append(jnis, args[i+1])
2739 i += 1
2740 }
2741 }
2742 jnisJoined := strings.Join(jnis, " ")
2743 for _, jni := range test.jnis {
2744 if !strings.Contains(jnisJoined, jni) {
2745 t.Errorf("missing jni %q in %q", jni, jnis)
2746 }
2747 }
2748 })
2749 }
2750}
Colin Cross50ddcc42019-05-16 12:28:22 -07002751
2752func TestUsesLibraries(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002753 t.Parallel()
Colin Cross50ddcc42019-05-16 12:28:22 -07002754 bp := `
2755 java_sdk_library {
2756 name: "foo",
2757 srcs: ["a.java"],
2758 api_packages: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002759 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002760 }
2761
2762 java_sdk_library {
Paul Duffin859fe962020-05-15 10:20:31 +01002763 name: "qux",
2764 srcs: ["a.java"],
2765 api_packages: ["qux"],
2766 sdk_version: "current",
2767 }
2768
2769 java_sdk_library {
2770 name: "quuz",
2771 srcs: ["a.java"],
2772 api_packages: ["quuz"],
2773 sdk_version: "current",
2774 }
2775
2776 java_sdk_library {
Colin Cross50ddcc42019-05-16 12:28:22 -07002777 name: "bar",
2778 srcs: ["a.java"],
2779 api_packages: ["bar"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002780 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002781 }
2782
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01002783 java_sdk_library {
2784 name: "runtime-library",
2785 srcs: ["a.java"],
2786 sdk_version: "current",
2787 }
2788
2789 java_library {
2790 name: "static-runtime-helper",
2791 srcs: ["a.java"],
2792 libs: ["runtime-library"],
2793 sdk_version: "current",
2794 }
2795
Colin Cross50ddcc42019-05-16 12:28:22 -07002796 android_app {
2797 name: "app",
2798 srcs: ["a.java"],
Paul Duffin859fe962020-05-15 10:20:31 +01002799 libs: ["qux", "quuz.stubs"],
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01002800 static_libs: ["static-runtime-helper"],
Colin Cross50ddcc42019-05-16 12:28:22 -07002801 uses_libs: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002802 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07002803 optional_uses_libs: [
2804 "bar",
2805 "baz",
2806 ],
2807 }
2808
2809 android_app_import {
2810 name: "prebuilt",
2811 apk: "prebuilts/apk/app.apk",
2812 certificate: "platform",
2813 uses_libs: ["foo"],
2814 optional_uses_libs: [
2815 "bar",
2816 "baz",
2817 ],
2818 }
2819 `
2820
Colin Cross98be1bb2019-12-13 20:41:13 -08002821 config := testAppConfig(nil, bp, nil)
Colin Cross50ddcc42019-05-16 12:28:22 -07002822 config.TestProductVariables.MissingUsesLibraries = []string{"baz"}
2823
Colin Cross98be1bb2019-12-13 20:41:13 -08002824 ctx := testContext()
Colin Cross50ddcc42019-05-16 12:28:22 -07002825
2826 run(t, ctx, config)
2827
2828 app := ctx.ModuleForTests("app", "android_common")
2829 prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
2830
Paul Duffin859fe962020-05-15 10:20:31 +01002831 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
2832 manifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01002833 for _, w := range []string{"qux", "quuz", "runtime-library"} {
2834 if !strings.Contains(manifestFixerArgs, "--uses-library "+w) {
2835 t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
2836 }
Paul Duffin859fe962020-05-15 10:20:31 +01002837 }
2838
Colin Cross50ddcc42019-05-16 12:28:22 -07002839 // Test that all libraries are verified
2840 cmd := app.Rule("verify_uses_libraries").RuleParams.Command
2841 if w := "--uses-library foo"; !strings.Contains(cmd, w) {
2842 t.Errorf("wanted %q in %q", w, cmd)
2843 }
2844
2845 if w := "--optional-uses-library bar --optional-uses-library baz"; !strings.Contains(cmd, w) {
2846 t.Errorf("wanted %q in %q", w, cmd)
2847 }
2848
2849 cmd = prebuilt.Rule("verify_uses_libraries").RuleParams.Command
2850
2851 if w := `uses_library_names="foo"`; !strings.Contains(cmd, w) {
2852 t.Errorf("wanted %q in %q", w, cmd)
2853 }
2854
2855 if w := `optional_uses_library_names="bar baz"`; !strings.Contains(cmd, w) {
2856 t.Errorf("wanted %q in %q", w, cmd)
2857 }
2858
Ulya Trafimovich39b437b2020-09-23 16:42:35 +01002859 // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs
Colin Cross50ddcc42019-05-16 12:28:22 -07002860 cmd = app.Rule("dexpreopt").RuleParams.Command
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002861 w := `--target-classpath-for-sdk any` +
2862 ` /system/framework/foo.jar` +
2863 `:/system/framework/quuz.jar` +
2864 `:/system/framework/qux.jar` +
2865 `:/system/framework/runtime-library.jar` +
2866 `:/system/framework/bar.jar`
2867 if !strings.Contains(cmd, w) {
Colin Cross50ddcc42019-05-16 12:28:22 -07002868 t.Errorf("wanted %q in %q", w, cmd)
2869 }
2870
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002871 cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
Ulya Trafimovich5f364b62020-06-30 12:39:01 +01002872 if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) {
Colin Cross50ddcc42019-05-16 12:28:22 -07002873 t.Errorf("wanted %q in %q", w, cmd)
2874 }
2875}
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002876
2877func TestCodelessApp(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002878 t.Parallel()
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002879 testCases := []struct {
2880 name string
2881 bp string
2882 noCode bool
2883 }{
2884 {
2885 name: "normal",
2886 bp: `
2887 android_app {
2888 name: "foo",
2889 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002890 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002891 }
2892 `,
2893 noCode: false,
2894 },
2895 {
2896 name: "app without sources",
2897 bp: `
2898 android_app {
2899 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002900 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002901 }
2902 `,
2903 noCode: true,
2904 },
2905 {
2906 name: "app with libraries",
2907 bp: `
2908 android_app {
2909 name: "foo",
2910 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002911 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002912 }
2913
2914 java_library {
2915 name: "lib",
2916 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002917 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002918 }
2919 `,
2920 noCode: false,
2921 },
2922 {
2923 name: "app with sourceless libraries",
2924 bp: `
2925 android_app {
2926 name: "foo",
2927 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002928 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002929 }
2930
2931 java_library {
2932 name: "lib",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002933 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07002934 }
2935 `,
2936 // TODO(jungjw): this should probably be true
2937 noCode: false,
2938 },
2939 }
2940
2941 for _, test := range testCases {
2942 t.Run(test.name, func(t *testing.T) {
2943 ctx := testApp(t, test.bp)
2944
2945 foo := ctx.ModuleForTests("foo", "android_common")
2946 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
2947 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
2948 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
2949 }
2950 })
2951 }
2952}
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002953
2954func TestEmbedNotice(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07002955 t.Parallel()
Colin Cross238c1f32020-06-07 16:58:18 -07002956 ctx, _ := testJavaWithFS(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002957 android_app {
2958 name: "foo",
2959 srcs: ["a.java"],
2960 static_libs: ["javalib"],
2961 jni_libs: ["libjni"],
2962 notice: "APP_NOTICE",
2963 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002964 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002965 }
2966
2967 // No embed_notice flag
2968 android_app {
2969 name: "bar",
2970 srcs: ["a.java"],
2971 jni_libs: ["libjni"],
2972 notice: "APP_NOTICE",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002973 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002974 }
2975
2976 // No NOTICE files
2977 android_app {
2978 name: "baz",
2979 srcs: ["a.java"],
2980 embed_notices: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002981 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002982 }
2983
2984 cc_library {
2985 name: "libjni",
2986 system_shared_libs: [],
2987 stl: "none",
2988 notice: "LIB_NOTICE",
Colin Cross094cde42020-02-15 10:38:00 -08002989 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002990 }
2991
2992 java_library {
2993 name: "javalib",
2994 srcs: [
2995 ":gen",
2996 ],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002997 sdk_version: "current",
Jaewoong Jung5b425e22019-06-17 17:40:56 -07002998 }
2999
3000 genrule {
3001 name: "gen",
3002 tools: ["gentool"],
3003 out: ["gen.java"],
3004 notice: "GENRULE_NOTICE",
3005 }
3006
3007 java_binary_host {
3008 name: "gentool",
3009 srcs: ["b.java"],
3010 notice: "TOOL_NOTICE",
3011 }
Colin Cross238c1f32020-06-07 16:58:18 -07003012 `, map[string][]byte{
3013 "APP_NOTICE": nil,
3014 "GENRULE_NOTICE": nil,
3015 "LIB_NOTICE": nil,
3016 "TOOL_NOTICE": nil,
3017 })
Jaewoong Jung5b425e22019-06-17 17:40:56 -07003018
3019 // foo has NOTICE files to process, and embed_notices is true.
3020 foo := ctx.ModuleForTests("foo", "android_common")
3021 // verify merge notices rule.
3022 mergeNotices := foo.Rule("mergeNoticesRule")
3023 noticeInputs := mergeNotices.Inputs.Strings()
3024 // TOOL_NOTICE should be excluded as it's a host module.
3025 if len(mergeNotices.Inputs) != 3 {
3026 t.Errorf("number of input notice files: expected = 3, actual = %q", noticeInputs)
3027 }
3028 if !inList("APP_NOTICE", noticeInputs) {
3029 t.Errorf("APP_NOTICE is missing from notice files, %q", noticeInputs)
3030 }
3031 if !inList("LIB_NOTICE", noticeInputs) {
3032 t.Errorf("LIB_NOTICE is missing from notice files, %q", noticeInputs)
3033 }
3034 if !inList("GENRULE_NOTICE", noticeInputs) {
3035 t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs)
3036 }
3037 // aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets.
3038 res := foo.Output("package-res.apk")
3039 aapt2Flags := res.Args["flags"]
3040 e := "-A " + buildDir + "/.intermediates/foo/android_common/NOTICE"
3041 if !strings.Contains(aapt2Flags, e) {
3042 t.Errorf("asset dir flag for NOTICE, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
3043 }
3044
3045 // bar has NOTICE files to process, but embed_notices is not set.
3046 bar := ctx.ModuleForTests("bar", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07003047 res = bar.Output("package-res.apk")
3048 aapt2Flags = res.Args["flags"]
3049 e = "-A " + buildDir + "/.intermediates/bar/android_common/NOTICE"
3050 if strings.Contains(aapt2Flags, e) {
3051 t.Errorf("bar shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07003052 }
3053
3054 // baz's embed_notice is true, but it doesn't have any NOTICE files.
3055 baz := ctx.ModuleForTests("baz", "android_common")
Jaewoong Jung98772792019-07-01 17:15:13 -07003056 res = baz.Output("package-res.apk")
3057 aapt2Flags = res.Args["flags"]
3058 e = "-A " + buildDir + "/.intermediates/baz/android_common/NOTICE"
3059 if strings.Contains(aapt2Flags, e) {
3060 t.Errorf("baz shouldn't have the asset dir flag for NOTICE: %q", e)
Jaewoong Jung5b425e22019-06-17 17:40:56 -07003061 }
3062}
Colin Cross53a87f52019-06-25 13:35:30 -07003063
3064func TestUncompressDex(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07003065 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003066 testCases := []struct {
3067 name string
3068 bp string
3069
3070 uncompressedPlatform bool
3071 uncompressedUnbundled bool
3072 }{
3073 {
3074 name: "normal",
3075 bp: `
3076 android_app {
3077 name: "foo",
3078 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003079 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003080 }
3081 `,
3082 uncompressedPlatform: true,
3083 uncompressedUnbundled: false,
3084 },
3085 {
3086 name: "use_embedded_dex",
3087 bp: `
3088 android_app {
3089 name: "foo",
3090 use_embedded_dex: true,
3091 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003092 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003093 }
3094 `,
3095 uncompressedPlatform: true,
3096 uncompressedUnbundled: true,
3097 },
3098 {
3099 name: "privileged",
3100 bp: `
3101 android_app {
3102 name: "foo",
3103 privileged: true,
3104 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003105 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003106 }
3107 `,
3108 uncompressedPlatform: true,
3109 uncompressedUnbundled: true,
3110 },
David Srbeckye033cba2020-05-20 22:20:28 +01003111 {
3112 name: "normal_uncompress_dex_true",
3113 bp: `
3114 android_app {
3115 name: "foo",
3116 srcs: ["a.java"],
3117 sdk_version: "current",
3118 uncompress_dex: true,
3119 }
3120 `,
3121 uncompressedPlatform: true,
3122 uncompressedUnbundled: true,
3123 },
3124 {
3125 name: "normal_uncompress_dex_false",
3126 bp: `
3127 android_app {
3128 name: "foo",
3129 srcs: ["a.java"],
3130 sdk_version: "current",
3131 uncompress_dex: false,
3132 }
3133 `,
3134 uncompressedPlatform: false,
3135 uncompressedUnbundled: false,
3136 },
Colin Cross53a87f52019-06-25 13:35:30 -07003137 }
3138
3139 test := func(t *testing.T, bp string, want bool, unbundled bool) {
3140 t.Helper()
3141
Colin Cross98be1bb2019-12-13 20:41:13 -08003142 config := testAppConfig(nil, bp, nil)
Colin Cross53a87f52019-06-25 13:35:30 -07003143 if unbundled {
3144 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
Jeongik Cha816a23a2020-07-08 01:09:23 +09003145 config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
Colin Cross53a87f52019-06-25 13:35:30 -07003146 }
3147
Colin Cross98be1bb2019-12-13 20:41:13 -08003148 ctx := testContext()
Colin Cross53a87f52019-06-25 13:35:30 -07003149
3150 run(t, ctx, config)
3151
3152 foo := ctx.ModuleForTests("foo", "android_common")
3153 dex := foo.Rule("r8")
3154 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
3155 aligned := foo.MaybeRule("zipalign").Rule != nil
3156
3157 if uncompressedInDexJar != want {
3158 t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar)
3159 }
3160
3161 if aligned != want {
3162 t.Errorf("want aligned %v, got %v", want, aligned)
3163 }
3164 }
3165
3166 for _, tt := range testCases {
3167 t.Run(tt.name, func(t *testing.T) {
3168 t.Run("platform", func(t *testing.T) {
3169 test(t, tt.bp, tt.uncompressedPlatform, false)
3170 })
3171 t.Run("unbundled", func(t *testing.T) {
3172 test(t, tt.bp, tt.uncompressedUnbundled, true)
3173 })
3174 })
3175 }
3176}
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003177
3178func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
3179 if expectedValue != "" {
3180 expectedFlag := "--" + flagName + " " + expectedValue
3181 if !strings.Contains(aapt2Flags, expectedFlag) {
3182 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
3183 }
3184 } else {
3185 unexpectedFlag := "--" + flagName
3186 if strings.Contains(aapt2Flags, unexpectedFlag) {
3187 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
3188 }
3189 }
3190}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003191
3192func TestRuntimeResourceOverlay(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07003193 t.Parallel()
Jaewoong Jungfe3c7f62020-04-09 16:15:30 -07003194 fs := map[string][]byte{
3195 "baz/res/res/values/strings.xml": nil,
3196 "bar/res/res/values/strings.xml": nil,
3197 }
3198 bp := `
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003199 runtime_resource_overlay {
3200 name: "foo",
3201 certificate: "platform",
Liz Kammer966b2f02020-05-19 16:15:25 -07003202 lineage: "lineage.bin",
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003203 product_specific: true,
Jaewoong Jungfe3c7f62020-04-09 16:15:30 -07003204 static_libs: ["bar"],
3205 resource_libs: ["baz"],
Jaewoong Jungf0f747c2020-01-24 10:30:02 -08003206 aaptflags: ["--keep-raw-values"],
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003207 }
3208
3209 runtime_resource_overlay {
3210 name: "foo_themed",
3211 certificate: "platform",
3212 product_specific: true,
3213 theme: "faza",
Jaewoong Jungad0177b2020-04-24 15:22:40 -07003214 overrides: ["foo"],
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003215 }
Jaewoong Jungfe3c7f62020-04-09 16:15:30 -07003216
3217 android_library {
3218 name: "bar",
3219 resource_dirs: ["bar/res"],
3220 }
3221
3222 android_app {
3223 name: "baz",
3224 sdk_version: "current",
3225 resource_dirs: ["baz/res"],
3226 }
3227 `
3228 config := testAppConfig(nil, bp, fs)
3229 ctx := testContext()
3230 run(t, ctx, config)
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003231
3232 m := ctx.ModuleForTests("foo", "android_common")
3233
Jaewoong Jungf0f747c2020-01-24 10:30:02 -08003234 // Check AAPT2 link flags.
3235 aapt2Flags := m.Output("package-res.apk").Args["flags"]
3236 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
3237 absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
3238 if len(absentFlags) > 0 {
3239 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
3240 }
3241
Jaewoong Jungfe3c7f62020-04-09 16:15:30 -07003242 // Check overlay.list output for static_libs dependency.
3243 overlayList := m.Output("aapt2/overlay.list").Inputs.Strings()
3244 staticLibPackage := buildDir + "/.intermediates/bar/android_common/package-res.apk"
3245 if !inList(staticLibPackage, overlayList) {
3246 t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
3247 }
3248
3249 // Check AAPT2 link flags for resource_libs dependency.
3250 resourceLibFlag := "-I " + buildDir + "/.intermediates/baz/android_common/package-res.apk"
3251 if !strings.Contains(aapt2Flags, resourceLibFlag) {
3252 t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
3253 }
3254
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003255 // Check cert signing flag.
3256 signedApk := m.Output("signed/foo.apk")
Liz Kammer966b2f02020-05-19 16:15:25 -07003257 lineageFlag := signedApk.Args["flags"]
3258 expectedLineageFlag := "--lineage lineage.bin"
3259 if expectedLineageFlag != lineageFlag {
3260 t.Errorf("Incorrect signing lineage flags, expected: %q, got: %q", expectedLineageFlag, lineageFlag)
3261 }
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003262 signingFlag := signedApk.Args["certificates"]
3263 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
3264 if expected != signingFlag {
3265 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
3266 }
Jaewoong Jungad0177b2020-04-24 15:22:40 -07003267 androidMkEntries := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
3268 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
Jaewoong Jung78ec5d82020-01-31 10:11:47 -08003269 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
3270 if !reflect.DeepEqual(path, expectedPath) {
3271 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
3272 }
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003273
3274 // Check device location.
Jaewoong Jungad0177b2020-04-24 15:22:40 -07003275 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Jaewoong Jung78ec5d82020-01-31 10:11:47 -08003276 expectedPath = []string{"/tmp/target/product/test_device/product/overlay"}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003277 if !reflect.DeepEqual(path, expectedPath) {
3278 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
3279 }
3280
3281 // A themed module has a different device location
3282 m = ctx.ModuleForTests("foo_themed", "android_common")
Jaewoong Jungad0177b2020-04-24 15:22:40 -07003283 androidMkEntries = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
3284 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003285 expectedPath = []string{"/tmp/target/product/test_device/product/overlay/faza"}
3286 if !reflect.DeepEqual(path, expectedPath) {
3287 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
3288 }
Jaewoong Jungad0177b2020-04-24 15:22:40 -07003289
3290 overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
3291 expectedOverrides := []string{"foo"}
3292 if !reflect.DeepEqual(overrides, expectedOverrides) {
3293 t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
3294 }
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003295}
Roshan Pius4df2bc72020-04-27 09:42:27 -07003296
Jaewoong Jung062ed7e2020-04-26 15:10:51 -07003297func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07003298 t.Parallel()
Jaewoong Jung062ed7e2020-04-26 15:10:51 -07003299 ctx, config := testJava(t, `
3300 java_defaults {
3301 name: "rro_defaults",
3302 theme: "default_theme",
3303 product_specific: true,
3304 aaptflags: ["--keep-raw-values"],
3305 }
3306
3307 runtime_resource_overlay {
3308 name: "foo_with_defaults",
3309 defaults: ["rro_defaults"],
3310 }
3311
3312 runtime_resource_overlay {
3313 name: "foo_barebones",
3314 }
3315 `)
3316
3317 //
3318 // RRO module with defaults
3319 //
3320 m := ctx.ModuleForTests("foo_with_defaults", "android_common")
3321
3322 // Check AAPT2 link flags.
3323 aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
3324 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
3325 absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
3326 if len(absentFlags) > 0 {
3327 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
3328 }
3329
3330 // Check device location.
3331 path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
3332 expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"}
3333 if !reflect.DeepEqual(path, expectedPath) {
3334 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath)
3335 }
3336
3337 //
3338 // RRO module without defaults
3339 //
3340 m = ctx.ModuleForTests("foo_barebones", "android_common")
3341
3342 // Check AAPT2 link flags.
3343 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
3344 unexpectedFlags := "--keep-raw-values"
3345 if inList(unexpectedFlags, aapt2Flags) {
3346 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
3347 }
3348
3349 // Check device location.
3350 path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
3351 expectedPath = []string{"/tmp/target/product/test_device/system/overlay"}
3352 if !reflect.DeepEqual(path, expectedPath) {
3353 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
3354 }
3355}
Roshan Piusb8307962020-04-27 09:42:27 -07003356
Roshan Pius4df2bc72020-04-27 09:42:27 -07003357func TestOverrideRuntimeResourceOverlay(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -07003358 t.Parallel()
Roshan Pius4df2bc72020-04-27 09:42:27 -07003359 ctx, _ := testJava(t, `
3360 runtime_resource_overlay {
3361 name: "foo_overlay",
3362 certificate: "platform",
3363 product_specific: true,
3364 sdk_version: "current",
3365 }
3366
3367 override_runtime_resource_overlay {
3368 name: "bar_overlay",
3369 base: "foo_overlay",
3370 package_name: "com.android.bar.overlay",
3371 target_package_name: "com.android.bar",
3372 }
3373 `)
3374
3375 expectedVariants := []struct {
3376 moduleName string
3377 variantName string
3378 apkPath string
3379 overrides []string
3380 targetVariant string
3381 packageFlag string
3382 targetPackageFlag string
3383 }{
3384 {
3385 variantName: "android_common",
3386 apkPath: "/target/product/test_device/product/overlay/foo_overlay.apk",
3387 overrides: nil,
3388 targetVariant: "android_common",
3389 packageFlag: "",
3390 targetPackageFlag: "",
3391 },
3392 {
3393 variantName: "android_common_bar_overlay",
3394 apkPath: "/target/product/test_device/product/overlay/bar_overlay.apk",
3395 overrides: []string{"foo_overlay"},
3396 targetVariant: "android_common_bar",
3397 packageFlag: "com.android.bar.overlay",
3398 targetPackageFlag: "com.android.bar",
3399 },
3400 }
3401 for _, expected := range expectedVariants {
3402 variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
3403
3404 // Check the final apk name
3405 outputs := variant.AllOutputs()
3406 expectedApkPath := buildDir + expected.apkPath
3407 found := false
3408 for _, o := range outputs {
3409 if o == expectedApkPath {
3410 found = true
3411 break
3412 }
3413 }
3414 if !found {
3415 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
3416 }
3417
3418 // Check if the overrides field values are correctly aggregated.
3419 mod := variant.Module().(*RuntimeResourceOverlay)
3420 if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
3421 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
3422 expected.overrides, mod.properties.Overrides)
3423 }
3424
3425 // Check aapt2 flags.
3426 res := variant.Output("package-res.apk")
3427 aapt2Flags := res.Args["flags"]
3428 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
Liz Kammer9f9fd022020-06-18 19:44:06 +00003429 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
Roshan Pius4df2bc72020-04-27 09:42:27 -07003430 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
3431 }
3432}