blob: 3d88604ab36304ae123a5c5aae6c3fe8f45198ee [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"
Jiyong Parkf528b702024-12-30 16:01:58 +090021 "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"
Ulya Trafimovich9023b022021-03-22 16:02:28 +000030 "android/soong/dexpreopt"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080031)
32
Paul Duffin71ae5942021-03-22 15:36:52 +000033// testApp runs tests using the prepareForJavaTest
Paul Duffin0ed42d32021-03-13 02:19:32 +000034//
35// See testJava for an explanation as to how to stop using this deprecated method.
36//
37// deprecated
38func testApp(t *testing.T, bp string) *android.TestContext {
39 t.Helper()
Paul Duffin71ae5942021-03-22 15:36:52 +000040 result := prepareForJavaTest.RunTestWithBp(t, bp)
Paul Duffin0ed42d32021-03-13 02:19:32 +000041 return result.TestContext
42}
43
44func TestApp(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080045 t.Parallel()
Paul Duffin0ed42d32021-03-13 02:19:32 +000046 resourceFiles := []string{
Colin Cross3bc7ffa2017-11-22 16:19:37 -080047 "res/layout/layout.xml",
48 "res/values/strings.xml",
49 "res/values-en-rUS/strings.xml",
50 }
51
Paul Duffin0ed42d32021-03-13 02:19:32 +000052 compiledResourceFiles := []string{
Colin Cross3bc7ffa2017-11-22 16:19:37 -080053 "aapt2/res/layout_layout.xml.flat",
54 "aapt2/res/values_strings.arsc.flat",
55 "aapt2/res/values-en-rUS_strings.arsc.flat",
56 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -080057
Colin Crossa97c5d32018-03-28 14:58:31 -070058 for _, moduleType := range []string{"android_app", "android_library"} {
59 t.Run(moduleType, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080060 t.Parallel()
Paul Duffin71ae5942021-03-22 15:36:52 +000061 result := android.GroupFixturePreparers(
62 prepareForJavaTest,
Paul Duffin0ed42d32021-03-13 02:19:32 +000063 android.FixtureModifyMockFS(func(fs android.MockFS) {
64 for _, file := range resourceFiles {
65 fs[file] = nil
66 }
67 }),
68 ).RunTestWithBp(t, moduleType+` {
Colin Crossa97c5d32018-03-28 14:58:31 -070069 name: "foo",
70 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +090071 sdk_version: "current"
Colin Crossa97c5d32018-03-28 14:58:31 -070072 }
73 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080074
Colin Cross90607e92025-02-11 14:58:07 -080075 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080076
Colin Cross31656952018-05-24 16:11:20 -070077 var expectedLinkImplicits []string
78
79 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
80 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080081
Colin Cross90607e92025-02-11 14:58:07 -080082 frameworkRes := result.ModuleForTests(t, "framework-res", "android_common")
Colin Crossa97c5d32018-03-28 14:58:31 -070083 expectedLinkImplicits = append(expectedLinkImplicits,
84 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080085
Colin Crossa97c5d32018-03-28 14:58:31 -070086 // Test the mapping from input files to compiled output file names
87 compile := foo.Output(compiledResourceFiles[0])
Paul Duffin0ed42d32021-03-13 02:19:32 +000088 android.AssertDeepEquals(t, "aapt2 compile inputs", resourceFiles, compile.Inputs.Strings())
Colin Crossb69301e2017-12-01 10:48:26 -080089
Colin Crossa97c5d32018-03-28 14:58:31 -070090 compiledResourceOutputs := compile.Outputs.Strings()
91 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -080092
Colin Crossa97c5d32018-03-28 14:58:31 -070093 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080094
Colin Crossa97c5d32018-03-28 14:58:31 -070095 list := foo.Output("aapt2/res.list")
96 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080097
Colin Crossa97c5d32018-03-28 14:58:31 -070098 // Check that the link rule uses
Colin Cross90607e92025-02-11 14:58:07 -080099 res := result.ModuleForTests(t, "foo", "android_common").Output("package-res.apk")
Paul Duffin0ed42d32021-03-13 02:19:32 +0000100 android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings())
Colin Crossa97c5d32018-03-28 14:58:31 -0700101 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800102 }
103}
Colin Cross890ff552017-11-30 20:13:19 -0800104
Colin Crosse560c4a2019-03-19 16:03:11 -0700105func TestAppSplits(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800106 t.Parallel()
Colin Crosse560c4a2019-03-19 16:03:11 -0700107 ctx := testApp(t, `
108 android_app {
109 name: "foo",
110 srcs: ["a.java"],
111 package_splits: ["v4", "v7,hdpi"],
Jeongik Cha538c0d02019-07-11 15:54:27 +0900112 sdk_version: "current"
Colin Crosse560c4a2019-03-19 16:03:11 -0700113 }`)
114
Colin Cross90607e92025-02-11 14:58:07 -0800115 foo := ctx.ModuleForTests(t, "foo", "android_common")
Colin Crosse560c4a2019-03-19 16:03:11 -0700116
117 expectedOutputs := []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000118 "out/soong/.intermediates/foo/android_common/foo.apk",
119 "out/soong/.intermediates/foo/android_common/foo_v4.apk",
120 "out/soong/.intermediates/foo/android_common/foo_v7_hdpi.apk",
Colin Crosse560c4a2019-03-19 16:03:11 -0700121 }
122 for _, expectedOutput := range expectedOutputs {
123 foo.Output(expectedOutput)
124 }
125
Yu Liu51c22312024-08-20 23:56:15 +0000126 outputFiles := foo.OutputFiles(ctx, t, "")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000127 android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles)
Colin Crosse560c4a2019-03-19 16:03:11 -0700128}
129
Jeongik Cha538c0d02019-07-11 15:54:27 +0900130func TestPlatformAPIs(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800131 t.Parallel()
Jeongik Cha538c0d02019-07-11 15:54:27 +0900132 testJava(t, `
133 android_app {
134 name: "foo",
135 srcs: ["a.java"],
136 platform_apis: true,
137 }
138 `)
139
140 testJava(t, `
141 android_app {
142 name: "foo",
143 srcs: ["a.java"],
144 sdk_version: "current",
145 }
146 `)
147
Spandan Das60999342021-11-16 04:15:33 +0000148 testJavaError(t, "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true", `
Jeongik Cha538c0d02019-07-11 15:54:27 +0900149 android_app {
150 name: "bar",
151 srcs: ["b.java"],
152 }
153 `)
154
Spandan Das60999342021-11-16 04:15:33 +0000155 testJavaError(t, "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.", `
Jeongik Cha538c0d02019-07-11 15:54:27 +0900156 android_app {
157 name: "bar",
158 srcs: ["b.java"],
159 sdk_version: "system_current",
160 platform_apis: true,
161 }
162 `)
163}
164
Jeongik Chae403e9e2019-12-07 00:16:24 +0900165func TestAndroidAppLinkType(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800166 t.Parallel()
Jeongik Chae403e9e2019-12-07 00:16:24 +0900167 testJava(t, `
168 android_app {
169 name: "foo",
170 srcs: ["a.java"],
171 libs: ["bar"],
172 static_libs: ["baz"],
173 platform_apis: true,
174 }
175
176 java_library {
177 name: "bar",
178 sdk_version: "current",
179 srcs: ["b.java"],
180 }
181
182 android_library {
183 name: "baz",
184 sdk_version: "system_current",
185 srcs: ["c.java"],
186 }
187 `)
188
Steven Moreland00298982020-11-17 21:44:36 +0000189 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900190 android_app {
191 name: "foo",
192 srcs: ["a.java"],
193 libs: ["bar"],
194 sdk_version: "current",
195 static_libs: ["baz"],
196 }
197
198 java_library {
199 name: "bar",
200 sdk_version: "current",
201 srcs: ["b.java"],
202 }
203
204 android_library {
205 name: "baz",
206 sdk_version: "system_current",
207 srcs: ["c.java"],
208 }
209 `)
210
211 testJava(t, `
212 android_app {
213 name: "foo",
214 srcs: ["a.java"],
215 libs: ["bar"],
216 sdk_version: "system_current",
217 static_libs: ["baz"],
218 }
219
220 java_library {
221 name: "bar",
222 sdk_version: "current",
223 srcs: ["b.java"],
224 }
225
226 android_library {
227 name: "baz",
228 sdk_version: "system_current",
229 srcs: ["c.java"],
230 }
231 `)
232
Steven Moreland00298982020-11-17 21:44:36 +0000233 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
Jeongik Chae403e9e2019-12-07 00:16:24 +0900234 android_app {
235 name: "foo",
236 srcs: ["a.java"],
237 libs: ["bar"],
238 sdk_version: "system_current",
239 static_libs: ["baz"],
240 }
241
242 java_library {
243 name: "bar",
244 sdk_version: "current",
245 srcs: ["b.java"],
246 }
247
248 android_library {
249 name: "baz",
250 srcs: ["c.java"],
251 }
252 `)
253}
254
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100255func TestUpdatableApps(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800256 t.Parallel()
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100257 testCases := []struct {
258 name string
259 bp string
260 expectedError string
261 }{
262 {
263 name: "Stable public SDK",
264 bp: `android_app {
265 name: "foo",
266 srcs: ["a.java"],
267 sdk_version: "29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100268 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100269 updatable: true,
270 }`,
271 },
272 {
273 name: "Stable system SDK",
274 bp: `android_app {
275 name: "foo",
276 srcs: ["a.java"],
277 sdk_version: "system_29",
Artur Satayevf40fc852020-04-16 13:43:02 +0100278 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100279 updatable: true,
280 }`,
281 },
282 {
283 name: "Current public SDK",
284 bp: `android_app {
285 name: "foo",
286 srcs: ["a.java"],
287 sdk_version: "current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100288 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100289 updatable: true,
290 }`,
291 },
292 {
293 name: "Current system SDK",
294 bp: `android_app {
295 name: "foo",
296 srcs: ["a.java"],
297 sdk_version: "system_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100298 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100299 updatable: true,
300 }`,
301 },
302 {
303 name: "Current module SDK",
304 bp: `android_app {
305 name: "foo",
306 srcs: ["a.java"],
307 sdk_version: "module_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100308 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100309 updatable: true,
310 }`,
311 },
312 {
313 name: "Current core SDK",
314 bp: `android_app {
315 name: "foo",
316 srcs: ["a.java"],
317 sdk_version: "core_current",
Artur Satayevf40fc852020-04-16 13:43:02 +0100318 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100319 updatable: true,
320 }`,
321 },
322 {
323 name: "No Platform APIs",
324 bp: `android_app {
325 name: "foo",
326 srcs: ["a.java"],
327 platform_apis: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100328 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100329 updatable: true,
330 }`,
331 expectedError: "Updatable apps must use stable SDKs",
332 },
333 {
334 name: "No Core Platform APIs",
335 bp: `android_app {
336 name: "foo",
337 srcs: ["a.java"],
338 sdk_version: "core_platform",
Artur Satayevf40fc852020-04-16 13:43:02 +0100339 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100340 updatable: true,
341 }`,
342 expectedError: "Updatable apps must use stable SDKs",
343 },
344 {
345 name: "No unspecified APIs",
346 bp: `android_app {
347 name: "foo",
348 srcs: ["a.java"],
349 updatable: true,
Artur Satayevf40fc852020-04-16 13:43:02 +0100350 min_sdk_version: "29",
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100351 }`,
352 expectedError: "Updatable apps must use stable SDK",
353 },
Artur Satayevf40fc852020-04-16 13:43:02 +0100354 {
355 name: "Must specify min_sdk_version",
356 bp: `android_app {
357 name: "app_without_min_sdk_version",
358 srcs: ["a.java"],
359 sdk_version: "29",
360 updatable: true,
361 }`,
362 expectedError: "updatable apps must set min_sdk_version.",
363 },
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100364 }
365
366 for _, test := range testCases {
367 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800368 t.Parallel()
Paul Duffincdb88a92021-03-14 00:36:50 +0000369 errorHandler := android.FixtureExpectsNoErrors
370 if test.expectedError != "" {
371 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100372 }
Paul Duffin71ae5942021-03-22 15:36:52 +0000373 android.GroupFixturePreparers(
374 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{
Paul Duffin2645a292021-03-13 02:36:00 +0000375 "29": {"foo"},
376 })).
Paul Duffincdb88a92021-03-14 00:36:50 +0000377 ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, test.bp)
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100378 })
379 }
380}
381
Jooyung Han749dc692020-04-15 11:03:39 +0900382func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800383 t.Parallel()
Jooyung Han749dc692020-04-15 11:03:39 +0900384 testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
385 android_app {
386 name: "foo",
387 srcs: ["a.java"],
388 updatable: true,
389 sdk_version: "current",
390 min_sdk_version: "29",
391 static_libs: ["bar"],
392 }
393
394 java_library {
395 name: "bar",
396 sdk_version: "current",
397 }
398 `)
399}
400
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900401func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800402 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900403 testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
404 android_app {
405 name: "foo",
406 srcs: ["a.java"],
407 updatable: true,
408 sdk_version: "current",
409 min_sdk_version: "current",
410 jni_libs: ["libjni"],
411 }
412
413 cc_library {
414 name: "libjni",
415 stl: "none",
416 system_shared_libs: [],
417 sdk_version: "current",
418 }
419 `)
420}
421
422func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800423 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900424 bp := cc.GatherRequiredDepsForTest(android.Android) + `
425 android_app {
426 name: "foo",
427 srcs: ["a.java"],
428 updatable: true,
429 sdk_version: "current",
430 min_sdk_version: "29",
431 jni_libs: ["libjni"],
432 }
433
434 cc_library {
435 name: "libjni",
436 stl: "none",
437 system_shared_libs: [],
Spandan Das2e8c0442022-05-08 00:39:35 +0000438 sdk_version: "current",
439 min_sdk_version: "29",
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900440 }
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900441 `
442 fs := map[string][]byte{
443 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
444 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": nil,
445 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o": nil,
446 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o": nil,
447 }
448
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000449 ctx, _ := testJavaWithFS(t, bp, fs)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900450
Colin Cross90607e92025-02-11 14:58:07 -0800451 inputs := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900452 var crtbeginFound, crtendFound bool
Colin Cross90607e92025-02-11 14:58:07 -0800453 expectedCrtBegin := ctx.ModuleForTests(t, "crtbegin_so",
Colin Crossdea1d032022-12-06 14:50:08 -0800454 "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
Colin Cross90607e92025-02-11 14:58:07 -0800455 expectedCrtEnd := ctx.ModuleForTests(t, "crtend_so",
Colin Crossdea1d032022-12-06 14:50:08 -0800456 "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
Dan Albert92fe7402020-07-15 13:33:30 -0700457 implicits := []string{}
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900458 for _, input := range inputs {
Dan Albert92fe7402020-07-15 13:33:30 -0700459 implicits = append(implicits, input.String())
460 if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900461 crtbeginFound = true
Dan Albert92fe7402020-07-15 13:33:30 -0700462 } else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900463 crtendFound = true
464 }
465 }
Dan Albert92fe7402020-07-15 13:33:30 -0700466 if !crtbeginFound {
467 t.Error(fmt.Sprintf(
468 "expected implicit with suffix %q, have the following implicits:\n%s",
469 expectedCrtBegin, strings.Join(implicits, "\n")))
470 }
471 if !crtendFound {
472 t.Error(fmt.Sprintf(
473 "expected implicit with suffix %q, have the following implicits:\n%s",
474 expectedCrtEnd, strings.Join(implicits, "\n")))
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900475 }
476}
477
478func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800479 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900480 bp := cc.GatherRequiredDepsForTest(android.Android) + `
481 android_app {
482 name: "foo",
483 srcs: ["a.java"],
484 updatable: true,
485 sdk_version: "current",
486 min_sdk_version: "29", // this APK should support 29
487 jni_libs: ["libjni"],
488 }
489
490 cc_library {
491 name: "libjni",
492 stl: "none",
493 sdk_version: "current",
Spandan Das2e8c0442022-05-08 00:39:35 +0000494 min_sdk_version: "current",
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900495 }
496 `
Spandan Das2e8c0442022-05-08 00:39:35 +0000497 testJavaError(t, `"libjni" .*: min_sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900498}
499
Spandan Das2e8c0442022-05-08 00:39:35 +0000500func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800501 t.Parallel()
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900502 bp := cc.GatherRequiredDepsForTest(android.Android) + `
503 android_app {
504 name: "foo",
505 srcs: ["a.java"],
506 updatable: true,
507 sdk_version: "current",
508 min_sdk_version: "29", // this APK should support 29
509 jni_libs: ["libjni"],
510 }
511
512 cc_library {
513 name: "libjni",
514 stl: "none",
515 shared_libs: ["libbar"],
516 system_shared_libs: [],
517 sdk_version: "27",
Spandan Das2e8c0442022-05-08 00:39:35 +0000518 min_sdk_version: "27",
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900519 }
520
521 cc_library {
522 name: "libbar",
523 stl: "none",
524 system_shared_libs: [],
525 sdk_version: "current",
Spandan Das2e8c0442022-05-08 00:39:35 +0000526 min_sdk_version: "current",
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900527 }
528 `
529 testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp)
530}
531
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000532func TestUpdatableApps_ApplyDefaultUpdatableModuleVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800533 t.Parallel()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000534 result := android.GroupFixturePreparers(
535 PrepareForTestWithJavaDefaultModules,
536 ).RunTestWithBp(t, `
537 android_app {
538 name: "com.android.foo",
539 srcs: ["a.java"],
540 sdk_version: "current",
541 min_sdk_version: "31",
542 updatable: true,
543 }
544 `)
Colin Cross90607e92025-02-11 14:58:07 -0800545 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000546 android.AssertStringDoesContain(t,
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000547 "com.android.foo: expected manifest fixer to set override-placeholder-version to RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION",
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000548 foo.BuildParams.Args["args"],
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000549 fmt.Sprintf("--override-placeholder-version %s", testDefaultUpdatableModuleVersion),
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000550 )
551}
552
553func TestUpdatableApps_ApplyOverrideApexManifestDefaultVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800554 t.Parallel()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000555 result := android.GroupFixturePreparers(
556 PrepareForTestWithJavaDefaultModules,
557 android.FixtureMergeEnv(map[string]string{
558 "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234",
559 }),
560 ).RunTestWithBp(t, `
561 android_app {
562 name: "com.android.foo",
563 srcs: ["a.java"],
564 sdk_version: "current",
565 min_sdk_version: "31",
566 updatable: true,
567 }
568 `)
Colin Cross90607e92025-02-11 14:58:07 -0800569 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000570 android.AssertStringDoesContain(t,
571 "com.android.foo: expected manifest fixer to set override-placeholder-version to 1234",
572 foo.BuildParams.Args["args"],
573 "--override-placeholder-version 1234",
574 )
575}
576
Colin Cross0ddae7f2019-02-07 15:30:01 -0800577func TestResourceDirs(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800578 t.Parallel()
Colin Cross0ddae7f2019-02-07 15:30:01 -0800579 testCases := []struct {
580 name string
581 prop string
582 resources []string
583 }{
584 {
585 name: "no resource_dirs",
586 prop: "",
587 resources: []string{"res/res/values/strings.xml"},
588 },
589 {
590 name: "resource_dirs",
591 prop: `resource_dirs: ["res"]`,
592 resources: []string{"res/res/values/strings.xml"},
593 },
594 {
595 name: "empty resource_dirs",
596 prop: `resource_dirs: []`,
597 resources: nil,
598 },
599 }
600
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000601 fs := android.MockFS{
Colin Cross0ddae7f2019-02-07 15:30:01 -0800602 "res/res/values/strings.xml": nil,
603 }
604
605 bp := `
606 android_app {
607 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +0900608 sdk_version: "current",
Colin Cross0ddae7f2019-02-07 15:30:01 -0800609 %s
610 }
611 `
612
613 for _, testCase := range testCases {
614 t.Run(testCase.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800615 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000616 result := android.GroupFixturePreparers(
617 PrepareForTestWithJavaDefaultModules,
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000618 fs.AddToFixture(),
619 ).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop))
Colin Cross0ddae7f2019-02-07 15:30:01 -0800620
Colin Cross90607e92025-02-11 14:58:07 -0800621 module := result.ModuleForTests(t, "foo", "android_common")
Colin Cross0ddae7f2019-02-07 15:30:01 -0800622 resourceList := module.MaybeOutput("aapt2/res.list")
623
624 var resources []string
625 if resourceList.Rule != nil {
626 for _, compiledResource := range resourceList.Inputs.Strings() {
627 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
628 }
629 }
630
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000631 android.AssertDeepEquals(t, "resource files", testCase.resources, resources)
Colin Cross0ddae7f2019-02-07 15:30:01 -0800632 })
633 }
634}
635
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800636func TestLibraryAssets(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800637 t.Parallel()
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800638 bp := `
639 android_app {
640 name: "foo",
641 sdk_version: "current",
642 static_libs: ["lib1", "lib2", "lib3"],
643 }
644
645 android_library {
646 name: "lib1",
647 sdk_version: "current",
648 asset_dirs: ["assets_a"],
649 }
650
651 android_library {
652 name: "lib2",
653 sdk_version: "current",
654 }
655
656 android_library {
657 name: "lib3",
658 sdk_version: "current",
Colin Crossab8d1382023-07-14 17:23:41 +0000659 static_libs: ["lib4", "import"],
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800660 }
661
662 android_library {
663 name: "lib4",
664 sdk_version: "current",
665 asset_dirs: ["assets_b"],
666 }
Colin Crossab8d1382023-07-14 17:23:41 +0000667
Jiakai Zhangba82e282023-10-13 18:08:59 +0100668 android_library {
669 name: "lib5",
670 sdk_version: "current",
671 assets: [
672 "path/to/asset_file_1",
673 "path/to/asset_file_2",
674 ],
675 }
676
Colin Crossab8d1382023-07-14 17:23:41 +0000677 android_library_import {
678 name: "import",
679 sdk_version: "current",
680 aars: ["import.aar"],
681 }
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800682 `
683
684 testCases := []struct {
Jiakai Zhangba82e282023-10-13 18:08:59 +0100685 name string
686 assetFlag string
687 assetPackages []string
688 tmpAssetDirInputs []string
689 tmpAssetDirOutputs []string
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800690 }{
691 {
692 name: "foo",
Colin Crossab8d1382023-07-14 17:23:41 +0000693 // lib1 has its own assets. lib3 doesn't have any, but lib4 and import have assets.
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800694 assetPackages: []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000695 "out/soong/.intermediates/foo/android_common/aapt2/package-res.apk",
696 "out/soong/.intermediates/lib1/android_common/assets.zip",
Colin Crossab8d1382023-07-14 17:23:41 +0000697 "out/soong/.intermediates/lib4/android_common/assets.zip",
698 "out/soong/.intermediates/import/android_common/assets.zip",
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800699 },
700 },
701 {
702 name: "lib1",
703 assetFlag: "-A assets_a",
704 },
705 {
706 name: "lib2",
707 },
708 {
709 name: "lib3",
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800710 },
711 {
712 name: "lib4",
713 assetFlag: "-A assets_b",
714 },
Jiakai Zhangba82e282023-10-13 18:08:59 +0100715 {
716 name: "lib5",
717 assetFlag: "-A out/soong/.intermediates/lib5/android_common/tmp_asset_dir",
718 tmpAssetDirInputs: []string{
719 "path/to/asset_file_1",
720 "path/to/asset_file_2",
721 },
722 tmpAssetDirOutputs: []string{
723 "out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_1",
724 "out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_2",
725 },
726 },
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800727 }
728 ctx := testApp(t, bp)
729
730 for _, test := range testCases {
731 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800732 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -0800733 m := ctx.ModuleForTests(t, test.name, "android_common")
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800734
735 // Check asset flag in aapt2 link flags
736 var aapt2link android.TestingBuildParams
737 if len(test.assetPackages) > 0 {
738 aapt2link = m.Output("aapt2/package-res.apk")
739 } else {
740 aapt2link = m.Output("package-res.apk")
741 }
Paul Duffina71a67a2021-03-29 00:42:57 +0100742 aapt2link = aapt2link
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800743 aapt2Flags := aapt2link.Args["flags"]
744 if test.assetFlag != "" {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000745 android.AssertStringDoesContain(t, "asset flag", aapt2Flags, test.assetFlag)
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800746 } else {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000747 android.AssertStringDoesNotContain(t, "aapt2 link flags", aapt2Flags, " -A ")
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800748 }
749
750 // Check asset merge rule.
751 if len(test.assetPackages) > 0 {
752 mergeAssets := m.Output("package-res.apk")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +0000753 android.AssertPathsRelativeToTopEquals(t, "mergeAssets inputs", test.assetPackages, mergeAssets.Inputs)
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800754 }
Jiakai Zhangba82e282023-10-13 18:08:59 +0100755
756 if len(test.tmpAssetDirInputs) > 0 {
757 rule := m.Rule("tmp_asset_dir")
758 inputs := rule.Implicits
759 outputs := append(android.WritablePaths{rule.Output}, rule.ImplicitOutputs...).Paths()
760 android.AssertPathsRelativeToTopEquals(t, "tmp_asset_dir inputs", test.tmpAssetDirInputs, inputs)
761 android.AssertPathsRelativeToTopEquals(t, "tmp_asset_dir outputs", test.tmpAssetDirOutputs, outputs)
762 }
Jaewoong Jung6431ca72020-01-15 14:15:10 -0800763 })
764 }
765}
766
Colin Crossb014f072021-02-26 14:54:36 -0800767func TestAppJavaResources(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800768 t.Parallel()
Colin Crossb014f072021-02-26 14:54:36 -0800769 bp := `
770 android_app {
771 name: "foo",
772 sdk_version: "current",
773 java_resources: ["resources/a"],
774 srcs: ["a.java"],
775 }
776
777 android_app {
778 name: "bar",
779 sdk_version: "current",
780 java_resources: ["resources/a"],
781 }
782 `
783
784 ctx := testApp(t, bp)
785
Colin Cross90607e92025-02-11 14:58:07 -0800786 foo := ctx.ModuleForTests(t, "foo", "android_common")
Colin Crossb014f072021-02-26 14:54:36 -0800787 fooResources := foo.Output("res/foo.jar")
788 fooDexJar := foo.Output("dex-withres/foo.jar")
789 fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
790 fooApk := foo.Rule("combineApk")
791
792 if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) {
793 t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g)
794 }
795
796 if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w {
797 t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g)
798 }
799
800 if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) {
801 t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
802 }
803
Colin Cross90607e92025-02-11 14:58:07 -0800804 bar := ctx.ModuleForTests(t, "bar", "android_common")
Colin Crossb014f072021-02-26 14:54:36 -0800805 barResources := bar.Output("res/bar.jar")
806 barApk := bar.Rule("combineApk")
807
808 if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) {
809 t.Errorf("expected resources jar %q in bar apk inputs %q", w, g)
810 }
811}
812
Colin Crossff3ff7f2023-07-05 14:04:12 -0700813func TestAndroidResourceProcessor(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800814 t.Parallel()
Colin Crossff3ff7f2023-07-05 14:04:12 -0700815 testCases := []struct {
Colin Cross8676c8c2023-10-12 15:58:57 -0700816 name string
817 appUsesRP bool
818 directLibUsesRP bool
819 transitiveLibUsesRP bool
820 sharedLibUsesRP bool
821 sharedTransitiveStaticLibUsesRP bool
822 sharedTransitiveSharedLibUsesRP bool
Colin Crossff3ff7f2023-07-05 14:04:12 -0700823
824 dontVerifyApp bool
825 appResources []string
826 appOverlays []string
827 appImports []string
828 appSrcJars []string
829 appClasspath []string
830 appCombined []string
831
832 dontVerifyDirect bool
833 directResources []string
834 directOverlays []string
835 directImports []string
836 directSrcJars []string
837 directClasspath []string
838 directCombined []string
839
840 dontVerifyTransitive bool
841 transitiveResources []string
842 transitiveOverlays []string
843 transitiveImports []string
844 transitiveSrcJars []string
845 transitiveClasspath []string
846 transitiveCombined []string
847
848 dontVerifyDirectImport bool
849 directImportResources []string
850 directImportOverlays []string
851 directImportImports []string
852
853 dontVerifyTransitiveImport bool
854 transitiveImportResources []string
855 transitiveImportOverlays []string
856 transitiveImportImports []string
Colin Cross8676c8c2023-10-12 15:58:57 -0700857
858 dontVerifyShared bool
859 sharedResources []string
860 sharedOverlays []string
861 sharedImports []string
862 sharedSrcJars []string
863 sharedClasspath []string
864 sharedCombined []string
Colin Crossff3ff7f2023-07-05 14:04:12 -0700865 }{
866 {
Colin Cross4eae06d2023-06-20 22:40:02 -0700867 // Test with all modules set to use_resource_processor: false (except android_library_import modules,
868 // which always use resource processor).
869 name: "legacy",
870 appUsesRP: false,
871 directLibUsesRP: false,
872 transitiveLibUsesRP: false,
Colin Crossff3ff7f2023-07-05 14:04:12 -0700873
874 appResources: nil,
875 appOverlays: []string{
876 "out/soong/.intermediates/transitive/android_common/package-res.apk",
Colin Crossab8d1382023-07-14 17:23:41 +0000877 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700878 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
879 "out/soong/.intermediates/direct/android_common/package-res.apk",
Colin Crossab8d1382023-07-14 17:23:41 +0000880 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700881 "out/soong/.intermediates/direct_import/android_common/package-res.apk",
882 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
883 },
Colin Cross8676c8c2023-10-12 15:58:57 -0700884 appImports: []string{
885 "out/soong/.intermediates/shared/android_common/package-res.apk",
886 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
887 },
Colin Crossff3ff7f2023-07-05 14:04:12 -0700888 appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
889 appClasspath: []string{
890 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
Colin Cross8676c8c2023-10-12 15:58:57 -0700891 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700892 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +0000893 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700894 },
895 appCombined: []string{
896 "out/soong/.intermediates/app/android_common/javac/app.jar",
897 "out/soong/.intermediates/direct/android_common/combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +0000898 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700899 },
900
901 directResources: nil,
902 directOverlays: []string{
903 "out/soong/.intermediates/transitive/android_common/package-res.apk",
Colin Crossab8d1382023-07-14 17:23:41 +0000904 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700905 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
906 "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat",
907 },
908 directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
909 directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
910 directClasspath: []string{
911 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
912 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +0000913 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700914 },
915 directCombined: []string{
916 "out/soong/.intermediates/direct/android_common/javac/direct.jar",
917 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +0000918 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700919 },
920
921 transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
922 transitiveOverlays: nil,
923 transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
924 transitiveSrcJars: []string{"out/soong/.intermediates/transitive/android_common/gen/android/R.srcjar"},
925 transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar"},
926 transitiveCombined: nil,
927
Colin Cross8676c8c2023-10-12 15:58:57 -0700928 sharedResources: nil,
929 sharedOverlays: []string{
930 "out/soong/.intermediates/shared_transitive_static/android_common/package-res.apk",
931 "out/soong/.intermediates/shared/android_common/aapt2/shared/res/values_strings.arsc.flat",
932 },
933 sharedImports: []string{
934 "out/soong/.intermediates/shared_transitive_shared/android_common/package-res.apk",
935 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
936 },
937 sharedSrcJars: []string{"out/soong/.intermediates/shared/android_common/gen/android/R.srcjar"},
938 sharedClasspath: []string{
939 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
940 "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
941 "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
942 },
943 sharedCombined: []string{
944 "out/soong/.intermediates/shared/android_common/javac/shared.jar",
945 "out/soong/.intermediates/shared_transitive_static/android_common/javac/shared_transitive_static.jar",
946 },
947
Colin Crossff3ff7f2023-07-05 14:04:12 -0700948 directImportResources: nil,
Colin Cross4eae06d2023-06-20 22:40:02 -0700949 directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"},
950 directImportImports: []string{
951 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700952 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
953 },
Colin Crossff3ff7f2023-07-05 14:04:12 -0700954
955 transitiveImportResources: nil,
Colin Cross4eae06d2023-06-20 22:40:02 -0700956 transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"},
957 transitiveImportImports: []string{
958 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
Colin Crossff3ff7f2023-07-05 14:04:12 -0700959 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
960 },
Colin Cross4eae06d2023-06-20 22:40:02 -0700961 },
962 {
963 // Test with all modules set to use_resource_processor: true.
Colin Cross8676c8c2023-10-12 15:58:57 -0700964 name: "resource_processor",
965 appUsesRP: true,
966 directLibUsesRP: true,
967 transitiveLibUsesRP: true,
968 sharedLibUsesRP: true,
969 sharedTransitiveSharedLibUsesRP: true,
970 sharedTransitiveStaticLibUsesRP: true,
Colin Cross4eae06d2023-06-20 22:40:02 -0700971
972 appResources: nil,
973 appOverlays: []string{
974 "out/soong/.intermediates/transitive/android_common/package-res.apk",
975 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
976 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
977 "out/soong/.intermediates/direct/android_common/package-res.apk",
978 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
979 "out/soong/.intermediates/direct_import/android_common/package-res.apk",
980 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
981 },
Colin Cross8676c8c2023-10-12 15:58:57 -0700982 appImports: []string{
983 "out/soong/.intermediates/shared/android_common/package-res.apk",
984 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
985 },
Colin Cross4eae06d2023-06-20 22:40:02 -0700986 appSrcJars: nil,
987 appClasspath: []string{
988 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
989 "out/soong/.intermediates/app/android_common/busybox/R.jar",
Colin Cross8676c8c2023-10-12 15:58:57 -0700990 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -0700991 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +0000992 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -0700993 },
994 appCombined: []string{
Colin Cross4eae06d2023-06-20 22:40:02 -0700995 "out/soong/.intermediates/app/android_common/javac/app.jar",
Colin Crossfd620b22024-02-23 10:05:21 -0800996 "out/soong/.intermediates/app/android_common/busybox/R.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -0700997 "out/soong/.intermediates/direct/android_common/combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +0000998 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -0700999 },
1000
1001 directResources: nil,
1002 directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"},
1003 directImports: []string{
1004 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1005 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
1006 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
1007 "out/soong/.intermediates/transitive/android_common/package-res.apk",
1008 },
1009 directSrcJars: nil,
1010 directClasspath: []string{
1011 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001012 "out/soong/.intermediates/direct/android_common/busybox/R.jar",
Colin Cross1d3f5902024-03-05 11:51:54 -08001013 "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
1014 "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
1015 "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001016 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001017 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001018 },
1019 directCombined: []string{
1020 "out/soong/.intermediates/direct/android_common/javac/direct.jar",
1021 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001022 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001023 },
1024
1025 transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
1026 transitiveOverlays: nil,
1027 transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
1028 transitiveSrcJars: nil,
1029 transitiveClasspath: []string{
1030 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
1031 "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
1032 },
1033 transitiveCombined: nil,
1034
Colin Cross8676c8c2023-10-12 15:58:57 -07001035 sharedResources: nil,
1036 sharedOverlays: []string{"out/soong/.intermediates/shared/android_common/aapt2/shared/res/values_strings.arsc.flat"},
1037 sharedImports: []string{
1038 "out/soong/.intermediates/shared_transitive_shared/android_common/package-res.apk",
1039 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1040 "out/soong/.intermediates/shared_transitive_static/android_common/package-res.apk",
1041 },
1042 sharedSrcJars: nil,
1043 sharedClasspath: []string{
1044 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
Colin Cross1d3f5902024-03-05 11:51:54 -08001045 "out/soong/.intermediates/shared/android_common/busybox/R.jar",
Colin Cross8676c8c2023-10-12 15:58:57 -07001046 "out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar",
1047 "out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar",
Colin Cross8676c8c2023-10-12 15:58:57 -07001048 "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
1049 "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
1050 },
1051 sharedCombined: []string{
1052 "out/soong/.intermediates/shared/android_common/javac/shared.jar",
1053 "out/soong/.intermediates/shared_transitive_static/android_common/javac/shared_transitive_static.jar",
1054 },
1055
Colin Cross4eae06d2023-06-20 22:40:02 -07001056 directImportResources: nil,
1057 directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"},
1058 directImportImports: []string{
1059 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1060 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
1061 },
1062
1063 transitiveImportResources: nil,
1064 transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"},
1065 transitiveImportImports: []string{
1066 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1067 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
1068 },
1069 }, {
1070 // Test an app building with resource processor enabled but with dependencies built without
1071 // resource processor.
1072 name: "app_resource_processor",
1073 appUsesRP: true,
1074 directLibUsesRP: false,
1075 transitiveLibUsesRP: false,
1076
1077 appResources: nil,
1078 appOverlays: []string{
1079 "out/soong/.intermediates/transitive/android_common/package-res.apk",
1080 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
1081 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
1082 "out/soong/.intermediates/direct/android_common/package-res.apk",
1083 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
1084 "out/soong/.intermediates/direct_import/android_common/package-res.apk",
1085 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
1086 },
Colin Cross8676c8c2023-10-12 15:58:57 -07001087 appImports: []string{
1088 "out/soong/.intermediates/shared/android_common/package-res.apk",
1089 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1090 },
Colin Cross4eae06d2023-06-20 22:40:02 -07001091 appSrcJars: nil,
1092 appClasspath: []string{
1093 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
1094 // R.jar has to come before direct.jar
1095 "out/soong/.intermediates/app/android_common/busybox/R.jar",
Colin Cross8676c8c2023-10-12 15:58:57 -07001096 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001097 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001098 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001099 },
1100 appCombined: []string{
Colin Cross4eae06d2023-06-20 22:40:02 -07001101 "out/soong/.intermediates/app/android_common/javac/app.jar",
Colin Crossfd620b22024-02-23 10:05:21 -08001102 "out/soong/.intermediates/app/android_common/busybox/R.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001103 "out/soong/.intermediates/direct/android_common/combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001104 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001105 },
1106
1107 dontVerifyDirect: true,
1108 dontVerifyTransitive: true,
Colin Cross8676c8c2023-10-12 15:58:57 -07001109 dontVerifyShared: true,
Colin Cross4eae06d2023-06-20 22:40:02 -07001110 dontVerifyDirectImport: true,
1111 dontVerifyTransitiveImport: true,
1112 },
1113 {
1114 // Test an app building without resource processor enabled but with a dependency built with
1115 // resource processor.
1116 name: "app_dependency_lib_resource_processor",
1117 appUsesRP: false,
1118 directLibUsesRP: true,
1119 transitiveLibUsesRP: false,
1120
1121 appOverlays: []string{
1122 "out/soong/.intermediates/transitive/android_common/package-res.apk",
1123 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
1124 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
1125 "out/soong/.intermediates/direct/android_common/package-res.apk",
1126 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
1127 "out/soong/.intermediates/direct_import/android_common/package-res.apk",
1128 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
1129 },
Colin Cross8676c8c2023-10-12 15:58:57 -07001130 appImports: []string{
1131 "out/soong/.intermediates/shared/android_common/package-res.apk",
1132 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1133 },
Colin Cross4eae06d2023-06-20 22:40:02 -07001134 appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
1135 appClasspath: []string{
1136 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
Colin Cross8676c8c2023-10-12 15:58:57 -07001137 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001138 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001139 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001140 },
1141 appCombined: []string{
1142 "out/soong/.intermediates/app/android_common/javac/app.jar",
1143 "out/soong/.intermediates/direct/android_common/combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001144 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001145 },
1146
1147 directResources: nil,
1148 directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"},
1149 directImports: []string{
1150 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1151 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
1152 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
1153 "out/soong/.intermediates/transitive/android_common/package-res.apk",
1154 },
1155 directSrcJars: nil,
1156 directClasspath: []string{
1157 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001158 "out/soong/.intermediates/direct/android_common/busybox/R.jar",
Colin Cross1d3f5902024-03-05 11:51:54 -08001159 "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
1160 "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001161 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001162 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001163 },
1164 directCombined: []string{
1165 "out/soong/.intermediates/direct/android_common/javac/direct.jar",
1166 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001167 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001168 },
1169
1170 dontVerifyTransitive: true,
Colin Cross8676c8c2023-10-12 15:58:57 -07001171 dontVerifyShared: true,
Colin Cross4eae06d2023-06-20 22:40:02 -07001172 dontVerifyDirectImport: true,
1173 dontVerifyTransitiveImport: true,
1174 },
1175 {
1176 // Test a library building without resource processor enabled but with a dependency built with
1177 // resource processor.
1178 name: "lib_dependency_lib_resource_processor",
1179 appUsesRP: false,
1180 directLibUsesRP: false,
1181 transitiveLibUsesRP: true,
1182
1183 appOverlays: []string{
1184 "out/soong/.intermediates/transitive/android_common/package-res.apk",
1185 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
1186 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
1187 "out/soong/.intermediates/direct/android_common/package-res.apk",
1188 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
1189 "out/soong/.intermediates/direct_import/android_common/package-res.apk",
1190 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
1191 },
Colin Cross8676c8c2023-10-12 15:58:57 -07001192 appImports: []string{
1193 "out/soong/.intermediates/shared/android_common/package-res.apk",
1194 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
1195 },
Colin Cross4eae06d2023-06-20 22:40:02 -07001196 appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
1197 appClasspath: []string{
1198 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
Colin Cross8676c8c2023-10-12 15:58:57 -07001199 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001200 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001201 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001202 },
1203 appCombined: []string{
1204 "out/soong/.intermediates/app/android_common/javac/app.jar",
1205 "out/soong/.intermediates/direct/android_common/combined/direct.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001206 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001207 },
1208
1209 directResources: nil,
1210 directOverlays: []string{
1211 "out/soong/.intermediates/transitive/android_common/package-res.apk",
1212 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
1213 "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
1214 "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat",
1215 },
1216 directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
1217 directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
1218 directClasspath: []string{
1219 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
1220 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001221 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001222 },
1223 directCombined: []string{
1224 "out/soong/.intermediates/direct/android_common/javac/direct.jar",
1225 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
Colin Cross9055e212024-03-23 04:43:41 +00001226 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
Colin Cross4eae06d2023-06-20 22:40:02 -07001227 },
1228
1229 transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
1230 transitiveOverlays: nil,
1231 transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
1232 transitiveSrcJars: nil,
1233 transitiveClasspath: []string{
1234 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
1235 "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
1236 },
1237 transitiveCombined: nil,
1238
Colin Cross8676c8c2023-10-12 15:58:57 -07001239 dontVerifyShared: true,
Colin Cross4eae06d2023-06-20 22:40:02 -07001240 dontVerifyDirectImport: true,
1241 dontVerifyTransitiveImport: true,
Colin Crossff3ff7f2023-07-05 14:04:12 -07001242 },
1243 }
1244
1245 for _, testCase := range testCases {
1246 t.Run(testCase.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001247 t.Parallel()
Colin Crossff3ff7f2023-07-05 14:04:12 -07001248 bp := fmt.Sprintf(`
1249 android_app {
1250 name: "app",
1251 sdk_version: "current",
1252 srcs: ["app/app.java"],
1253 resource_dirs: ["app/res"],
1254 manifest: "app/AndroidManifest.xml",
Colin Cross8676c8c2023-10-12 15:58:57 -07001255 libs: ["shared"],
Colin Crossff3ff7f2023-07-05 14:04:12 -07001256 static_libs: ["direct", "direct_import"],
Colin Cross4eae06d2023-06-20 22:40:02 -07001257 use_resource_processor: %v,
Colin Crossff3ff7f2023-07-05 14:04:12 -07001258 }
1259
1260 android_library {
1261 name: "direct",
1262 sdk_version: "current",
1263 srcs: ["direct/direct.java"],
1264 resource_dirs: ["direct/res"],
1265 manifest: "direct/AndroidManifest.xml",
1266 static_libs: ["transitive", "transitive_import"],
Colin Cross4eae06d2023-06-20 22:40:02 -07001267 use_resource_processor: %v,
Colin Crossff3ff7f2023-07-05 14:04:12 -07001268 }
1269
1270 android_library {
1271 name: "transitive",
1272 sdk_version: "current",
1273 srcs: ["transitive/transitive.java"],
1274 resource_dirs: ["transitive/res"],
1275 manifest: "transitive/AndroidManifest.xml",
Colin Cross4eae06d2023-06-20 22:40:02 -07001276 use_resource_processor: %v,
Colin Crossff3ff7f2023-07-05 14:04:12 -07001277 }
1278
Colin Cross8676c8c2023-10-12 15:58:57 -07001279 android_library {
1280 name: "shared",
1281 sdk_version: "current",
1282 srcs: ["shared/shared.java"],
1283 resource_dirs: ["shared/res"],
1284 manifest: "shared/AndroidManifest.xml",
1285 use_resource_processor: %v,
1286 libs: ["shared_transitive_shared"],
1287 static_libs: ["shared_transitive_static"],
1288 }
1289
1290 android_library {
1291 name: "shared_transitive_shared",
1292 sdk_version: "current",
1293 srcs: ["shared_transitive_shared/shared_transitive_shared.java"],
1294 resource_dirs: ["shared_transitive_shared/res"],
1295 manifest: "shared_transitive_shared/AndroidManifest.xml",
1296 use_resource_processor: %v,
1297 }
1298
1299 android_library {
1300 name: "shared_transitive_static",
1301 sdk_version: "current",
1302 srcs: ["shared_transitive_static/shared.java"],
1303 resource_dirs: ["shared_transitive_static/res"],
1304 manifest: "shared_transitive_static/AndroidManifest.xml",
1305 use_resource_processor: %v,
1306 }
1307
Colin Crossff3ff7f2023-07-05 14:04:12 -07001308 android_library_import {
1309 name: "direct_import",
1310 sdk_version: "current",
1311 aars: ["direct_import.aar"],
1312 static_libs: ["direct_import_dep"],
1313 }
1314
1315 android_library_import {
1316 name: "direct_import_dep",
1317 sdk_version: "current",
1318 aars: ["direct_import_dep.aar"],
1319 }
1320
1321 android_library_import {
1322 name: "transitive_import",
1323 sdk_version: "current",
1324 aars: ["transitive_import.aar"],
1325 static_libs: ["transitive_import_dep"],
1326 }
1327
1328 android_library_import {
1329 name: "transitive_import_dep",
1330 sdk_version: "current",
1331 aars: ["transitive_import_dep.aar"],
1332 }
Colin Cross8676c8c2023-10-12 15:58:57 -07001333 `, testCase.appUsesRP, testCase.directLibUsesRP, testCase.transitiveLibUsesRP,
1334 testCase.sharedLibUsesRP, testCase.sharedTransitiveSharedLibUsesRP, testCase.sharedTransitiveStaticLibUsesRP)
Colin Crossff3ff7f2023-07-05 14:04:12 -07001335
1336 fs := android.MockFS{
Colin Cross8676c8c2023-10-12 15:58:57 -07001337 "app/res/values/strings.xml": nil,
1338 "direct/res/values/strings.xml": nil,
1339 "transitive/res/values/strings.xml": nil,
1340 "shared/res/values/strings.xml": nil,
1341 "shared_transitive_static/res/values/strings.xml": nil,
1342 "shared_transitive_shared/res/values/strings.xml": nil,
Colin Crossff3ff7f2023-07-05 14:04:12 -07001343 }
1344
1345 result := android.GroupFixturePreparers(
1346 PrepareForTestWithJavaDefaultModules,
Colin Crossff3ff7f2023-07-05 14:04:12 -07001347 fs.AddToFixture(),
1348 ).RunTestWithBp(t, bp)
1349
1350 type aaptInfo struct {
1351 resources, overlays, imports, srcJars, classpath, combined android.Paths
1352 }
1353
1354 getAaptInfo := func(moduleName string) (aaptInfo aaptInfo) {
Colin Cross90607e92025-02-11 14:58:07 -08001355 mod := result.ModuleForTests(t, moduleName, "android_common")
Colin Crossff3ff7f2023-07-05 14:04:12 -07001356 resourceListRule := mod.MaybeOutput("aapt2/res.list")
1357 overlayListRule := mod.MaybeOutput("aapt2/overlay.list")
1358 aaptRule := mod.Rule("aapt2Link")
1359 javacRule := mod.MaybeRule("javac")
1360 combinedRule := mod.MaybeOutput("combined/" + moduleName + ".jar")
1361
1362 aaptInfo.resources = resourceListRule.Inputs
1363 aaptInfo.overlays = overlayListRule.Inputs
1364
1365 aaptFlags := strings.Split(aaptRule.Args["flags"], " ")
1366 for i, flag := range aaptFlags {
1367 if flag == "-I" && i+1 < len(aaptFlags) {
1368 aaptInfo.imports = append(aaptInfo.imports, android.PathForTesting(aaptFlags[i+1]))
1369 }
1370 }
1371
1372 if len(javacRule.Args["srcJars"]) > 0 {
1373 aaptInfo.srcJars = android.PathsForTesting(strings.Split(javacRule.Args["srcJars"], " ")...)
1374 }
1375
1376 if len(javacRule.Args["classpath"]) > 0 {
1377 classpathArg := strings.TrimPrefix(javacRule.Args["classpath"], "-classpath ")
1378 aaptInfo.classpath = android.PathsForTesting(strings.Split(classpathArg, ":")...)
1379 }
1380
1381 aaptInfo.combined = combinedRule.Inputs
1382 return
1383 }
1384
1385 app := getAaptInfo("app")
1386 direct := getAaptInfo("direct")
1387 transitive := getAaptInfo("transitive")
Colin Cross8676c8c2023-10-12 15:58:57 -07001388 shared := getAaptInfo("shared")
Colin Crossff3ff7f2023-07-05 14:04:12 -07001389 directImport := getAaptInfo("direct_import")
1390 transitiveImport := getAaptInfo("transitive_import")
1391
1392 if !testCase.dontVerifyApp {
1393 android.AssertPathsRelativeToTopEquals(t, "app resources", testCase.appResources, app.resources)
1394 android.AssertPathsRelativeToTopEquals(t, "app overlays", testCase.appOverlays, app.overlays)
1395 android.AssertPathsRelativeToTopEquals(t, "app imports", testCase.appImports, app.imports)
1396 android.AssertPathsRelativeToTopEquals(t, "app srcjars", testCase.appSrcJars, app.srcJars)
1397 android.AssertPathsRelativeToTopEquals(t, "app classpath", testCase.appClasspath, app.classpath)
1398 android.AssertPathsRelativeToTopEquals(t, "app combined", testCase.appCombined, app.combined)
1399 }
1400
1401 if !testCase.dontVerifyDirect {
1402 android.AssertPathsRelativeToTopEquals(t, "direct resources", testCase.directResources, direct.resources)
1403 android.AssertPathsRelativeToTopEquals(t, "direct overlays", testCase.directOverlays, direct.overlays)
1404 android.AssertPathsRelativeToTopEquals(t, "direct imports", testCase.directImports, direct.imports)
1405 android.AssertPathsRelativeToTopEquals(t, "direct srcjars", testCase.directSrcJars, direct.srcJars)
1406 android.AssertPathsRelativeToTopEquals(t, "direct classpath", testCase.directClasspath, direct.classpath)
1407 android.AssertPathsRelativeToTopEquals(t, "direct combined", testCase.directCombined, direct.combined)
1408 }
1409
1410 if !testCase.dontVerifyTransitive {
1411 android.AssertPathsRelativeToTopEquals(t, "transitive resources", testCase.transitiveResources, transitive.resources)
1412 android.AssertPathsRelativeToTopEquals(t, "transitive overlays", testCase.transitiveOverlays, transitive.overlays)
1413 android.AssertPathsRelativeToTopEquals(t, "transitive imports", testCase.transitiveImports, transitive.imports)
1414 android.AssertPathsRelativeToTopEquals(t, "transitive srcjars", testCase.transitiveSrcJars, transitive.srcJars)
1415 android.AssertPathsRelativeToTopEquals(t, "transitive classpath", testCase.transitiveClasspath, transitive.classpath)
1416 android.AssertPathsRelativeToTopEquals(t, "transitive combined", testCase.transitiveCombined, transitive.combined)
1417 }
1418
Colin Cross8676c8c2023-10-12 15:58:57 -07001419 if !testCase.dontVerifyShared {
1420 android.AssertPathsRelativeToTopEquals(t, "shared resources", testCase.sharedResources, shared.resources)
1421 android.AssertPathsRelativeToTopEquals(t, "shared overlays", testCase.sharedOverlays, shared.overlays)
1422 android.AssertPathsRelativeToTopEquals(t, "shared imports", testCase.sharedImports, shared.imports)
1423 android.AssertPathsRelativeToTopEquals(t, "shared srcjars", testCase.sharedSrcJars, shared.srcJars)
1424 android.AssertPathsRelativeToTopEquals(t, "shared classpath", testCase.sharedClasspath, shared.classpath)
1425 android.AssertPathsRelativeToTopEquals(t, "shared combined", testCase.sharedCombined, shared.combined)
1426 }
1427
Colin Crossff3ff7f2023-07-05 14:04:12 -07001428 if !testCase.dontVerifyDirectImport {
1429 android.AssertPathsRelativeToTopEquals(t, "direct_import resources", testCase.directImportResources, directImport.resources)
1430 android.AssertPathsRelativeToTopEquals(t, "direct_import overlays", testCase.directImportOverlays, directImport.overlays)
1431 android.AssertPathsRelativeToTopEquals(t, "direct_import imports", testCase.directImportImports, directImport.imports)
1432 }
1433
1434 if !testCase.dontVerifyTransitiveImport {
1435 android.AssertPathsRelativeToTopEquals(t, "transitive_import resources", testCase.transitiveImportResources, transitiveImport.resources)
1436 android.AssertPathsRelativeToTopEquals(t, "transitive_import overlays", testCase.transitiveImportOverlays, transitiveImport.overlays)
1437 android.AssertPathsRelativeToTopEquals(t, "transitive_import imports", testCase.transitiveImportImports, transitiveImport.imports)
1438 }
1439 })
1440 }
1441}
1442
1443func TestAndroidResourceOverlays(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001444 t.Parallel()
Colin Crossc4441622024-09-18 14:55:49 -07001445 type moduleAndVariant struct {
1446 module string
1447 variant string
1448 }
1449
Colin Cross5c4791c2019-02-01 11:44:44 -08001450 testCases := []struct {
1451 name string
1452 enforceRROTargets []string
1453 enforceRROExcludedOverlays []string
Colin Crossc4441622024-09-18 14:55:49 -07001454 resourceFiles map[moduleAndVariant][]string
1455 overlayFiles map[moduleAndVariant][]string
1456 rroDirs map[moduleAndVariant][]string
Colin Cross5c4791c2019-02-01 11:44:44 -08001457 }{
1458 {
1459 name: "no RRO",
1460 enforceRROTargets: nil,
1461 enforceRROExcludedOverlays: nil,
Colin Crossc4441622024-09-18 14:55:49 -07001462 resourceFiles: map[moduleAndVariant][]string{
1463 {"foo", "android_common"}: nil,
1464 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
1465 {"lib", "android_common"}: nil,
1466 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
Colin Crossbec85302019-02-13 13:15:46 -08001467 },
Colin Crossc4441622024-09-18 14:55:49 -07001468 overlayFiles: map[moduleAndVariant][]string{
1469 {"foo", "android_common"}: {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001470 "out/soong/.intermediates/lib2/android_common/package-res.apk",
1471 "out/soong/.intermediates/lib/android_common/package-res.apk",
1472 "out/soong/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -08001473 "foo/res/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -08001474 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
1475 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Anton Hansson53c88442019-03-18 15:53:16 +00001476 "product/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -08001477 },
Colin Crossc4441622024-09-18 14:55:49 -07001478 {"bar", "android_common"}: {
Colin Cross5c4791c2019-02-01 11:44:44 -08001479 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
1480 "device/vendor/blah/overlay/bar/res/values/strings.xml",
1481 },
Colin Crossc4441622024-09-18 14:55:49 -07001482 {"lib", "android_common"}: {
Colin Crossbec85302019-02-13 13:15:46 -08001483 "lib/res/res/values/strings.xml",
1484 "device/vendor/blah/overlay/lib/res/values/strings.xml",
1485 },
Colin Cross5c4791c2019-02-01 11:44:44 -08001486 },
Colin Crossc4441622024-09-18 14:55:49 -07001487 rroDirs: map[moduleAndVariant][]string{
1488 {"foo", "android_common"}: nil,
1489 {"bar", "android_common"}: nil,
Colin Cross5c4791c2019-02-01 11:44:44 -08001490 },
1491 },
1492 {
1493 name: "enforce RRO on foo",
1494 enforceRROTargets: []string{"foo"},
1495 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossc4441622024-09-18 14:55:49 -07001496 resourceFiles: map[moduleAndVariant][]string{
1497 {"foo", "android_common"}: nil,
1498 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
1499 {"lib", "android_common"}: nil,
1500 {"lib", "android_common_rro"}: nil,
1501 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
1502 {"lib2", "android_common_rro"}: {"lib2/res/res/values/strings.xml"},
Colin Crossbec85302019-02-13 13:15:46 -08001503 },
Colin Crossc4441622024-09-18 14:55:49 -07001504 overlayFiles: map[moduleAndVariant][]string{
1505 {"foo", "android_common"}: {
1506 "out/soong/.intermediates/lib2/android_common_rro/package-res.apk",
1507 "out/soong/.intermediates/lib/android_common_rro/package-res.apk",
1508 "out/soong/.intermediates/lib3/android_common_rro/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -08001509 "foo/res/res/values/strings.xml",
1510 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
1511 },
Colin Crossc4441622024-09-18 14:55:49 -07001512 {"bar", "android_common"}: {
Colin Cross5c4791c2019-02-01 11:44:44 -08001513 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
1514 "device/vendor/blah/overlay/bar/res/values/strings.xml",
1515 },
Colin Crossc4441622024-09-18 14:55:49 -07001516 {"lib", "android_common"}: {
Colin Crossbec85302019-02-13 13:15:46 -08001517 "lib/res/res/values/strings.xml",
Colin Crossc4441622024-09-18 14:55:49 -07001518 "device/vendor/blah/overlay/lib/res/values/strings.xml",
1519 },
1520 {"lib", "android_common_rro"}: {
Colin Crossc4441622024-09-18 14:55:49 -07001521 "lib/res/res/values/strings.xml",
Colin Crossbec85302019-02-13 13:15:46 -08001522 },
Colin Cross5c4791c2019-02-01 11:44:44 -08001523 },
Colin Crossc1c37552019-01-31 11:42:41 -08001524
Colin Crossc4441622024-09-18 14:55:49 -07001525 rroDirs: map[moduleAndVariant][]string{
1526 {"foo", "android_common"}: {
Anton Hansson53c88442019-03-18 15:53:16 +00001527 "device:device/vendor/blah/overlay/foo/res",
Anton Hansson53c88442019-03-18 15:53:16 +00001528 "product:product/vendor/blah/overlay/foo/res",
Jaewoong Jungc779cd42020-10-06 18:56:10 -07001529 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -08001530 },
Colin Crossc4441622024-09-18 14:55:49 -07001531 {"bar", "android_common"}: nil,
1532 {"lib", "android_common"}: nil,
1533 {"lib", "android_common_rro"}: {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -08001534 },
1535 },
1536 {
1537 name: "enforce RRO on all",
1538 enforceRROTargets: []string{"*"},
1539 enforceRROExcludedOverlays: []string{
1540 // Excluding specific apps/res directories also allowed.
1541 "device/vendor/blah/static_overlay/foo",
1542 "device/vendor/blah/static_overlay/bar/res",
1543 },
Colin Crossc4441622024-09-18 14:55:49 -07001544 resourceFiles: map[moduleAndVariant][]string{
1545 {"foo", "android_common"}: nil,
1546 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
1547 {"lib", "android_common"}: nil,
1548 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
Colin Crossbec85302019-02-13 13:15:46 -08001549 },
Colin Crossc4441622024-09-18 14:55:49 -07001550 overlayFiles: map[moduleAndVariant][]string{
1551 {"foo", "android_common"}: {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001552 "out/soong/.intermediates/lib2/android_common/package-res.apk",
1553 "out/soong/.intermediates/lib/android_common/package-res.apk",
1554 "out/soong/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -08001555 "foo/res/res/values/strings.xml",
1556 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
1557 },
Colin Crossc4441622024-09-18 14:55:49 -07001558 {"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
1559 {"lib", "android_common"}: {
Colin Crossbec85302019-02-13 13:15:46 -08001560 "lib/res/res/values/strings.xml",
1561 },
Colin Cross5c4791c2019-02-01 11:44:44 -08001562 },
Colin Crossc4441622024-09-18 14:55:49 -07001563 rroDirs: map[moduleAndVariant][]string{
1564 {"foo", "android_common"}: {
Anton Hansson53c88442019-03-18 15:53:16 +00001565 "device:device/vendor/blah/overlay/foo/res",
1566 "product:product/vendor/blah/overlay/foo/res",
1567 // Lib dep comes after the direct deps
1568 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -08001569 },
Colin Crossc4441622024-09-18 14:55:49 -07001570 {"bar", "android_common"}: {"device:device/vendor/blah/overlay/bar/res"},
1571 {"lib", "android_common"}: {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -08001572 },
1573 },
1574 }
1575
Anton Hansson53c88442019-03-18 15:53:16 +00001576 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -08001577 "device/vendor/blah/overlay",
1578 "device/vendor/blah/overlay2",
1579 "device/vendor/blah/static_overlay",
1580 }
1581
Anton Hansson53c88442019-03-18 15:53:16 +00001582 productResourceOverlays := []string{
1583 "product/vendor/blah/overlay",
1584 }
1585
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001586 fs := android.MockFS{
Colin Cross890ff552017-11-30 20:13:19 -08001587 "foo/res/res/values/strings.xml": nil,
1588 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -08001589 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -08001590 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -08001591 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
1592 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -08001593 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -08001594 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
1595 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
1596 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +00001597 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -08001598 }
1599
1600 bp := `
1601 android_app {
1602 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001603 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -08001604 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +00001605 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -08001606 }
1607
1608 android_app {
1609 name: "bar",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001610 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -08001611 resource_dirs: ["bar/res"],
1612 }
Colin Cross6ed7dea2019-01-31 14:44:30 -08001613
1614 android_library {
1615 name: "lib",
Jeongik Cha75b83b02019-11-01 15:28:00 +09001616 sdk_version: "current",
Colin Cross6ed7dea2019-01-31 14:44:30 -08001617 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -08001618 static_libs: ["lib2"],
1619 }
1620
1621 android_library {
1622 name: "lib2",
Jeongik Cha75b83b02019-11-01 15:28:00 +09001623 sdk_version: "current",
Colin Crossbec85302019-02-13 13:15:46 -08001624 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -08001625 }
Anton Hansson53c88442019-03-18 15:53:16 +00001626
1627 // This library has the same resources as lib (should not lead to dupe RROs)
1628 android_library {
1629 name: "lib3",
Jeongik Cha75b83b02019-11-01 15:28:00 +09001630 sdk_version: "current",
Anton Hansson53c88442019-03-18 15:53:16 +00001631 resource_dirs: ["lib/res"]
1632 }
Colin Cross890ff552017-11-30 20:13:19 -08001633 `
1634
Colin Cross5c4791c2019-02-01 11:44:44 -08001635 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -08001636 t.Run(testCase.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001637 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001638 result := android.GroupFixturePreparers(
1639 PrepareForTestWithJavaDefaultModules,
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001640 fs.AddToFixture(),
1641 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1642 variables.DeviceResourceOverlays = deviceResourceOverlays
1643 variables.ProductResourceOverlays = productResourceOverlays
1644 if testCase.enforceRROTargets != nil {
1645 variables.EnforceRROTargets = testCase.enforceRROTargets
1646 }
1647 if testCase.enforceRROExcludedOverlays != nil {
1648 variables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
1649 }
1650 }),
1651 ).RunTestWithBp(t, bp)
Colin Cross890ff552017-11-30 20:13:19 -08001652
Colin Crossbec85302019-02-13 13:15:46 -08001653 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
1654 for _, o := range list {
1655 res := module.MaybeOutput(o)
1656 if res.Rule != nil {
Colin Crossc4441622024-09-18 14:55:49 -07001657 // If the overlay is compiled as part of this moduleAndVariant (i.e. a .arsc.flat file),
Colin Crossbec85302019-02-13 13:15:46 -08001658 // verify the inputs to the .arsc.flat rule.
1659 files = append(files, res.Inputs.Strings()...)
1660 } else {
Colin Crossc4441622024-09-18 14:55:49 -07001661 // Otherwise, verify the full path to the output of the other moduleAndVariant
Colin Crossbec85302019-02-13 13:15:46 -08001662 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +00001663 }
Colin Cross890ff552017-11-30 20:13:19 -08001664 }
Colin Crossbec85302019-02-13 13:15:46 -08001665 return files
Colin Cross890ff552017-11-30 20:13:19 -08001666 }
1667
Colin Crossc4441622024-09-18 14:55:49 -07001668 getResources := func(moduleName, variantName string) (resourceFiles, overlayFiles, rroDirs []string) {
Colin Cross90607e92025-02-11 14:58:07 -08001669 module := result.ModuleForTests(t, moduleName, variantName)
Colin Crossbec85302019-02-13 13:15:46 -08001670 resourceList := module.MaybeOutput("aapt2/res.list")
1671 if resourceList.Rule != nil {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001672 resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs))
Anton Hansson0375a4f2019-01-24 14:39:19 +00001673 }
Colin Crossbec85302019-02-13 13:15:46 -08001674 overlayList := module.MaybeOutput("aapt2/overlay.list")
1675 if overlayList.Rule != nil {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001676 overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs))
Colin Crossbec85302019-02-13 13:15:46 -08001677 }
1678
Colin Crossab8d1382023-07-14 17:23:41 +00001679 for _, d := range module.Module().(AndroidLibraryDependency).RRODirsDepSet().ToList() {
Anton Hansson53c88442019-03-18 15:53:16 +00001680 var prefix string
1681 if d.overlayType == device {
1682 prefix = "device:"
1683 } else if d.overlayType == product {
1684 prefix = "product:"
1685 } else {
1686 t.Fatalf("Unexpected overlayType %d", d.overlayType)
1687 }
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001688 rroDirs = append(rroDirs, prefix+android.PathRelativeToTop(d.path))
Anton Hansson53c88442019-03-18 15:53:16 +00001689 }
Colin Crossbec85302019-02-13 13:15:46 -08001690
1691 return resourceFiles, overlayFiles, rroDirs
1692 }
1693
Colin Crossc4441622024-09-18 14:55:49 -07001694 modules := []moduleAndVariant{
1695 {"foo", "android_common"},
1696 {"foo", "android_common_rro"},
1697 {"bar", "android_common"},
1698 {"bar", "android_common_rro"},
1699 {"lib", "android_common"},
1700 {"lib", "android_common_rro"},
1701 {"lib2", "android_common"},
1702 {"lib2", "android_common_rro"},
1703 }
1704 for _, moduleAndVariant := range modules {
1705 if _, exists := testCase.resourceFiles[moduleAndVariant]; !exists {
1706 continue
1707 }
1708 resourceFiles, overlayFiles, rroDirs := getResources(moduleAndVariant.module, moduleAndVariant.variant)
Colin Crossbec85302019-02-13 13:15:46 -08001709
Colin Crossc4441622024-09-18 14:55:49 -07001710 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[moduleAndVariant]) {
Colin Crossbec85302019-02-13 13:15:46 -08001711 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
Colin Crossc4441622024-09-18 14:55:49 -07001712 moduleAndVariant, testCase.resourceFiles[moduleAndVariant], resourceFiles)
Colin Crossbec85302019-02-13 13:15:46 -08001713 }
Colin Crossc4441622024-09-18 14:55:49 -07001714 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[moduleAndVariant]) {
Colin Crossbec85302019-02-13 13:15:46 -08001715 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
Colin Crossc4441622024-09-18 14:55:49 -07001716 moduleAndVariant, testCase.overlayFiles[moduleAndVariant], overlayFiles)
Colin Crossbec85302019-02-13 13:15:46 -08001717 }
Colin Crossc4441622024-09-18 14:55:49 -07001718 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[moduleAndVariant]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +00001719 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossc4441622024-09-18 14:55:49 -07001720 moduleAndVariant, testCase.rroDirs[moduleAndVariant], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +00001721 }
Colin Cross890ff552017-11-30 20:13:19 -08001722 }
Colin Cross890ff552017-11-30 20:13:19 -08001723 })
1724 }
1725}
Colin Crossd09b0b62018-04-18 11:06:47 -07001726
Paul Duffincdb88a92021-03-14 00:36:50 +00001727func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) {
Colin Cross90607e92025-02-11 14:58:07 -08001728 foo := result.ModuleForTests(t, "foo", "android_common")
Jeongik Cha219141c2020-08-06 23:00:37 +09001729 link := foo.Output("package-res.apk")
1730 linkFlags := strings.Split(link.Args["flags"], " ")
1731 min := android.IndexList("--min-sdk-version", linkFlags)
1732 target := android.IndexList("--target-sdk-version", linkFlags)
1733
1734 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
1735 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
1736 }
1737
1738 gotMinSdkVersion := linkFlags[min+1]
1739 gotTargetSdkVersion := linkFlags[target+1]
1740
Paul Duffincdb88a92021-03-14 00:36:50 +00001741 android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion)
Jeongik Cha219141c2020-08-06 23:00:37 +09001742
Paul Duffincdb88a92021-03-14 00:36:50 +00001743 android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion)
Jeongik Cha219141c2020-08-06 23:00:37 +09001744}
1745
Colin Crossd09b0b62018-04-18 11:06:47 -07001746func TestAppSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001747 t.Parallel()
Colin Crossd09b0b62018-04-18 11:06:47 -07001748 testCases := []struct {
1749 name string
1750 sdkVersion string
1751 platformSdkInt int
1752 platformSdkCodename string
1753 platformSdkFinal bool
Spandan Dasffb31af2023-03-01 19:46:18 +00001754 minSdkVersionBp string
Colin Crossd09b0b62018-04-18 11:06:47 -07001755 expectedMinSdkVersion string
Jeongik Cha538c0d02019-07-11 15:54:27 +09001756 platformApis bool
Dan Albert4f378d72020-07-23 17:32:15 -07001757 activeCodenames []string
Colin Crossd09b0b62018-04-18 11:06:47 -07001758 }{
1759 {
1760 name: "current final SDK",
1761 sdkVersion: "current",
1762 platformSdkInt: 27,
1763 platformSdkCodename: "REL",
1764 platformSdkFinal: true,
1765 expectedMinSdkVersion: "27",
1766 },
1767 {
1768 name: "current non-final SDK",
1769 sdkVersion: "current",
1770 platformSdkInt: 27,
1771 platformSdkCodename: "OMR1",
1772 platformSdkFinal: false,
1773 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001774 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001775 },
1776 {
1777 name: "default final SDK",
1778 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001779 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001780 platformSdkInt: 27,
1781 platformSdkCodename: "REL",
1782 platformSdkFinal: true,
1783 expectedMinSdkVersion: "27",
1784 },
1785 {
1786 name: "default non-final SDK",
1787 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001788 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001789 platformSdkInt: 27,
1790 platformSdkCodename: "OMR1",
1791 platformSdkFinal: false,
1792 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001793 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001794 },
1795 {
1796 name: "14",
1797 sdkVersion: "14",
1798 expectedMinSdkVersion: "14",
Dan Albert4f378d72020-07-23 17:32:15 -07001799 platformSdkCodename: "S",
1800 activeCodenames: []string{"S"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001801 },
Spandan Dasffb31af2023-03-01 19:46:18 +00001802 {
1803 name: "two active SDKs",
1804 sdkVersion: "module_current",
1805 minSdkVersionBp: "UpsideDownCake",
1806 expectedMinSdkVersion: "UpsideDownCake", // And not VanillaIceCream
1807 platformSdkCodename: "VanillaIceCream",
1808 activeCodenames: []string{"UpsideDownCake", "VanillaIceCream"},
1809 },
Colin Crossd09b0b62018-04-18 11:06:47 -07001810 }
1811
1812 for _, moduleType := range []string{"android_app", "android_library"} {
1813 for _, test := range testCases {
1814 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001815 t.Parallel()
Jeongik Cha538c0d02019-07-11 15:54:27 +09001816 platformApiProp := ""
1817 if test.platformApis {
1818 platformApiProp = "platform_apis: true,"
1819 }
Spandan Dasffb31af2023-03-01 19:46:18 +00001820 minSdkVersionProp := ""
1821 if test.minSdkVersionBp != "" {
1822 minSdkVersionProp = fmt.Sprintf(` min_sdk_version: "%s",`, test.minSdkVersionBp)
1823 }
Colin Crossd09b0b62018-04-18 11:06:47 -07001824 bp := fmt.Sprintf(`%s {
1825 name: "foo",
1826 srcs: ["a.java"],
1827 sdk_version: "%s",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001828 %s
Spandan Dasffb31af2023-03-01 19:46:18 +00001829 %s
1830 }`, moduleType, test.sdkVersion, platformApiProp, minSdkVersionProp)
Colin Crossd09b0b62018-04-18 11:06:47 -07001831
Paul Duffin71ae5942021-03-22 15:36:52 +00001832 result := android.GroupFixturePreparers(
1833 prepareForJavaTest,
Paul Duffincdb88a92021-03-14 00:36:50 +00001834 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1835 variables.Platform_sdk_version = &test.platformSdkInt
1836 variables.Platform_sdk_codename = &test.platformSdkCodename
1837 variables.Platform_version_active_codenames = test.activeCodenames
1838 variables.Platform_sdk_final = &test.platformSdkFinal
1839 }),
Paul Duffin2645a292021-03-13 02:36:00 +00001840 FixtureWithPrebuiltApis(map[string][]string{
1841 "14": {"foo"},
1842 }),
Paul Duffincdb88a92021-03-14 00:36:50 +00001843 ).RunTestWithBp(t, bp)
Colin Crossd09b0b62018-04-18 11:06:47 -07001844
Paul Duffincdb88a92021-03-14 00:36:50 +00001845 checkSdkVersion(t, result, test.expectedMinSdkVersion)
Colin Crossd09b0b62018-04-18 11:06:47 -07001846 })
1847 }
1848 }
1849}
Colin Crossa4f08812018-10-02 22:03:40 -07001850
Jeongik Cha219141c2020-08-06 23:00:37 +09001851func TestVendorAppSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001852 t.Parallel()
Jeongik Cha219141c2020-08-06 23:00:37 +09001853 testCases := []struct {
1854 name string
1855 sdkVersion string
1856 platformSdkInt int
1857 platformSdkCodename string
1858 platformSdkFinal bool
1859 deviceCurrentApiLevelForVendorModules string
1860 expectedMinSdkVersion string
1861 }{
1862 {
1863 name: "current final SDK",
1864 sdkVersion: "current",
1865 platformSdkInt: 29,
1866 platformSdkCodename: "REL",
1867 platformSdkFinal: true,
1868 deviceCurrentApiLevelForVendorModules: "29",
1869 expectedMinSdkVersion: "29",
1870 },
1871 {
1872 name: "current final SDK",
1873 sdkVersion: "current",
1874 platformSdkInt: 29,
1875 platformSdkCodename: "REL",
1876 platformSdkFinal: true,
1877 deviceCurrentApiLevelForVendorModules: "28",
1878 expectedMinSdkVersion: "28",
1879 },
1880 {
1881 name: "current final SDK",
1882 sdkVersion: "current",
1883 platformSdkInt: 29,
1884 platformSdkCodename: "Q",
1885 platformSdkFinal: false,
Jeongik Cha219141c2020-08-06 23:00:37 +09001886 deviceCurrentApiLevelForVendorModules: "28",
1887 expectedMinSdkVersion: "28",
1888 },
1889 }
1890
1891 for _, moduleType := range []string{"android_app", "android_library"} {
1892 for _, sdkKind := range []string{"", "system_"} {
1893 for _, test := range testCases {
1894 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001895 t.Parallel()
Jeongik Cha219141c2020-08-06 23:00:37 +09001896 bp := fmt.Sprintf(`%s {
1897 name: "foo",
1898 srcs: ["a.java"],
1899 sdk_version: "%s%s",
1900 vendor: true,
1901 }`, moduleType, sdkKind, test.sdkVersion)
1902
Paul Duffin71ae5942021-03-22 15:36:52 +00001903 result := android.GroupFixturePreparers(
1904 prepareForJavaTest,
Paul Duffincdb88a92021-03-14 00:36:50 +00001905 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1906 variables.Platform_sdk_version = &test.platformSdkInt
1907 variables.Platform_sdk_codename = &test.platformSdkCodename
1908 variables.Platform_sdk_final = &test.platformSdkFinal
1909 variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
1910 variables.DeviceSystemSdkVersions = []string{"28", "29"}
1911 }),
Paul Duffin2645a292021-03-13 02:36:00 +00001912 FixtureWithPrebuiltApis(map[string][]string{
1913 "28": {"foo"},
1914 "29": {"foo"},
1915 "current": {"foo"},
1916 }),
Paul Duffincdb88a92021-03-14 00:36:50 +00001917 ).RunTestWithBp(t, bp)
1918
1919 checkSdkVersion(t, result, test.expectedMinSdkVersion)
Jeongik Cha219141c2020-08-06 23:00:37 +09001920 })
1921 }
1922 }
1923 }
1924}
1925
Paul Duffin50c217c2019-06-12 13:25:22 +01001926func TestJNIABI(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001927 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001928 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001929 cc_library {
1930 name: "libjni",
1931 system_shared_libs: [],
Colin Crossc511bc52020-04-07 16:50:32 +00001932 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001933 stl: "none",
1934 }
1935
1936 android_test {
1937 name: "test",
1938 sdk_version: "core_platform",
1939 jni_libs: ["libjni"],
1940 }
1941
1942 android_test {
1943 name: "test_first",
1944 sdk_version: "core_platform",
1945 compile_multilib: "first",
1946 jni_libs: ["libjni"],
1947 }
1948
1949 android_test {
1950 name: "test_both",
1951 sdk_version: "core_platform",
1952 compile_multilib: "both",
1953 jni_libs: ["libjni"],
1954 }
1955
1956 android_test {
1957 name: "test_32",
1958 sdk_version: "core_platform",
1959 compile_multilib: "32",
1960 jni_libs: ["libjni"],
1961 }
1962
1963 android_test {
1964 name: "test_64",
1965 sdk_version: "core_platform",
1966 compile_multilib: "64",
1967 jni_libs: ["libjni"],
1968 }
1969 `)
1970
1971 testCases := []struct {
1972 name string
1973 abis []string
1974 }{
1975 {"test", []string{"arm64-v8a"}},
1976 {"test_first", []string{"arm64-v8a"}},
1977 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
1978 {"test_32", []string{"armeabi-v7a"}},
1979 {"test_64", []string{"arm64-v8a"}},
1980 }
1981
1982 for _, test := range testCases {
1983 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001984 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08001985 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Crossb3168ba2023-07-26 16:14:56 -07001986 jniLibZip := app.Output("jnilibs.zip")
Paul Duffin50c217c2019-06-12 13:25:22 +01001987 var abis []string
1988 args := strings.Fields(jniLibZip.Args["jarArgs"])
1989 for i := 0; i < len(args); i++ {
1990 if args[i] == "-P" {
1991 abis = append(abis, filepath.Base(args[i+1]))
1992 i++
1993 }
1994 }
1995 if !reflect.DeepEqual(abis, test.abis) {
1996 t.Errorf("want abis %v, got %v", test.abis, abis)
1997 }
1998 })
1999 }
2000}
2001
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002002func TestAppSdkVersionByPartition(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002003 t.Parallel()
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002004 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
2005 android_app {
2006 name: "foo",
2007 srcs: ["a.java"],
2008 vendor: true,
2009 platform_apis: true,
2010 }
2011 `)
2012
2013 testJava(t, `
2014 android_app {
2015 name: "bar",
2016 srcs: ["b.java"],
2017 platform_apis: true,
2018 }
2019 `)
2020
2021 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002022 bp := `
2023 android_app {
2024 name: "foo",
2025 srcs: ["a.java"],
2026 product_specific: true,
2027 platform_apis: true,
2028 }
2029 `
Colin Cross98be1bb2019-12-13 20:41:13 -08002030
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002031 errorHandler := android.FixtureExpectsNoErrors
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002032 if enforce {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002033 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product")
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002034 }
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002035
2036 android.GroupFixturePreparers(
2037 PrepareForTestWithJavaDefaultModules,
2038 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2039 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
2040 }),
2041 ).
2042 ExtendWithErrorHandler(errorHandler).
2043 RunTestWithBp(t, bp)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002044 }
2045}
2046
Paul Duffin50c217c2019-06-12 13:25:22 +01002047func TestJNIPackaging(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002048 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002049 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01002050 cc_library {
2051 name: "libjni",
2052 system_shared_libs: [],
2053 stl: "none",
Colin Cross094cde42020-02-15 10:38:00 -08002054 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002055 }
2056
2057 android_app {
2058 name: "app",
2059 jni_libs: ["libjni"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002060 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002061 }
2062
2063 android_app {
2064 name: "app_noembed",
2065 jni_libs: ["libjni"],
2066 use_embedded_native_libs: false,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002067 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002068 }
2069
2070 android_app {
2071 name: "app_embed",
2072 jni_libs: ["libjni"],
2073 use_embedded_native_libs: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002074 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002075 }
2076
2077 android_test {
2078 name: "test",
Colin Crossc511bc52020-04-07 16:50:32 +00002079 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002080 jni_libs: ["libjni"],
2081 }
2082
2083 android_test {
2084 name: "test_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00002085 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002086 jni_libs: ["libjni"],
2087 use_embedded_native_libs: false,
2088 }
2089
2090 android_test_helper_app {
2091 name: "test_helper",
Colin Crossc511bc52020-04-07 16:50:32 +00002092 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002093 jni_libs: ["libjni"],
2094 }
2095
2096 android_test_helper_app {
2097 name: "test_helper_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00002098 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002099 jni_libs: ["libjni"],
2100 use_embedded_native_libs: false,
2101 }
2102 `)
2103
2104 testCases := []struct {
2105 name string
2106 packaged bool
2107 compressed bool
2108 }{
Jiyong Parkd044bb42024-05-15 02:09:54 +09002109 {"app", false, false},
2110 {"app_noembed", false, false},
Paul Duffin50c217c2019-06-12 13:25:22 +01002111 {"app_embed", true, false},
2112 {"test", true, false},
2113 {"test_noembed", true, true},
2114 {"test_helper", true, false},
2115 {"test_helper_noembed", true, true},
2116 }
2117
2118 for _, test := range testCases {
2119 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002120 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08002121 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Crossb3168ba2023-07-26 16:14:56 -07002122 jniLibZip := app.MaybeOutput("jnilibs.zip")
Paul Duffin50c217c2019-06-12 13:25:22 +01002123 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
2124 t.Errorf("expected jni packaged %v, got %v", w, g)
2125 }
2126
2127 if jniLibZip.Rule != nil {
2128 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
2129 t.Errorf("expected jni compressed %v, got %v", w, g)
2130 }
Colin Crossc511bc52020-04-07 16:50:32 +00002131
2132 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
2133 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
2134 }
Paul Duffin50c217c2019-06-12 13:25:22 +01002135 }
2136 })
2137 }
Colin Cross47fa9d32019-03-26 10:51:39 -07002138}
2139
Colin Cross3c007702020-05-08 11:20:24 -07002140func TestJNISDK(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002141 t.Parallel()
Colin Cross3c007702020-05-08 11:20:24 -07002142 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
2143 cc_library {
2144 name: "libjni",
2145 system_shared_libs: [],
2146 stl: "none",
2147 sdk_version: "current",
2148 }
2149
2150 android_test {
2151 name: "app_platform",
2152 jni_libs: ["libjni"],
2153 platform_apis: true,
2154 }
2155
2156 android_test {
2157 name: "app_sdk",
2158 jni_libs: ["libjni"],
2159 sdk_version: "current",
2160 }
2161
2162 android_test {
2163 name: "app_force_platform",
2164 jni_libs: ["libjni"],
2165 sdk_version: "current",
2166 jni_uses_platform_apis: true,
2167 }
2168
2169 android_test {
2170 name: "app_force_sdk",
2171 jni_libs: ["libjni"],
2172 platform_apis: true,
2173 jni_uses_sdk_apis: true,
2174 }
Colin Crossc2d24052020-05-13 11:05:02 -07002175
2176 cc_library {
2177 name: "libvendorjni",
2178 system_shared_libs: [],
2179 stl: "none",
2180 vendor: true,
2181 }
2182
2183 android_test {
2184 name: "app_vendor",
2185 jni_libs: ["libvendorjni"],
2186 sdk_version: "current",
2187 vendor: true,
2188 }
Colin Cross3c007702020-05-08 11:20:24 -07002189 `)
2190
2191 testCases := []struct {
Colin Crossc2d24052020-05-13 11:05:02 -07002192 name string
2193 sdkJNI bool
2194 vendorJNI bool
Colin Cross3c007702020-05-08 11:20:24 -07002195 }{
Colin Crossc2d24052020-05-13 11:05:02 -07002196 {name: "app_platform"},
2197 {name: "app_sdk", sdkJNI: true},
2198 {name: "app_force_platform"},
2199 {name: "app_force_sdk", sdkJNI: true},
2200 {name: "app_vendor", vendorJNI: true},
Colin Cross3c007702020-05-08 11:20:24 -07002201 }
2202
Colin Cross90607e92025-02-11 14:58:07 -08002203 platformJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_shared").
Colin Crossc2d24052020-05-13 11:05:02 -07002204 Output("libjni.so").Output.String()
Colin Cross90607e92025-02-11 14:58:07 -08002205 sdkJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_sdk_shared").
Colin Crossc2d24052020-05-13 11:05:02 -07002206 Output("libjni.so").Output.String()
Colin Cross90607e92025-02-11 14:58:07 -08002207 vendorJNI := ctx.ModuleForTests(t, "libvendorjni", "android_vendor_arm64_armv8-a_shared").
Colin Crossc2d24052020-05-13 11:05:02 -07002208 Output("libvendorjni.so").Output.String()
2209
Colin Cross3c007702020-05-08 11:20:24 -07002210 for _, test := range testCases {
2211 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002212 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08002213 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Cross3c007702020-05-08 11:20:24 -07002214
Colin Crossb3168ba2023-07-26 16:14:56 -07002215 jniLibZip := app.MaybeOutput("jnilibs.zip")
Colin Cross3c007702020-05-08 11:20:24 -07002216 if len(jniLibZip.Implicits) != 1 {
2217 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
2218 }
2219 gotJNI := jniLibZip.Implicits[0].String()
2220
2221 if test.sdkJNI {
2222 if gotJNI != sdkJNI {
2223 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI)
2224 }
Colin Crossc2d24052020-05-13 11:05:02 -07002225 } else if test.vendorJNI {
2226 if gotJNI != vendorJNI {
2227 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI)
2228 }
Colin Cross3c007702020-05-08 11:20:24 -07002229 } else {
2230 if gotJNI != platformJNI {
2231 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI)
2232 }
2233 }
2234 })
2235 }
2236
2237 t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002238 t.Parallel()
Colin Cross3c007702020-05-08 11:20:24 -07002239 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
2240 android_test {
2241 name: "app_platform",
2242 platform_apis: true,
2243 jni_uses_platform_apis: true,
2244 }
2245 `)
2246 })
2247
2248 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002249 t.Parallel()
Colin Cross3c007702020-05-08 11:20:24 -07002250 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
2251 android_test {
2252 name: "app_sdk",
2253 sdk_version: "current",
2254 jni_uses_sdk_apis: true,
2255 }
2256 `)
2257 })
2258
2259}
2260
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002261func TestCertificates(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002262 t.Parallel()
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002263 testCases := []struct {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002264 name string
2265 bp string
Colin Cross5caad2b2022-12-12 15:11:46 -08002266 allowMissingDependencies bool
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002267 certificateOverride string
2268 expectedCertSigningFlags string
2269 expectedCertificate string
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002270 }{
2271 {
2272 name: "default",
2273 bp: `
2274 android_app {
2275 name: "foo",
2276 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002277 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002278 }
2279 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002280 certificateOverride: "",
2281 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002282 expectedCertificate: "build/make/target/product/security/testkey",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002283 },
2284 {
2285 name: "module certificate property",
2286 bp: `
2287 android_app {
2288 name: "foo",
2289 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002290 certificate: ":new_certificate",
2291 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002292 }
2293
2294 android_app_certificate {
2295 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07002296 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002297 }
2298 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002299 certificateOverride: "",
2300 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002301 expectedCertificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002302 },
2303 {
2304 name: "path certificate property",
2305 bp: `
2306 android_app {
2307 name: "foo",
2308 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002309 certificate: "expiredkey",
2310 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002311 }
2312 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002313 certificateOverride: "",
2314 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002315 expectedCertificate: "build/make/target/product/security/expiredkey",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002316 },
2317 {
2318 name: "certificate overrides",
2319 bp: `
2320 android_app {
2321 name: "foo",
2322 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002323 certificate: "expiredkey",
2324 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002325 }
2326
2327 android_app_certificate {
2328 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07002329 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002330 }
2331 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002332 certificateOverride: "foo:new_certificate",
2333 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002334 expectedCertificate: "cert/new_cert",
Liz Kammere2b27f42020-05-07 13:24:05 -07002335 },
2336 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002337 name: "certificate signing flags",
Liz Kammere2b27f42020-05-07 13:24:05 -07002338 bp: `
2339 android_app {
2340 name: "foo",
2341 srcs: ["a.java"],
2342 certificate: ":new_certificate",
2343 lineage: "lineage.bin",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002344 rotationMinSdkVersion: "32",
Liz Kammere2b27f42020-05-07 13:24:05 -07002345 sdk_version: "current",
2346 }
2347
2348 android_app_certificate {
2349 name: "new_certificate",
2350 certificate: "cert/new_cert",
2351 }
2352 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002353 certificateOverride: "",
2354 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
Colin Cross5caad2b2022-12-12 15:11:46 -08002355 expectedCertificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002356 },
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002357 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002358 name: "cert signing flags from filegroup",
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002359 bp: `
2360 android_app {
2361 name: "foo",
2362 srcs: ["a.java"],
2363 certificate: ":new_certificate",
2364 lineage: ":lineage_bin",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002365 rotationMinSdkVersion: "32",
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002366 sdk_version: "current",
2367 }
2368
2369 android_app_certificate {
2370 name: "new_certificate",
2371 certificate: "cert/new_cert",
2372 }
2373
2374 filegroup {
2375 name: "lineage_bin",
2376 srcs: ["lineage.bin"],
2377 }
2378 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002379 certificateOverride: "",
2380 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
Colin Cross5caad2b2022-12-12 15:11:46 -08002381 expectedCertificate: "cert/new_cert",
2382 },
2383 {
2384 name: "missing with AllowMissingDependencies",
2385 bp: `
2386 android_app {
2387 name: "foo",
2388 srcs: ["a.java"],
2389 certificate: ":new_certificate",
2390 sdk_version: "current",
2391 }
2392 `,
2393 expectedCertificate: "out/soong/.intermediates/foo/android_common/missing",
2394 allowMissingDependencies: true,
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002395 },
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002396 }
2397
2398 for _, test := range testCases {
2399 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002400 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002401 result := android.GroupFixturePreparers(
2402 PrepareForTestWithJavaDefaultModules,
2403 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2404 if test.certificateOverride != "" {
2405 variables.CertificateOverrides = []string{test.certificateOverride}
2406 }
Colin Cross5caad2b2022-12-12 15:11:46 -08002407 if test.allowMissingDependencies {
2408 variables.Allow_missing_dependencies = proptools.BoolPtr(true)
2409 }
2410 }),
2411 android.FixtureModifyContext(func(ctx *android.TestContext) {
2412 ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002413 }),
2414 ).RunTestWithBp(t, test.bp)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002415
Colin Cross90607e92025-02-11 14:58:07 -08002416 foo := result.ModuleForTests(t, "foo", "android_common")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002417
Colin Cross5caad2b2022-12-12 15:11:46 -08002418 certificate := foo.Module().(*AndroidApp).certificate
2419 android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key)
2420 // The sign_target_files_apks and check_target_files_signatures
2421 // tools require that certificates have a .x509.pem extension.
2422 android.AssertPathRelativeToTopEquals(t, "certificates pem", test.expectedCertificate+".x509.pem", certificate.Pem)
Liz Kammere2b27f42020-05-07 13:24:05 -07002423
Colin Cross5caad2b2022-12-12 15:11:46 -08002424 signapk := foo.Output("foo.apk")
2425 if signapk.Rule != android.ErrorRule {
2426 signCertificateFlags := signapk.Args["certificates"]
2427 expectedFlags := certificate.Pem.String() + " " + certificate.Key.String()
2428 android.AssertStringEquals(t, "certificates flags", expectedFlags, signCertificateFlags)
2429
2430 certSigningFlags := signapk.Args["flags"]
2431 android.AssertStringEquals(t, "cert signing flags", test.expectedCertSigningFlags, certSigningFlags)
2432 }
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002433 })
2434 }
2435}
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002436
Songchun Fan688de9a2020-03-24 20:32:24 -07002437func TestRequestV4SigningFlag(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002438 t.Parallel()
Songchun Fan688de9a2020-03-24 20:32:24 -07002439 testCases := []struct {
2440 name string
2441 bp string
2442 expected string
2443 }{
2444 {
2445 name: "default",
2446 bp: `
2447 android_app {
2448 name: "foo",
2449 srcs: ["a.java"],
2450 sdk_version: "current",
2451 }
2452 `,
2453 expected: "",
2454 },
2455 {
2456 name: "default",
2457 bp: `
2458 android_app {
2459 name: "foo",
2460 srcs: ["a.java"],
2461 sdk_version: "current",
2462 v4_signature: false,
2463 }
2464 `,
2465 expected: "",
2466 },
2467 {
2468 name: "module certificate property",
2469 bp: `
2470 android_app {
2471 name: "foo",
2472 srcs: ["a.java"],
2473 sdk_version: "current",
2474 v4_signature: true,
2475 }
2476 `,
2477 expected: "--enable-v4",
2478 },
2479 }
2480
2481 for _, test := range testCases {
2482 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002483 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002484 result := android.GroupFixturePreparers(
2485 PrepareForTestWithJavaDefaultModules,
2486 ).RunTestWithBp(t, test.bp)
Songchun Fan688de9a2020-03-24 20:32:24 -07002487
Colin Cross90607e92025-02-11 14:58:07 -08002488 foo := result.ModuleForTests(t, "foo", "android_common")
Songchun Fan688de9a2020-03-24 20:32:24 -07002489
2490 signapk := foo.Output("foo.apk")
2491 signFlags := signapk.Args["flags"]
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002492 android.AssertStringEquals(t, "signing flags", test.expected, signFlags)
Songchun Fan688de9a2020-03-24 20:32:24 -07002493 })
2494 }
2495}
2496
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002497func TestPackageNameOverride(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002498 t.Parallel()
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002499 testCases := []struct {
2500 name string
2501 bp string
2502 packageNameOverride string
2503 expected []string
2504 }{
2505 {
2506 name: "default",
2507 bp: `
2508 android_app {
2509 name: "foo",
2510 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002511 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002512 }
2513 `,
2514 packageNameOverride: "",
2515 expected: []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002516 "out/soong/.intermediates/foo/android_common/foo.apk",
Cole Faust6b7075f2024-12-17 10:42:42 -08002517 "out/target/product/test_device/system/app/foo/foo.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002518 },
2519 },
2520 {
Jooyung Han29e2f6d2022-01-08 12:13:59 +09002521 name: "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002522 bp: `
2523 android_app {
2524 name: "foo",
2525 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002526 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002527 }
2528 `,
2529 packageNameOverride: "foo:bar",
2530 expected: []string{
2531 // The package apk should be still be the original name for test dependencies.
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002532 "out/soong/.intermediates/foo/android_common/bar.apk",
Cole Faust6b7075f2024-12-17 10:42:42 -08002533 "out/target/product/test_device/system/app/bar/bar.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002534 },
2535 },
Jooyung Han29e2f6d2022-01-08 12:13:59 +09002536 {
2537 name: "overridden via stem",
2538 bp: `
2539 android_app {
2540 name: "foo",
2541 srcs: ["a.java"],
2542 sdk_version: "current",
2543 stem: "bar",
2544 }
2545 `,
2546 packageNameOverride: "",
2547 expected: []string{
2548 "out/soong/.intermediates/foo/android_common/bar.apk",
Cole Faust6b7075f2024-12-17 10:42:42 -08002549 "out/target/product/test_device/system/app/bar/bar.apk",
Jooyung Han29e2f6d2022-01-08 12:13:59 +09002550 },
2551 },
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002552 }
2553
2554 for _, test := range testCases {
2555 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002556 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002557 result := android.GroupFixturePreparers(
2558 PrepareForTestWithJavaDefaultModules,
2559 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2560 if test.packageNameOverride != "" {
2561 variables.PackageNameOverrides = []string{test.packageNameOverride}
2562 }
2563 }),
2564 ).RunTestWithBp(t, test.bp)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002565
Colin Cross90607e92025-02-11 14:58:07 -08002566 foo := result.ModuleForTests(t, "foo", "android_common")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002567
Lukacs T. Berkifbaf7252021-08-19 09:36:42 +02002568 outSoongDir := result.Config.SoongOutDir()
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002569
2570 outputs := foo.AllOutputs()
2571 outputMap := make(map[string]bool)
2572 for _, o := range outputs {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002573 outputMap[android.StringPathRelativeToTop(outSoongDir, o)] = true
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002574 }
2575 for _, e := range test.expected {
2576 if _, exist := outputMap[e]; !exist {
2577 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
2578 }
2579 }
2580 })
2581 }
2582}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002583
2584func TestInstrumentationTargetOverridden(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002585 t.Parallel()
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002586 bp := `
2587 android_app {
2588 name: "foo",
2589 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002590 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002591 }
2592
2593 android_test {
2594 name: "bar",
2595 instrumentation_for: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002596 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002597 }
2598 `
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002599
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002600 result := android.GroupFixturePreparers(
2601 PrepareForTestWithJavaDefaultModules,
2602 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2603 variables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
2604 }),
2605 ).RunTestWithBp(t, bp)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002606
Colin Cross90607e92025-02-11 14:58:07 -08002607 bar := result.ModuleForTests(t, "bar", "android_common")
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002608 res := bar.Output("package-res.apk")
2609 aapt2Flags := res.Args["flags"]
2610 e := "--rename-instrumentation-target-package org.dandroid.bp"
2611 if !strings.Contains(aapt2Flags, e) {
2612 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
2613 }
2614}
Jaewoong Jung525443a2019-02-28 15:35:54 -08002615
2616func TestOverrideAndroidApp(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002617 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002618 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
2619 t, `
Jaewoong Jung525443a2019-02-28 15:35:54 -08002620 android_app {
2621 name: "foo",
2622 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -07002623 certificate: "expiredkey",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002624 overrides: ["qux"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002625 sdk_version: "current",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002626 }
2627
2628 override_android_app {
2629 name: "bar",
2630 base: "foo",
2631 certificate: ":new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07002632 lineage: "lineage.bin",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002633 rotationMinSdkVersion: "32",
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08002634 logging_parent: "bah",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002635 }
2636
2637 android_app_certificate {
2638 name: "new_certificate",
2639 certificate: "cert/new_cert",
2640 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002641
2642 override_android_app {
2643 name: "baz",
2644 base: "foo",
2645 package_name: "org.dandroid.bp",
2646 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00002647
2648 override_android_app {
2649 name: "baz_no_rename_resources",
2650 base: "foo",
2651 package_name: "org.dandroid.bp",
2652 rename_resources_package: false,
2653 }
2654
2655 android_app {
2656 name: "foo_no_rename_resources",
2657 srcs: ["a.java"],
2658 certificate: "expiredkey",
2659 overrides: ["qux"],
2660 rename_resources_package: false,
2661 sdk_version: "current",
2662 }
2663
2664 override_android_app {
2665 name: "baz_base_no_rename_resources",
2666 base: "foo_no_rename_resources",
2667 package_name: "org.dandroid.bp",
2668 }
2669
2670 override_android_app {
2671 name: "baz_override_base_rename_resources",
2672 base: "foo_no_rename_resources",
2673 package_name: "org.dandroid.bp",
2674 rename_resources_package: true,
2675 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08002676 `)
2677
2678 expectedVariants := []struct {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002679 name string
2680 moduleName string
2681 variantName string
2682 apkName string
2683 apkPath string
2684 certFlag string
2685 certSigningFlags string
2686 overrides []string
2687 packageFlag string
2688 renameResources bool
2689 logging_parent string
Jaewoong Jung525443a2019-02-28 15:35:54 -08002690 }{
2691 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002692 name: "foo",
2693 moduleName: "foo",
2694 variantName: "android_common",
Cole Faust6b7075f2024-12-17 10:42:42 -08002695 apkPath: "out/target/product/test_device/system/app/foo/foo.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002696 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2697 certSigningFlags: "",
2698 overrides: []string{"qux"},
2699 packageFlag: "",
2700 renameResources: false,
2701 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002702 },
2703 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002704 name: "foo",
2705 moduleName: "bar",
2706 variantName: "android_common_bar",
Cole Faust6b7075f2024-12-17 10:42:42 -08002707 apkPath: "out/target/product/test_device/system/app/bar/bar.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002708 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
2709 certSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
2710 overrides: []string{"qux", "foo"},
2711 packageFlag: "",
2712 renameResources: false,
2713 logging_parent: "bah",
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002714 },
2715 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002716 name: "foo",
2717 moduleName: "baz",
2718 variantName: "android_common_baz",
Cole Faust6b7075f2024-12-17 10:42:42 -08002719 apkPath: "out/target/product/test_device/system/app/baz/baz.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002720 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2721 certSigningFlags: "",
2722 overrides: []string{"qux", "foo"},
2723 packageFlag: "org.dandroid.bp",
2724 renameResources: true,
2725 logging_parent: "",
Liz Kammer9f9fd022020-06-18 19:44:06 +00002726 },
2727 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002728 name: "foo",
2729 moduleName: "baz_no_rename_resources",
2730 variantName: "android_common_baz_no_rename_resources",
Cole Faust6b7075f2024-12-17 10:42:42 -08002731 apkPath: "out/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002732 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2733 certSigningFlags: "",
2734 overrides: []string{"qux", "foo"},
2735 packageFlag: "org.dandroid.bp",
2736 renameResources: false,
2737 logging_parent: "",
Liz Kammer9f9fd022020-06-18 19:44:06 +00002738 },
2739 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002740 name: "foo_no_rename_resources",
2741 moduleName: "baz_base_no_rename_resources",
2742 variantName: "android_common_baz_base_no_rename_resources",
Cole Faust6b7075f2024-12-17 10:42:42 -08002743 apkPath: "out/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002744 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2745 certSigningFlags: "",
2746 overrides: []string{"qux", "foo_no_rename_resources"},
2747 packageFlag: "org.dandroid.bp",
2748 renameResources: false,
2749 logging_parent: "",
Liz Kammer9f9fd022020-06-18 19:44:06 +00002750 },
2751 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002752 name: "foo_no_rename_resources",
2753 moduleName: "baz_override_base_rename_resources",
2754 variantName: "android_common_baz_override_base_rename_resources",
Cole Faust6b7075f2024-12-17 10:42:42 -08002755 apkPath: "out/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002756 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2757 certSigningFlags: "",
2758 overrides: []string{"qux", "foo_no_rename_resources"},
2759 packageFlag: "org.dandroid.bp",
2760 renameResources: true,
2761 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002762 },
2763 }
2764 for _, expected := range expectedVariants {
Colin Cross90607e92025-02-11 14:58:07 -08002765 variant := result.ModuleForTests(t, expected.name, expected.variantName)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002766
2767 // Check the final apk name
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002768 variant.Output(expected.apkPath)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002769
2770 // Check the certificate paths
Jaewoong Jung5a498812019-11-07 14:14:38 -08002771 signapk := variant.Output(expected.moduleName + ".apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07002772 certFlag := signapk.Args["certificates"]
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002773 android.AssertStringEquals(t, "certificates flags", expected.certFlag, certFlag)
Liz Kammere2b27f42020-05-07 13:24:05 -07002774
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002775 // Check the cert signing flags
2776 certSigningFlags := signapk.Args["flags"]
2777 android.AssertStringEquals(t, "cert signing flags", expected.certSigningFlags, certSigningFlags)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002778
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002779 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -08002780 mod := variant.Module().(*AndroidApp)
zhidoua2ce78f2022-02-17 02:33:12 +00002781 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002782
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08002783 // Test Overridable property: Logging_parent
2784 logging_parent := mod.aapt.LoggingParent
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002785 android.AssertStringEquals(t, "overrides property value for logging parent", expected.logging_parent, logging_parent)
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08002786
Liz Kammer1d5983b2020-05-19 19:15:37 +00002787 // Check the package renaming flag, if exists.
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002788 res := variant.Output("package-res.apk")
2789 aapt2Flags := res.Args["flags"]
Liz Kammer9f9fd022020-06-18 19:44:06 +00002790 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
2791 expectedPackage := expected.packageFlag
2792 if !expected.renameResources {
2793 expectedPackage = ""
Liz Kammer1d5983b2020-05-19 19:15:37 +00002794 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00002795 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002796 }
2797}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002798
zhidoua2ce78f2022-02-17 02:33:12 +00002799func TestOverrideAndroidAppOverrides(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002800 t.Parallel()
zhidoua2ce78f2022-02-17 02:33:12 +00002801 ctx, _ := testJava(
2802 t, `
2803 android_app {
2804 name: "foo",
2805 srcs: ["a.java"],
2806 sdk_version: "current",
2807 overrides: ["qux"]
2808 }
2809
2810 android_app {
2811 name: "bar",
2812 srcs: ["b.java"],
2813 sdk_version: "current",
2814 overrides: ["foo"]
2815 }
2816
2817 override_android_app {
2818 name: "foo_override",
2819 base: "foo",
2820 overrides: ["bar"]
2821 }
2822 `)
2823
2824 expectedVariants := []struct {
2825 name string
2826 moduleName string
2827 variantName string
2828 overrides []string
2829 }{
2830 {
2831 name: "foo",
2832 moduleName: "foo",
2833 variantName: "android_common",
2834 overrides: []string{"qux"},
2835 },
2836 {
2837 name: "bar",
2838 moduleName: "bar",
2839 variantName: "android_common",
2840 overrides: []string{"foo"},
2841 },
2842 {
2843 name: "foo",
2844 moduleName: "foo_override",
2845 variantName: "android_common_foo_override",
2846 overrides: []string{"bar", "foo"},
2847 },
2848 }
2849 for _, expected := range expectedVariants {
Colin Cross90607e92025-02-11 14:58:07 -08002850 variant := ctx.ModuleForTests(t, expected.name, expected.variantName)
zhidoua2ce78f2022-02-17 02:33:12 +00002851
2852 // Check if the overrides field values are correctly aggregated.
2853 mod := variant.Module().(*AndroidApp)
2854 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
2855 }
2856}
2857
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002858func TestOverrideAndroidAppWithPrebuilt(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002859 t.Parallel()
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002860 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
2861 t, `
2862 android_app {
2863 name: "foo",
2864 srcs: ["a.java"],
2865 sdk_version: "current",
2866 }
2867
2868 override_android_app {
2869 name: "bar",
2870 base: "foo",
2871 }
2872
2873 android_app_import {
2874 name: "bar",
2875 prefer: true,
2876 apk: "bar.apk",
2877 presigned: true,
2878 }
2879 `)
2880
2881 // An app that has an override that also has a prebuilt should not be hidden.
Colin Cross90607e92025-02-11 14:58:07 -08002882 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002883 if foo.Module().IsHideFromMake() {
2884 t.Errorf("expected foo to have HideFromMake false")
2885 }
2886
2887 // An override that also has a prebuilt should be hidden.
Colin Cross90607e92025-02-11 14:58:07 -08002888 barOverride := result.ModuleForTests(t, "foo", "android_common_bar")
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002889 if !barOverride.Module().IsHideFromMake() {
2890 t.Errorf("expected bar override variant of foo to have HideFromMake true")
2891 }
2892}
2893
Jooyung Han01d80d82022-01-08 12:16:32 +09002894func TestOverrideAndroidAppStem(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002895 t.Parallel()
Jooyung Han01d80d82022-01-08 12:16:32 +09002896 ctx, _ := testJava(t, `
2897 android_app {
2898 name: "foo",
2899 srcs: ["a.java"],
2900 sdk_version: "current",
2901 }
2902 override_android_app {
2903 name: "bar",
2904 base: "foo",
2905 }
2906 override_android_app {
2907 name: "baz",
2908 base: "foo",
2909 stem: "baz_stem",
2910 }
2911 android_app {
2912 name: "foo2",
2913 srcs: ["a.java"],
2914 sdk_version: "current",
2915 stem: "foo2_stem",
2916 }
2917 override_android_app {
2918 name: "bar2",
2919 base: "foo2",
2920 }
2921 override_android_app {
2922 name: "baz2",
2923 base: "foo2",
2924 stem: "baz2_stem",
2925 }
2926 `)
2927 for _, expected := range []struct {
2928 moduleName string
2929 variantName string
2930 apkPath string
2931 }{
2932 {
2933 moduleName: "foo",
2934 variantName: "android_common",
Cole Faust6b7075f2024-12-17 10:42:42 -08002935 apkPath: "out/target/product/test_device/system/app/foo/foo.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002936 },
2937 {
2938 moduleName: "foo",
2939 variantName: "android_common_bar",
Cole Faust6b7075f2024-12-17 10:42:42 -08002940 apkPath: "out/target/product/test_device/system/app/bar/bar.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002941 },
2942 {
2943 moduleName: "foo",
2944 variantName: "android_common_baz",
Cole Faust6b7075f2024-12-17 10:42:42 -08002945 apkPath: "out/target/product/test_device/system/app/baz_stem/baz_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002946 },
2947 {
2948 moduleName: "foo2",
2949 variantName: "android_common",
Cole Faust6b7075f2024-12-17 10:42:42 -08002950 apkPath: "out/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002951 },
2952 {
2953 moduleName: "foo2",
2954 variantName: "android_common_bar2",
2955 // Note that this may cause the duplicate output error.
Cole Faust6b7075f2024-12-17 10:42:42 -08002956 apkPath: "out/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002957 },
2958 {
2959 moduleName: "foo2",
2960 variantName: "android_common_baz2",
Cole Faust6b7075f2024-12-17 10:42:42 -08002961 apkPath: "out/target/product/test_device/system/app/baz2_stem/baz2_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002962 },
2963 } {
Colin Cross90607e92025-02-11 14:58:07 -08002964 variant := ctx.ModuleForTests(t, expected.moduleName, expected.variantName)
Jooyung Han01d80d82022-01-08 12:16:32 +09002965 variant.Output(expected.apkPath)
2966 }
2967}
2968
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002969func TestOverrideAndroidAppDependency(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002970 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002971 ctx, _ := testJava(t, `
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002972 android_app {
2973 name: "foo",
2974 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002975 sdk_version: "current",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002976 }
2977
2978 override_android_app {
2979 name: "bar",
2980 base: "foo",
2981 package_name: "org.dandroid.bp",
2982 }
2983
2984 android_test {
2985 name: "baz",
2986 srcs: ["b.java"],
2987 instrumentation_for: "foo",
2988 }
2989
2990 android_test {
2991 name: "qux",
2992 srcs: ["b.java"],
2993 instrumentation_for: "bar",
2994 }
2995 `)
2996
2997 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
Colin Cross90607e92025-02-11 14:58:07 -08002998 javac := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002999 fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07003000 if !strings.Contains(javac.Args["classpath"], fooTurbine) {
3001 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
3002 }
3003
3004 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
Colin Cross90607e92025-02-11 14:58:07 -08003005 javac = ctx.ModuleForTests(t, "qux", "android_common").Rule("javac")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003006 barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07003007 if !strings.Contains(javac.Args["classpath"], barTurbine) {
3008 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
3009 }
3010}
3011
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003012func TestOverrideAndroidTest(t *testing.T) {
3013 ctx, _ := testJava(t, `
3014 android_app {
3015 name: "foo",
3016 srcs: ["a.java"],
3017 package_name: "com.android.foo",
3018 sdk_version: "current",
3019 }
3020
3021 override_android_app {
3022 name: "bar",
3023 base: "foo",
3024 package_name: "com.android.bar",
3025 }
3026
3027 android_test {
3028 name: "foo_test",
3029 srcs: ["b.java"],
3030 instrumentation_for: "foo",
3031 }
3032
3033 override_android_test {
3034 name: "bar_test",
3035 base: "foo_test",
3036 package_name: "com.android.bar.test",
3037 instrumentation_for: "bar",
3038 instrumentation_target_package: "com.android.bar",
3039 }
3040 `)
3041
3042 expectedVariants := []struct {
3043 moduleName string
3044 variantName string
3045 apkPath string
3046 overrides []string
3047 targetVariant string
3048 packageFlag string
3049 targetPackageFlag string
3050 }{
3051 {
3052 variantName: "android_common",
Jaewoong Jung326a9412019-11-21 10:41:00 -08003053 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003054 overrides: nil,
3055 targetVariant: "android_common",
3056 packageFlag: "",
3057 targetPackageFlag: "",
3058 },
3059 {
3060 variantName: "android_common_bar_test",
Jaewoong Jung326a9412019-11-21 10:41:00 -08003061 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003062 overrides: []string{"foo_test"},
3063 targetVariant: "android_common_bar",
3064 packageFlag: "com.android.bar.test",
3065 targetPackageFlag: "com.android.bar",
3066 },
3067 }
3068 for _, expected := range expectedVariants {
Colin Cross90607e92025-02-11 14:58:07 -08003069 variant := ctx.ModuleForTests(t, "foo_test", expected.variantName)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003070
3071 // Check the final apk name
Cole Faust6b7075f2024-12-17 10:42:42 -08003072 variant.Output("out" + expected.apkPath)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003073
3074 // Check if the overrides field values are correctly aggregated.
3075 mod := variant.Module().(*AndroidTest)
zhidoua2ce78f2022-02-17 02:33:12 +00003076 if !reflect.DeepEqual(expected.overrides, mod.overridableAppProperties.Overrides) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003077 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
zhidoua2ce78f2022-02-17 02:33:12 +00003078 expected.overrides, mod.overridableAppProperties.Overrides)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003079 }
3080
3081 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
Paul Duffina71a67a2021-03-29 00:42:57 +01003082 javac := variant.Rule("javac")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003083 turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003084 if !strings.Contains(javac.Args["classpath"], turbine) {
3085 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
3086 }
3087
3088 // Check aapt2 flags.
3089 res := variant.Output("package-res.apk")
3090 aapt2Flags := res.Args["flags"]
3091 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
Liz Kammer9f9fd022020-06-18 19:44:06 +00003092 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003093 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
3094 }
3095}
3096
Jaewoong Jung39982342020-01-14 10:27:18 -08003097func TestAndroidTest_FixTestConfig(t *testing.T) {
3098 ctx, _ := testJava(t, `
3099 android_app {
3100 name: "foo",
3101 srcs: ["a.java"],
3102 package_name: "com.android.foo",
3103 sdk_version: "current",
3104 }
3105
3106 android_test {
3107 name: "foo_test",
3108 srcs: ["b.java"],
3109 instrumentation_for: "foo",
3110 }
3111
3112 android_test {
3113 name: "bar_test",
3114 srcs: ["b.java"],
3115 package_name: "com.android.bar.test",
3116 instrumentation_for: "foo",
Seth Moorec6f4b532023-02-02 13:22:26 -08003117 mainline_package_name: "com.android.bar",
Jaewoong Jung39982342020-01-14 10:27:18 -08003118 }
3119
3120 override_android_test {
3121 name: "baz_test",
3122 base: "foo_test",
3123 package_name: "com.android.baz.test",
Seth Moorec6f4b532023-02-02 13:22:26 -08003124 mainline_package_name: "com.android.baz",
Jaewoong Jung39982342020-01-14 10:27:18 -08003125 }
3126 `)
3127
3128 testCases := []struct {
3129 moduleName string
3130 variantName string
3131 expectedFlags []string
3132 }{
3133 {
3134 moduleName: "foo_test",
3135 variantName: "android_common",
3136 },
3137 {
3138 moduleName: "bar_test",
3139 variantName: "android_common",
3140 expectedFlags: []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003141 "--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
Jaewoong Jung39982342020-01-14 10:27:18 -08003142 "--package-name com.android.bar.test",
Seth Moorec6f4b532023-02-02 13:22:26 -08003143 "--mainline-package-name com.android.bar",
Jaewoong Jung39982342020-01-14 10:27:18 -08003144 },
3145 },
3146 {
3147 moduleName: "foo_test",
3148 variantName: "android_common_baz_test",
3149 expectedFlags: []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003150 "--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
Jaewoong Jung39982342020-01-14 10:27:18 -08003151 "--package-name com.android.baz.test",
3152 "--test-file-name baz_test.apk",
Seth Moorec6f4b532023-02-02 13:22:26 -08003153 "out/soong/.intermediates/foo_test/android_common_baz_test/test_config_fixer/AndroidTest.xml",
3154 "--mainline-package-name com.android.baz",
Jaewoong Jung39982342020-01-14 10:27:18 -08003155 },
3156 },
3157 }
3158
3159 for _, test := range testCases {
Colin Cross90607e92025-02-11 14:58:07 -08003160 variant := ctx.ModuleForTests(t, test.moduleName, test.variantName)
Paul Duffina71a67a2021-03-29 00:42:57 +01003161 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
Jaewoong Jung39982342020-01-14 10:27:18 -08003162
3163 if len(test.expectedFlags) > 0 {
3164 if params.Rule == nil {
3165 t.Errorf("test_config_fixer was expected to run, but didn't")
3166 } else {
3167 for _, flag := range test.expectedFlags {
3168 if !strings.Contains(params.RuleParams.Command, flag) {
3169 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
3170 }
3171 }
3172 }
3173 } else {
3174 if params.Rule != nil {
3175 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
3176 }
3177 }
Jaewoong Jung39982342020-01-14 10:27:18 -08003178 }
3179}
3180
Paul Duffin53a70a42022-01-11 14:35:55 +00003181func TestInstrumentationTargetPrebuilt(t *testing.T) {
3182 bp := `
3183 android_app_import {
3184 name: "foo",
3185 apk: "foo.apk",
3186 presigned: true,
3187 }
3188
3189 android_test {
3190 name: "bar",
3191 srcs: ["a.java"],
3192 instrumentation_for: "foo",
3193 sdk_version: "current",
3194 }
3195 `
3196
3197 android.GroupFixturePreparers(
3198 PrepareForTestWithJavaDefaultModules,
3199 ).ExtendWithErrorHandler(
3200 android.FixtureExpectsAtLeastOneErrorMatchingPattern(
3201 "instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property")).
3202 RunTestWithBp(t, bp)
3203}
3204
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003205func TestStl(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003206 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07003207 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003208 cc_library {
3209 name: "libjni",
Peter Collingbournead84f972019-12-17 16:46:18 -08003210 sdk_version: "current",
3211 stl: "c++_shared",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003212 }
3213
3214 android_test {
3215 name: "stl",
3216 jni_libs: ["libjni"],
3217 compile_multilib: "both",
3218 sdk_version: "current",
3219 stl: "c++_shared",
3220 }
3221
3222 android_test {
3223 name: "system",
3224 jni_libs: ["libjni"],
3225 compile_multilib: "both",
3226 sdk_version: "current",
3227 }
3228 `)
3229
3230 testCases := []struct {
3231 name string
3232 jnis []string
3233 }{
3234 {"stl",
3235 []string{
3236 "libjni.so",
Jaewoong Jung710756a2019-06-04 11:53:47 -07003237 "libc++_shared.so",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003238 },
3239 },
3240 {"system",
3241 []string{
3242 "libjni.so",
3243 },
3244 },
3245 }
3246
3247 for _, test := range testCases {
3248 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003249 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08003250 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Crossb3168ba2023-07-26 16:14:56 -07003251 jniLibZip := app.Output("jnilibs.zip")
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003252 var jnis []string
3253 args := strings.Fields(jniLibZip.Args["jarArgs"])
3254 for i := 0; i < len(args); i++ {
3255 if args[i] == "-f" {
3256 jnis = append(jnis, args[i+1])
3257 i += 1
3258 }
3259 }
3260 jnisJoined := strings.Join(jnis, " ")
3261 for _, jni := range test.jnis {
3262 if !strings.Contains(jnisJoined, jni) {
3263 t.Errorf("missing jni %q in %q", jni, jnis)
3264 }
3265 }
3266 })
3267 }
3268}
Colin Cross50ddcc42019-05-16 12:28:22 -07003269
3270func TestUsesLibraries(t *testing.T) {
3271 bp := `
3272 java_sdk_library {
3273 name: "foo",
3274 srcs: ["a.java"],
3275 api_packages: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003276 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07003277 }
3278
3279 java_sdk_library {
Paul Duffin859fe962020-05-15 10:20:31 +01003280 name: "qux",
3281 srcs: ["a.java"],
3282 api_packages: ["qux"],
3283 sdk_version: "current",
3284 }
3285
3286 java_sdk_library {
3287 name: "quuz",
3288 srcs: ["a.java"],
3289 api_packages: ["quuz"],
3290 sdk_version: "current",
3291 }
3292
3293 java_sdk_library {
Ulya Trafimovich65b03192020-12-03 16:50:22 +00003294 name: "fred",
3295 srcs: ["a.java"],
3296 api_packages: ["fred"],
3297 sdk_version: "current",
3298 }
3299
3300 java_sdk_library {
Colin Cross50ddcc42019-05-16 12:28:22 -07003301 name: "bar",
3302 srcs: ["a.java"],
3303 api_packages: ["bar"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003304 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07003305 }
3306
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01003307 java_sdk_library {
3308 name: "runtime-library",
3309 srcs: ["a.java"],
3310 sdk_version: "current",
3311 }
3312
3313 java_library {
3314 name: "static-runtime-helper",
3315 srcs: ["a.java"],
Jihoon Kang28c96572024-09-11 23:44:44 +00003316 libs: ["runtime-library.impl"],
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01003317 sdk_version: "current",
3318 }
3319
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003320 java_library {
3321 name: "runtime-required-x",
3322 srcs: ["a.java"],
3323 installable: true,
3324 sdk_version: "current",
3325 }
3326
3327 java_library {
3328 name: "runtime-optional-x",
3329 srcs: ["a.java"],
3330 installable: true,
3331 sdk_version: "current",
3332 }
3333
3334 android_library {
3335 name: "static-x",
3336 uses_libs: ["runtime-required-x"],
3337 optional_uses_libs: ["runtime-optional-x"],
3338 sdk_version: "current",
3339 }
3340
3341 java_library {
3342 name: "runtime-required-y",
3343 srcs: ["a.java"],
3344 installable: true,
3345 sdk_version: "current",
3346 }
3347
3348 java_library {
3349 name: "runtime-optional-y",
3350 srcs: ["a.java"],
3351 installable: true,
3352 sdk_version: "current",
3353 }
3354
3355 java_library {
3356 name: "static-y",
3357 srcs: ["a.java"],
3358 uses_libs: ["runtime-required-y"],
Jiakai Zhang36937082024-04-15 11:15:50 +00003359 optional_uses_libs: [
3360 "runtime-optional-y",
3361 "missing-lib-a",
3362 ],
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003363 sdk_version: "current",
3364 }
3365
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003366 // A library that has to use "provides_uses_lib", because:
3367 // - it is not an SDK library
3368 // - its library name is different from its module name
3369 java_library {
3370 name: "non-sdk-lib",
3371 provides_uses_lib: "com.non.sdk.lib",
3372 installable: true,
3373 srcs: ["a.java"],
3374 }
3375
Colin Cross50ddcc42019-05-16 12:28:22 -07003376 android_app {
3377 name: "app",
3378 srcs: ["a.java"],
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003379 libs: [
Jihoon Kang28c96572024-09-11 23:44:44 +00003380 "qux.impl",
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003381 "quuz.stubs"
3382 ],
Ulya Trafimovich65b03192020-12-03 16:50:22 +00003383 static_libs: [
3384 "static-runtime-helper",
3385 // statically linked component libraries should not pull their SDK libraries,
3386 // so "fred" should not be added to class loader context
3387 "fred.stubs",
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003388 "static-x",
3389 "static-y",
Ulya Trafimovich65b03192020-12-03 16:50:22 +00003390 ],
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003391 uses_libs: [
3392 "foo",
3393 "non-sdk-lib"
3394 ],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003395 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07003396 optional_uses_libs: [
3397 "bar",
Jiakai Zhangf98da192024-04-15 11:15:41 +00003398 "missing-lib-b",
Colin Cross50ddcc42019-05-16 12:28:22 -07003399 ],
3400 }
3401
3402 android_app_import {
3403 name: "prebuilt",
3404 apk: "prebuilts/apk/app.apk",
3405 certificate: "platform",
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003406 uses_libs: [
3407 "foo",
3408 "non-sdk-lib",
3409 "android.test.runner"
3410 ],
Colin Cross50ddcc42019-05-16 12:28:22 -07003411 optional_uses_libs: [
3412 "bar",
Jiakai Zhangf98da192024-04-15 11:15:41 +00003413 "missing-lib-b",
Colin Cross50ddcc42019-05-16 12:28:22 -07003414 ],
3415 }
3416 `
3417
Paul Duffin71ae5942021-03-22 15:36:52 +00003418 result := android.GroupFixturePreparers(
3419 prepareForJavaTest,
Paul Duffin2645a292021-03-13 02:36:00 +00003420 PrepareForTestWithJavaSdkLibraryFiles,
3421 FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"),
Jiakai Zhang48203e32023-06-02 23:42:21 +01003422 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3423 variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"}
3424 }),
Paul Duffind234b412021-03-12 23:04:46 +00003425 ).RunTestWithBp(t, bp)
Colin Cross50ddcc42019-05-16 12:28:22 -07003426
Colin Cross90607e92025-02-11 14:58:07 -08003427 app := result.ModuleForTests(t, "app", "android_common")
3428 prebuilt := result.ModuleForTests(t, "prebuilt", "android_common")
Colin Cross50ddcc42019-05-16 12:28:22 -07003429
Paul Duffin859fe962020-05-15 10:20:31 +01003430 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01003431 // These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
3432 // propagated from dependencies.
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003433 actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
Jiyong Parkd044bb42024-05-15 02:09:54 +09003434 expectManifestFixerArgs := `--extract-native-libs=true ` +
3435 `--uses-library foo ` +
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01003436 `--uses-library com.non.sdk.lib ` +
Jiakai Zhangf98da192024-04-15 11:15:41 +00003437 `--uses-library qux ` +
3438 `--uses-library quuz ` +
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01003439 `--uses-library runtime-library ` +
3440 `--uses-library runtime-required-x ` +
3441 `--uses-library runtime-required-y ` +
3442 `--optional-uses-library bar ` +
3443 `--optional-uses-library runtime-optional-x ` +
3444 `--optional-uses-library runtime-optional-y`
Gurpreet Singh75d65f32022-01-24 17:44:05 +00003445 android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs)
Paul Duffin859fe962020-05-15 10:20:31 +01003446
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003447 // Test that all libraries are verified (library order matters).
3448 verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command
3449 verifyArgs := `--uses-library foo ` +
Ulya Trafimovicheea486a2021-02-26 11:38:21 +00003450 `--uses-library com.non.sdk.lib ` +
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003451 `--uses-library qux ` +
3452 `--uses-library quuz ` +
3453 `--uses-library runtime-library ` +
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003454 `--uses-library runtime-required-x ` +
3455 `--uses-library runtime-required-y ` +
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003456 `--optional-uses-library bar ` +
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003457 `--optional-uses-library runtime-optional-x ` +
Jiakai Zhangf98da192024-04-15 11:15:41 +00003458 `--optional-uses-library runtime-optional-y ` +
Jiakai Zhang36937082024-04-15 11:15:50 +00003459 `--missing-optional-uses-library missing-lib-b ` +
3460 `--missing-optional-uses-library missing-lib-a`
Paul Duffind234b412021-03-12 23:04:46 +00003461 android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
Colin Cross50ddcc42019-05-16 12:28:22 -07003462
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003463 // Test that all libraries are verified for an APK (library order matters).
3464 verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00003465 verifyApkArgs := `--uses-library foo ` +
3466 `--uses-library com.non.sdk.lib ` +
3467 `--uses-library android.test.runner ` +
3468 `--optional-uses-library bar ` +
Jiakai Zhangf98da192024-04-15 11:15:41 +00003469 `--missing-optional-uses-library missing-lib-b `
Paul Duffind234b412021-03-12 23:04:46 +00003470 android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
Colin Cross50ddcc42019-05-16 12:28:22 -07003471
Jiakai Zhanga4496782023-05-17 16:57:30 +01003472 // Test that necessary args are passed for constructing CLC in Ninja phase.
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003473 cmd := app.Rule("dexpreopt").RuleParams.Command
Jiakai Zhanga4496782023-05-17 16:57:30 +01003474 android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=")
3475 android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd,
Spandan Das2069c3f2023-12-06 19:40:24 +00003476 "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt")
Colin Cross50ddcc42019-05-16 12:28:22 -07003477}
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003478
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003479func TestDexpreoptBcp(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003480 t.Parallel()
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003481 bp := `
3482 java_sdk_library {
3483 name: "foo",
3484 srcs: ["a.java"],
3485 api_packages: ["foo"],
3486 sdk_version: "current",
3487 }
3488
3489 java_sdk_library {
3490 name: "bar",
3491 srcs: ["a.java"],
3492 api_packages: ["bar"],
3493 permitted_packages: ["bar"],
3494 sdk_version: "current",
3495 }
3496
3497 android_app {
3498 name: "app",
3499 srcs: ["a.java"],
3500 sdk_version: "current",
3501 }
3502 `
3503
3504 testCases := []struct {
3505 name string
3506 with bool
3507 expect string
3508 }{
3509 {
3510 name: "with updatable bcp",
3511 with: true,
3512 expect: "/system/framework/foo.jar:/system/framework/bar.jar",
3513 },
3514 {
3515 name: "without updatable bcp",
3516 with: false,
3517 expect: "/system/framework/foo.jar",
3518 },
3519 }
3520
3521 for _, test := range testCases {
3522 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003523 t.Parallel()
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003524 result := android.GroupFixturePreparers(
3525 prepareForJavaTest,
3526 PrepareForTestWithJavaSdkLibraryFiles,
3527 FixtureWithLastReleaseApis("runtime-library", "foo", "bar"),
3528 dexpreopt.FixtureSetBootJars("platform:foo"),
satayevd604b212021-07-21 14:23:52 +01003529 dexpreopt.FixtureSetApexBootJars("platform:bar"),
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003530 dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with),
3531 ).RunTestWithBp(t, bp)
3532
Colin Cross90607e92025-02-11 14:58:07 -08003533 app := result.ModuleForTests(t, "app", "android_common")
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003534 cmd := app.Rule("dexpreopt").RuleParams.Command
3535 bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters
3536 android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp)
3537 })
3538 }
3539}
3540
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003541func TestCodelessApp(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003542 t.Parallel()
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003543 testCases := []struct {
3544 name string
3545 bp string
3546 noCode bool
3547 }{
3548 {
3549 name: "normal",
3550 bp: `
3551 android_app {
3552 name: "foo",
3553 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003554 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003555 }
3556 `,
3557 noCode: false,
3558 },
3559 {
3560 name: "app without sources",
3561 bp: `
3562 android_app {
3563 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09003564 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003565 }
3566 `,
3567 noCode: true,
3568 },
3569 {
3570 name: "app with libraries",
3571 bp: `
3572 android_app {
3573 name: "foo",
3574 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003575 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003576 }
3577
3578 java_library {
3579 name: "lib",
3580 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003581 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003582 }
3583 `,
3584 noCode: false,
3585 },
3586 {
3587 name: "app with sourceless libraries",
3588 bp: `
3589 android_app {
3590 name: "foo",
3591 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003592 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003593 }
3594
3595 java_library {
3596 name: "lib",
Jeongik Cha538c0d02019-07-11 15:54:27 +09003597 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003598 }
3599 `,
3600 // TODO(jungjw): this should probably be true
3601 noCode: false,
3602 },
3603 }
3604
3605 for _, test := range testCases {
3606 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003607 t.Parallel()
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003608 ctx := testApp(t, test.bp)
3609
Colin Cross90607e92025-02-11 14:58:07 -08003610 foo := ctx.ModuleForTests(t, "foo", "android_common")
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003611 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3612 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
3613 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
3614 }
3615 })
3616 }
3617}
Jaewoong Jung5b425e22019-06-17 17:40:56 -07003618
Colin Cross53a87f52019-06-25 13:35:30 -07003619func TestUncompressDex(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003620 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003621 testCases := []struct {
3622 name string
3623 bp string
3624
3625 uncompressedPlatform bool
3626 uncompressedUnbundled bool
3627 }{
3628 {
3629 name: "normal",
3630 bp: `
3631 android_app {
3632 name: "foo",
3633 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003634 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003635 }
3636 `,
3637 uncompressedPlatform: true,
3638 uncompressedUnbundled: false,
3639 },
3640 {
3641 name: "use_embedded_dex",
3642 bp: `
3643 android_app {
3644 name: "foo",
3645 use_embedded_dex: true,
3646 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003647 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003648 }
3649 `,
3650 uncompressedPlatform: true,
3651 uncompressedUnbundled: true,
3652 },
3653 {
3654 name: "privileged",
3655 bp: `
3656 android_app {
3657 name: "foo",
3658 privileged: true,
3659 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003660 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003661 }
3662 `,
3663 uncompressedPlatform: true,
3664 uncompressedUnbundled: true,
3665 },
David Srbeckye033cba2020-05-20 22:20:28 +01003666 {
3667 name: "normal_uncompress_dex_true",
3668 bp: `
3669 android_app {
3670 name: "foo",
3671 srcs: ["a.java"],
3672 sdk_version: "current",
3673 uncompress_dex: true,
3674 }
3675 `,
3676 uncompressedPlatform: true,
3677 uncompressedUnbundled: true,
3678 },
3679 {
3680 name: "normal_uncompress_dex_false",
3681 bp: `
3682 android_app {
3683 name: "foo",
3684 srcs: ["a.java"],
3685 sdk_version: "current",
3686 uncompress_dex: false,
3687 }
3688 `,
3689 uncompressedPlatform: false,
3690 uncompressedUnbundled: false,
3691 },
Colin Cross53a87f52019-06-25 13:35:30 -07003692 }
3693
3694 test := func(t *testing.T, bp string, want bool, unbundled bool) {
3695 t.Helper()
3696
Paul Duffin71ae5942021-03-22 15:36:52 +00003697 result := android.GroupFixturePreparers(
3698 prepareForJavaTest,
Paul Duffin2645a292021-03-13 02:36:00 +00003699 PrepareForTestWithPrebuiltsOfCurrentApi,
Paul Duffincdb88a92021-03-14 00:36:50 +00003700 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3701 if unbundled {
3702 variables.Unbundled_build = proptools.BoolPtr(true)
3703 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
3704 }
3705 }),
3706 ).RunTestWithBp(t, bp)
Colin Cross53a87f52019-06-25 13:35:30 -07003707
Colin Cross90607e92025-02-11 14:58:07 -08003708 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross53a87f52019-06-25 13:35:30 -07003709 dex := foo.Rule("r8")
3710 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
3711 aligned := foo.MaybeRule("zipalign").Rule != nil
3712
Paul Duffincdb88a92021-03-14 00:36:50 +00003713 android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar)
Colin Cross53a87f52019-06-25 13:35:30 -07003714
Paul Duffincdb88a92021-03-14 00:36:50 +00003715 android.AssertBoolEquals(t, "aligne", want, aligned)
Colin Cross53a87f52019-06-25 13:35:30 -07003716 }
3717
3718 for _, tt := range testCases {
3719 t.Run(tt.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003720 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003721 t.Run("platform", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003722 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003723 test(t, tt.bp, tt.uncompressedPlatform, false)
3724 })
3725 t.Run("unbundled", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003726 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003727 test(t, tt.bp, tt.uncompressedUnbundled, true)
3728 })
3729 })
3730 }
3731}
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003732
3733func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
3734 if expectedValue != "" {
3735 expectedFlag := "--" + flagName + " " + expectedValue
3736 if !strings.Contains(aapt2Flags, expectedFlag) {
3737 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
3738 }
3739 } else {
3740 unexpectedFlag := "--" + flagName
3741 if strings.Contains(aapt2Flags, unexpectedFlag) {
3742 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
3743 }
3744 }
3745}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003746
Cole Faust9a631312020-10-22 21:05:24 +00003747func TestExportedProguardFlagFiles(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003748 t.Parallel()
Cole Faust9a631312020-10-22 21:05:24 +00003749 ctx, _ := testJava(t, `
3750 android_app {
3751 name: "foo",
3752 sdk_version: "current",
Colin Crosscde55342024-03-27 14:11:51 -07003753 static_libs: [
3754 "lib1",
3755 "lib3",
3756 ],
Cole Faust9a631312020-10-22 21:05:24 +00003757 }
3758
3759 android_library {
3760 name: "lib1",
3761 sdk_version: "current",
3762 optimize: {
3763 proguard_flags_files: ["lib1proguard.cfg"],
Colin Crosscde55342024-03-27 14:11:51 -07003764 },
3765 static_libs: ["lib2"],
3766 }
3767
3768 android_library {
3769 name: "lib2",
3770 sdk_version: "current",
3771 optimize: {
3772 proguard_flags_files: ["lib2proguard.cfg"],
Cole Faust9a631312020-10-22 21:05:24 +00003773 }
3774 }
Colin Crosscde55342024-03-27 14:11:51 -07003775
3776 android_library_import {
3777 name: "lib3",
3778 sdk_version: "current",
3779 aars: ["lib3.aar"],
3780 static_libs: ["lib4"],
3781 }
3782
3783 android_library {
3784 name: "lib4",
3785 sdk_version: "current",
3786 optimize: {
3787 proguard_flags_files: ["lib4proguard.cfg"],
3788 }
3789 }
3790
3791
Cole Faust9a631312020-10-22 21:05:24 +00003792 `)
3793
Colin Cross90607e92025-02-11 14:58:07 -08003794 m := ctx.ModuleForTests(t, "foo", "android_common")
Colin Crosscde55342024-03-27 14:11:51 -07003795 r8 := m.Rule("java.r8")
3796 implicits := r8.Implicits.RelativeToTop().Strings()
3797 android.AssertStringListContains(t, "r8 implicits", implicits, "lib1proguard.cfg")
3798 android.AssertStringListContains(t, "r8 implicits", implicits, "lib2proguard.cfg")
3799 android.AssertStringListContains(t, "r8 implicits", implicits, "lib4proguard.cfg")
3800 android.AssertStringListContains(t, "r8 implicits", implicits, "out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
Cole Faust9a631312020-10-22 21:05:24 +00003801
Colin Crosscde55342024-03-27 14:11:51 -07003802 flags := r8.Args["r8Flags"]
3803 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib1proguard.cfg")
3804 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib2proguard.cfg")
3805 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib4proguard.cfg")
3806 android.AssertStringDoesContain(t, "r8 flags", flags, "-include out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
Cole Faust9a631312020-10-22 21:05:24 +00003807}
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003808
3809func TestTargetSdkVersionManifestFixer(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003810 t.Parallel()
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003811 platform_sdk_codename := "Tiramisu"
Spandan Dasfb6a1ee2023-04-27 16:08:26 +00003812 platform_sdk_version := 33
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003813 testCases := []struct {
3814 name string
3815 targetSdkVersionInBp string
3816 targetSdkVersionExpected string
3817 unbundledBuild bool
Spandan Dasfb6a1ee2023-04-27 16:08:26 +00003818 platformSdkFinal bool
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003819 }{
3820 {
3821 name: "Non-Unbundled build: Android.bp has targetSdkVersion",
3822 targetSdkVersionInBp: "30",
3823 targetSdkVersionExpected: "30",
3824 unbundledBuild: false,
3825 },
3826 {
3827 name: "Unbundled build: Android.bp has targetSdkVersion",
3828 targetSdkVersionInBp: "30",
3829 targetSdkVersionExpected: "30",
3830 unbundledBuild: true,
3831 },
3832 {
3833 name: "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
3834 targetSdkVersionInBp: platform_sdk_codename,
3835 targetSdkVersionExpected: platform_sdk_codename,
3836 unbundledBuild: false,
3837 },
3838 {
3839 name: "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
3840 targetSdkVersionInBp: platform_sdk_codename,
3841 targetSdkVersionExpected: "10000",
3842 unbundledBuild: true,
3843 },
3844
3845 {
3846 name: "Non-Unbundled build: Android.bp has no targetSdkVersion",
3847 targetSdkVersionExpected: platform_sdk_codename,
3848 unbundledBuild: false,
3849 },
3850 {
3851 name: "Unbundled build: Android.bp has no targetSdkVersion",
3852 targetSdkVersionExpected: "10000",
3853 unbundledBuild: true,
3854 },
Spandan Dasfb6a1ee2023-04-27 16:08:26 +00003855 {
3856 name: "Bundled build in REL branches",
3857 targetSdkVersionExpected: "33",
3858 unbundledBuild: false,
3859 platformSdkFinal: true,
3860 },
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003861 }
3862 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08003863 t.Run(testCase.name, func(t *testing.T) {
3864 t.Parallel()
3865 targetSdkVersionTemplate := ""
3866 if testCase.targetSdkVersionInBp != "" {
3867 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
3868 }
3869 bp := fmt.Sprintf(`
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003870 android_app {
3871 name: "foo",
3872 sdk_version: "current",
Spandan Dasca70fc42023-03-01 23:38:49 +00003873 %s
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003874 }
Spandan Dasca70fc42023-03-01 23:38:49 +00003875 `, targetSdkVersionTemplate)
Colin Cross844cb6a2025-01-29 15:53:21 -08003876 fixture := android.GroupFixturePreparers(
3877 prepareForJavaTest,
3878 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3879 if testCase.platformSdkFinal {
3880 variables.Platform_sdk_final = proptools.BoolPtr(true)
3881 }
3882 // explicitly set platform_sdk_codename to make the test deterministic
3883 variables.Platform_sdk_codename = &platform_sdk_codename
3884 variables.Platform_sdk_version = &platform_sdk_version
3885 variables.Platform_version_active_codenames = []string{platform_sdk_codename}
3886 // create a non-empty list if unbundledBuild==true
3887 if testCase.unbundledBuild {
3888 variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
3889 }
3890 }),
3891 )
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003892
Colin Cross844cb6a2025-01-29 15:53:21 -08003893 result := fixture.RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08003894 foo := result.ModuleForTests(t, "foo", "android_common")
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003895
Colin Cross844cb6a2025-01-29 15:53:21 -08003896 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3897 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
3898 })
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003899 }
3900}
Colin Cross412436f2022-04-07 17:40:07 -07003901
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003902func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003903 t.Parallel()
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003904 platform_sdk_codename := "Tiramisu"
3905 platform_sdk_version := 33
3906 testCases := []struct {
3907 name string
3908 platform_sdk_final bool
3909 targetSdkVersionInBp *string
3910 targetSdkVersionExpected *string
3911 updatable bool
3912 }{
3913 {
3914 name: "Non-Updatable Module: Android.bp has older targetSdkVersion",
3915 targetSdkVersionInBp: proptools.StringPtr("29"),
3916 targetSdkVersionExpected: proptools.StringPtr("29"),
3917 updatable: false,
3918 },
3919 {
3920 name: "Updatable Module: Android.bp has older targetSdkVersion",
3921 targetSdkVersionInBp: proptools.StringPtr("30"),
3922 targetSdkVersionExpected: proptools.StringPtr("30"),
3923 updatable: true,
3924 },
3925 {
3926 name: "Updatable Module: Android.bp has no targetSdkVersion",
3927 targetSdkVersionExpected: proptools.StringPtr("10000"),
3928 updatable: true,
3929 },
3930 {
3931 name: "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion",
3932 platform_sdk_final: true,
3933 targetSdkVersionInBp: proptools.StringPtr("30"),
3934 targetSdkVersionExpected: proptools.StringPtr("30"),
3935 updatable: false,
3936 },
3937 {
3938 name: "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion",
3939 platform_sdk_final: true,
3940 targetSdkVersionInBp: proptools.StringPtr("30"),
3941 targetSdkVersionExpected: proptools.StringPtr("30"),
3942 updatable: true,
3943 },
3944 {
3945 name: "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename",
3946 platform_sdk_final: true,
3947 targetSdkVersionInBp: proptools.StringPtr(platform_sdk_codename),
3948 targetSdkVersionExpected: proptools.StringPtr("33"),
3949 updatable: true,
3950 },
3951 {
3952 name: "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion",
3953 platform_sdk_final: true,
3954 targetSdkVersionExpected: proptools.StringPtr("33"),
3955 updatable: true,
3956 },
3957 }
3958 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08003959 t.Run(testCase.name, func(t *testing.T) {
3960 t.Parallel()
3961 targetSdkVersionTemplate := ""
3962 if testCase.targetSdkVersionInBp != nil {
3963 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
3964 }
3965 bp := fmt.Sprintf(`
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003966 android_app {
3967 name: "foo",
3968 sdk_version: "current",
3969 min_sdk_version: "29",
Spandan Dasca70fc42023-03-01 23:38:49 +00003970 %s
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003971 updatable: %t,
3972 enforce_default_target_sdk_version: %t
3973 }
Spandan Dasca70fc42023-03-01 23:38:49 +00003974 `, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003975
Colin Cross844cb6a2025-01-29 15:53:21 -08003976 fixture := android.GroupFixturePreparers(
3977 PrepareForTestWithJavaDefaultModules,
3978 android.PrepareForTestWithAllowMissingDependencies,
3979 android.PrepareForTestWithAndroidMk,
3980 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3981 // explicitly set following platform variables to make the test deterministic
3982 variables.Platform_sdk_final = &testCase.platform_sdk_final
3983 variables.Platform_sdk_version = &platform_sdk_version
3984 variables.Platform_sdk_codename = &platform_sdk_codename
3985 variables.Platform_version_active_codenames = []string{platform_sdk_codename}
3986 variables.Unbundled_build = proptools.BoolPtr(true)
3987 variables.Unbundled_build_apps = []string{"sampleModule"}
3988 }),
3989 )
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003990
Colin Cross844cb6a2025-01-29 15:53:21 -08003991 result := fixture.RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08003992 foo := result.ModuleForTests(t, "foo", "android_common")
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003993
Colin Cross844cb6a2025-01-29 15:53:21 -08003994 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3995 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
3996 })
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003997 }
3998}
3999
4000func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004001 t.Parallel()
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004002 platform_sdk_codename := "Tiramisu"
4003 platform_sdk_version := 33
4004 testCases := []struct {
4005 name string
4006 enforceDefaultTargetSdkVersion bool
4007 expectedError string
4008 platform_sdk_final bool
4009 targetSdkVersionInBp string
4010 targetSdkVersionExpected string
4011 updatable bool
4012 }{
4013 {
4014 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
4015 enforceDefaultTargetSdkVersion: false,
4016 targetSdkVersionInBp: "29",
4017 targetSdkVersionExpected: "29",
4018 updatable: false,
4019 },
4020 {
4021 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
4022 enforceDefaultTargetSdkVersion: true,
4023 platform_sdk_final: true,
4024 targetSdkVersionInBp: "current",
4025 targetSdkVersionExpected: "33",
4026 updatable: true,
4027 },
4028 {
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004029 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004030 enforceDefaultTargetSdkVersion: true,
4031 platform_sdk_final: false,
4032 targetSdkVersionInBp: "current",
4033 targetSdkVersionExpected: "10000",
4034 updatable: false,
4035 },
4036 {
4037 name: "Not enforcing Target SDK Version for Updatable app",
4038 enforceDefaultTargetSdkVersion: false,
4039 expectedError: "Updatable apps must enforce default target sdk version",
4040 targetSdkVersionInBp: "29",
4041 targetSdkVersionExpected: "29",
4042 updatable: true,
4043 },
4044 }
4045 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004046 t.Run(testCase.name, func(t *testing.T) {
4047 t.Parallel()
4048 errExpected := testCase.expectedError != ""
4049 bp := fmt.Sprintf(`
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004050 android_app {
4051 name: "foo",
4052 enforce_default_target_sdk_version: %t,
4053 sdk_version: "current",
4054 min_sdk_version: "29",
4055 target_sdk_version: "%v",
4056 updatable: %t
4057 }
4058 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
4059
Colin Cross844cb6a2025-01-29 15:53:21 -08004060 fixture := android.GroupFixturePreparers(
4061 PrepareForTestWithJavaDefaultModules,
4062 android.PrepareForTestWithAllowMissingDependencies,
4063 android.PrepareForTestWithAndroidMk,
4064 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4065 // explicitly set following platform variables to make the test deterministic
4066 variables.Platform_sdk_final = &testCase.platform_sdk_final
4067 variables.Platform_sdk_version = &platform_sdk_version
4068 variables.Platform_sdk_codename = &platform_sdk_codename
4069 variables.Unbundled_build = proptools.BoolPtr(true)
4070 variables.Unbundled_build_apps = []string{"sampleModule"}
4071 }),
4072 )
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004073
Colin Cross844cb6a2025-01-29 15:53:21 -08004074 errorHandler := android.FixtureExpectsNoErrors
4075 if errExpected {
4076 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
4077 }
4078 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004079
Colin Cross844cb6a2025-01-29 15:53:21 -08004080 if !errExpected {
Colin Cross90607e92025-02-11 14:58:07 -08004081 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross844cb6a2025-01-29 15:53:21 -08004082 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
4083 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
4084 }
4085 })
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004086 }
4087}
4088
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004089func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004090 t.Parallel()
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004091 platform_sdk_codename := "Tiramisu"
4092 platform_sdk_version := 33
4093 testCases := []struct {
4094 name string
4095 enforceDefaultTargetSdkVersion bool
4096 expectedError string
4097 platform_sdk_final bool
4098 targetSdkVersionInBp string
4099 targetSdkVersionExpected string
4100 }{
4101 {
4102 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
4103 enforceDefaultTargetSdkVersion: false,
4104 targetSdkVersionInBp: "29",
4105 targetSdkVersionExpected: "29",
4106 },
4107 {
4108 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
4109 enforceDefaultTargetSdkVersion: true,
4110 platform_sdk_final: true,
4111 targetSdkVersionInBp: "current",
4112 targetSdkVersionExpected: "33",
4113 },
4114 {
4115 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
4116 enforceDefaultTargetSdkVersion: true,
4117 platform_sdk_final: false,
4118 targetSdkVersionInBp: "current",
4119 targetSdkVersionExpected: "10000",
4120 },
4121 }
4122 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004123 t.Run(testCase.name, func(t *testing.T) {
4124 t.Parallel()
4125 errExpected := testCase.expectedError != ""
4126 bp := fmt.Sprintf(`
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004127 android_test {
4128 name: "foo",
4129 enforce_default_target_sdk_version: %t,
4130 min_sdk_version: "29",
4131 target_sdk_version: "%v",
4132 }
4133 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp)
4134
Colin Cross844cb6a2025-01-29 15:53:21 -08004135 fixture := android.GroupFixturePreparers(
4136 PrepareForTestWithJavaDefaultModules,
4137 android.PrepareForTestWithAllowMissingDependencies,
4138 android.PrepareForTestWithAndroidMk,
4139 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4140 // explicitly set following platform variables to make the test deterministic
4141 variables.Platform_sdk_final = &testCase.platform_sdk_final
4142 variables.Platform_sdk_version = &platform_sdk_version
4143 variables.Platform_sdk_codename = &platform_sdk_codename
4144 variables.Unbundled_build = proptools.BoolPtr(true)
4145 variables.Unbundled_build_apps = []string{"sampleModule"}
4146 }),
4147 )
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004148
Colin Cross844cb6a2025-01-29 15:53:21 -08004149 errorHandler := android.FixtureExpectsNoErrors
4150 if errExpected {
4151 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
4152 }
4153 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004154
Colin Cross844cb6a2025-01-29 15:53:21 -08004155 if !errExpected {
Colin Cross90607e92025-02-11 14:58:07 -08004156 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross844cb6a2025-01-29 15:53:21 -08004157 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
4158 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
4159 }
4160 })
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004161 }
4162}
4163
Colin Cross412436f2022-04-07 17:40:07 -07004164func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004165 t.Parallel()
Colin Cross412436f2022-04-07 17:40:07 -07004166 result := android.GroupFixturePreparers(
4167 PrepareForTestWithJavaDefaultModules,
4168 android.PrepareForTestWithAllowMissingDependencies,
4169 android.PrepareForTestWithAndroidMk,
4170 ).RunTestWithBp(t, `
4171 android_app {
4172 name: "foo",
4173 srcs: ["a.java"],
4174 certificate: ":missing_certificate",
4175 sdk_version: "current",
Zyan Wub7550aa2023-05-18 15:46:31 +08004176 }
4177
4178 android_app {
4179 name: "bar",
4180 srcs: ["a.java"],
4181 certificate: ":missing_certificate",
4182 product_specific: true,
4183 sdk_version: "current",
Colin Cross412436f2022-04-07 17:40:07 -07004184 }`)
4185
Colin Cross90607e92025-02-11 14:58:07 -08004186 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross412436f2022-04-07 17:40:07 -07004187 fooApk := foo.Output("foo.apk")
4188 if fooApk.Rule != android.ErrorRule {
4189 t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
4190 }
4191 android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
4192}
Sam Delmerico82602492022-06-10 17:05:42 +00004193
4194func TestAppIncludesJniPackages(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004195 t.Parallel()
Sam Delmerico82602492022-06-10 17:05:42 +00004196 ctx := android.GroupFixturePreparers(
4197 PrepareForTestWithJavaDefaultModules,
4198 ).RunTestWithBp(t, `
4199 android_library_import {
4200 name: "aary-nodeps",
4201 aars: ["aary.aar"],
4202 extract_jni: true,
4203 }
4204
4205 android_library {
4206 name: "aary-lib",
4207 sdk_version: "current",
4208 min_sdk_version: "21",
4209 static_libs: ["aary-nodeps"],
4210 }
4211
4212 android_app {
4213 name: "aary-lib-dep",
4214 sdk_version: "current",
4215 min_sdk_version: "21",
4216 manifest: "AndroidManifest.xml",
4217 static_libs: ["aary-lib"],
4218 use_embedded_native_libs: true,
4219 }
4220
4221 android_app {
4222 name: "aary-import-dep",
4223 sdk_version: "current",
4224 min_sdk_version: "21",
4225 manifest: "AndroidManifest.xml",
4226 static_libs: ["aary-nodeps"],
4227 use_embedded_native_libs: true,
4228 }
4229
4230 android_app {
4231 name: "aary-no-use-embedded",
4232 sdk_version: "current",
4233 min_sdk_version: "21",
4234 manifest: "AndroidManifest.xml",
4235 static_libs: ["aary-nodeps"],
4236 }`)
4237
4238 testCases := []struct {
4239 name string
4240 hasPackage bool
4241 }{
4242 {
4243 name: "aary-import-dep",
4244 hasPackage: true,
4245 },
4246 {
4247 name: "aary-lib-dep",
4248 hasPackage: true,
4249 },
4250 {
4251 name: "aary-no-use-embedded",
Jiyong Parkd044bb42024-05-15 02:09:54 +09004252 hasPackage: false,
Sam Delmerico82602492022-06-10 17:05:42 +00004253 },
4254 }
4255
4256 for _, tc := range testCases {
4257 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004258 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08004259 app := ctx.ModuleForTests(t, tc.name, "android_common")
Sam Delmerico82602492022-06-10 17:05:42 +00004260
4261 outputFile := "jnilibs.zip"
4262 jniOutputLibZip := app.MaybeOutput(outputFile)
4263 if jniOutputLibZip.Rule == nil && !tc.hasPackage {
4264 return
4265 }
4266
4267 jniPackage := "arm64-v8a_jni.zip"
4268 inputs := jniOutputLibZip.Inputs
4269 foundPackage := false
4270 for i := 0; i < len(inputs); i++ {
4271 if strings.Contains(inputs[i].String(), jniPackage) {
4272 foundPackage = true
4273 }
4274 }
4275 if foundPackage != tc.hasPackage {
4276 t.Errorf("expected to find %v in %v inputs; inputs = %v", jniPackage, outputFile, inputs)
4277 }
4278 })
4279 }
4280}
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004281
4282func TestTargetSdkVersionMtsTests(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004283 t.Parallel()
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004284 platformSdkCodename := "Tiramisu"
4285 android_test := "android_test"
4286 android_test_helper_app := "android_test_helper_app"
4287 bpTemplate := `
4288 %v {
4289 name: "mytest",
Spandan Dasb0410872024-06-25 03:30:03 +00004290 min_sdk_version: "34",
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004291 target_sdk_version: "%v",
4292 test_suites: ["othersuite", "%v"],
4293 }
4294 `
4295 testCases := []struct {
4296 desc string
4297 moduleType string
4298 targetSdkVersionInBp string
4299 targetSdkVersionExpected string
4300 testSuites string
4301 }{
4302 {
4303 desc: "Non-MTS android_test_apps targeting current should not be upgraded to 10000",
4304 moduleType: android_test,
4305 targetSdkVersionInBp: "current",
4306 targetSdkVersionExpected: platformSdkCodename,
4307 testSuites: "non-mts-suite",
4308 },
4309 {
4310 desc: "MTS android_test_apps targeting released sdks should not be upgraded to 10000",
4311 moduleType: android_test,
4312 targetSdkVersionInBp: "29",
4313 targetSdkVersionExpected: "29",
4314 testSuites: "mts-suite",
4315 },
4316 {
4317 desc: "MTS android_test_apps targeting current should be upgraded to 10000",
4318 moduleType: android_test,
4319 targetSdkVersionInBp: "current",
4320 targetSdkVersionExpected: "10000",
4321 testSuites: "mts-suite",
4322 },
4323 {
4324 desc: "MTS android_test_helper_apps targeting current should be upgraded to 10000",
4325 moduleType: android_test_helper_app,
4326 targetSdkVersionInBp: "current",
4327 targetSdkVersionExpected: "10000",
4328 testSuites: "mts-suite",
4329 },
4330 }
4331 fixture := android.GroupFixturePreparers(
4332 prepareForJavaTest,
4333 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4334 variables.Platform_sdk_codename = &platformSdkCodename
4335 variables.Platform_version_active_codenames = []string{platformSdkCodename}
4336 }),
4337 )
4338 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004339 t.Run(testCase.desc, func(t *testing.T) {
4340 t.Parallel()
4341 result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
Colin Cross90607e92025-02-11 14:58:07 -08004342 mytest := result.ModuleForTests(t, "mytest", "android_common")
Colin Cross844cb6a2025-01-29 15:53:21 -08004343 manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
4344 android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
4345 })
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004346 }
4347}
Andrei Onea580636b2022-08-17 16:53:46 +00004348
4349func TestPrivappAllowlist(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004350 t.Parallel()
Andrei Onea580636b2022-08-17 16:53:46 +00004351 testJavaError(t, "privileged must be set in order to use privapp_allowlist", `
4352 android_app {
4353 name: "foo",
4354 srcs: ["a.java"],
4355 privapp_allowlist: "perms.xml",
4356 }
4357 `)
4358
4359 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
4360 t,
4361 `
4362 android_app {
4363 name: "foo",
4364 srcs: ["a.java"],
Sam Delmerico15809f82023-05-15 17:21:47 -04004365 privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
Andrei Onea580636b2022-08-17 16:53:46 +00004366 privileged: true,
Andrei Onea580636b2022-08-17 16:53:46 +00004367 sdk_version: "current",
4368 }
4369 override_android_app {
4370 name: "bar",
4371 base: "foo",
4372 package_name: "com.google.android.foo",
4373 }
4374 `,
4375 )
Colin Cross90607e92025-02-11 14:58:07 -08004376 app := result.ModuleForTests(t, "foo", "android_common")
4377 overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
Andrei Onea580636b2022-08-17 16:53:46 +00004378
Sam Delmerico15809f82023-05-15 17:21:47 -04004379 // verify that privapp allowlist is created for override apps
Andrei Onea580636b2022-08-17 16:53:46 +00004380 overrideApp.Output("out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml")
Sam Delmerico15809f82023-05-15 17:21:47 -04004381 expectedAllowlistInput := "privapp_allowlist_com.android.foo.xml"
4382 overrideActualAllowlistInput := overrideApp.Rule("modifyAllowlist").Input.String()
4383 if expectedAllowlistInput != overrideActualAllowlistInput {
4384 t.Errorf("expected override allowlist to be %q; got %q", expectedAllowlistInput, overrideActualAllowlistInput)
Andrei Onea580636b2022-08-17 16:53:46 +00004385 }
4386
4387 // verify that permissions are copied to device
Cole Faust6b7075f2024-12-17 10:42:42 -08004388 app.Output("out/target/product/test_device/system/etc/permissions/foo.xml")
4389 overrideApp.Output("out/target/product/test_device/system/etc/permissions/bar.xml")
Andrei Onea580636b2022-08-17 16:53:46 +00004390}
Sam Delmericob1daccd2023-05-25 14:45:30 -04004391
4392func TestPrivappAllowlistAndroidMk(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004393 t.Parallel()
Sam Delmericob1daccd2023-05-25 14:45:30 -04004394 result := android.GroupFixturePreparers(
4395 PrepareForTestWithJavaDefaultModules,
4396 android.PrepareForTestWithAndroidMk,
4397 ).RunTestWithBp(
4398 t,
4399 `
4400 android_app {
4401 name: "foo",
4402 srcs: ["a.java"],
4403 privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
4404 privileged: true,
4405 sdk_version: "current",
4406 }
4407 override_android_app {
4408 name: "bar",
4409 base: "foo",
4410 package_name: "com.google.android.foo",
4411 }
4412 `,
4413 )
Colin Cross90607e92025-02-11 14:58:07 -08004414 baseApp := result.ModuleForTests(t, "foo", "android_common")
4415 overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
Sam Delmericob1daccd2023-05-25 14:45:30 -04004416
4417 baseAndroidApp := baseApp.Module().(*AndroidApp)
4418 baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0]
4419 android.AssertStringMatches(
4420 t,
4421 "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find foo.apk",
4422 baseEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
4423 "\\S+foo.apk",
4424 )
4425 android.AssertStringMatches(
4426 t,
4427 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include foo.apk",
4428 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4429 "\\S+foo.apk",
4430 )
4431 android.AssertStringMatches(
4432 t,
4433 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
4434 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4435 "\\S+foo.apk:\\S+/target/product/test_device/system/priv-app/foo/foo.apk",
4436 )
4437 android.AssertStringMatches(
4438 t,
4439 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
4440 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
Anton Hansson0e486a42023-06-01 16:38:35 +00004441 "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml",
Sam Delmericob1daccd2023-05-25 14:45:30 -04004442 )
4443
4444 overrideAndroidApp := overrideApp.Module().(*AndroidApp)
4445 overrideEntries := android.AndroidMkEntriesForTest(t, result.TestContext, overrideAndroidApp)[0]
4446 android.AssertStringMatches(
4447 t,
4448 "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find bar.apk",
4449 overrideEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
4450 "\\S+bar.apk",
4451 )
4452 android.AssertStringMatches(
4453 t,
4454 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include bar.apk",
4455 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4456 "\\S+bar.apk",
4457 )
4458 android.AssertStringMatches(
4459 t,
4460 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
4461 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4462 "\\S+bar.apk:\\S+/target/product/test_device/system/priv-app/bar/bar.apk",
4463 )
4464 android.AssertStringMatches(
4465 t,
4466 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
4467 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
Anton Hansson0e486a42023-06-01 16:38:35 +00004468 "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml",
Sam Delmericob1daccd2023-05-25 14:45:30 -04004469 )
4470}
Sam Delmerico0e0d96e2023-08-18 22:43:28 +00004471
Jihoon Kang84b25892023-12-01 22:01:06 +00004472func TestAppFlagsPackages(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004473 t.Parallel()
Jihoon Kang98ea8362024-07-16 18:20:03 +00004474 ctx := android.GroupFixturePreparers(
4475 prepareForJavaTest,
4476 android.FixtureMergeMockFs(
4477 map[string][]byte{
4478 "res/layout/layout.xml": nil,
4479 "res/values/strings.xml": nil,
4480 "res/values-en-rUS/strings.xml": nil,
4481 },
4482 ),
4483 ).RunTestWithBp(t, `
Jihoon Kang84b25892023-12-01 22:01:06 +00004484 android_app {
4485 name: "foo",
4486 srcs: ["a.java"],
4487 sdk_version: "current",
4488 flags_packages: [
4489 "bar",
4490 "baz",
4491 ],
4492 }
4493 aconfig_declarations {
4494 name: "bar",
Dennis Shen4e7773d2024-01-05 19:06:50 +00004495 package: "com.example.package.bar",
Yu Liu315a53c2024-04-24 16:41:57 +00004496 container: "com.android.foo",
Jihoon Kang84b25892023-12-01 22:01:06 +00004497 srcs: [
4498 "bar.aconfig",
4499 ],
4500 }
4501 aconfig_declarations {
4502 name: "baz",
Dennis Shen4e7773d2024-01-05 19:06:50 +00004503 package: "com.example.package.baz",
Yu Liu315a53c2024-04-24 16:41:57 +00004504 container: "com.android.foo",
Jihoon Kang84b25892023-12-01 22:01:06 +00004505 srcs: [
4506 "baz.aconfig",
4507 ],
4508 }
4509 `)
4510
Colin Cross90607e92025-02-11 14:58:07 -08004511 foo := ctx.ModuleForTests(t, "foo", "android_common")
Jihoon Kang84b25892023-12-01 22:01:06 +00004512
4513 // android_app module depends on aconfig_declarations listed in flags_packages
4514 android.AssertBoolEquals(t, "foo expected to depend on bar", true,
Jihoon Kang98ea8362024-07-16 18:20:03 +00004515 CheckModuleHasDependency(t, ctx.TestContext, "foo", "android_common", "bar"))
Jihoon Kang84b25892023-12-01 22:01:06 +00004516
4517 android.AssertBoolEquals(t, "foo expected to depend on baz", true,
Jihoon Kang98ea8362024-07-16 18:20:03 +00004518 CheckModuleHasDependency(t, ctx.TestContext, "foo", "android_common", "baz"))
Jihoon Kang84b25892023-12-01 22:01:06 +00004519
4520 aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
4521 linkInFlags := aapt2LinkRule.Args["inFlags"]
4522 android.AssertStringDoesContain(t,
4523 "aapt2 link command expected to pass feature flags arguments",
4524 linkInFlags,
4525 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
4526 )
Jihoon Kang98ea8362024-07-16 18:20:03 +00004527
4528 aapt2CompileRule := foo.Rule("android/soong/java.aapt2Compile")
4529 compileFlags := aapt2CompileRule.Args["cFlags"]
4530 android.AssertStringDoesContain(t,
4531 "aapt2 compile command expected to pass feature flags arguments",
4532 compileFlags,
4533 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
4534 )
Jihoon Kang84b25892023-12-01 22:01:06 +00004535}
Spandan Das0727ba72024-02-13 16:37:43 +00004536
Jihoon Kang9aef7772024-06-14 23:45:06 +00004537func TestAppFlagsPackagesPropagation(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004538 t.Parallel()
Jihoon Kang9aef7772024-06-14 23:45:06 +00004539 ctx := testApp(t, `
4540 aconfig_declarations {
4541 name: "foo",
4542 package: "com.example.package.foo",
4543 container: "com.android.foo",
4544 srcs: [
4545 "foo.aconfig",
4546 ],
4547 }
4548 aconfig_declarations {
4549 name: "bar",
4550 package: "com.example.package.bar",
4551 container: "com.android.bar",
4552 srcs: [
4553 "bar.aconfig",
4554 ],
4555 }
4556 aconfig_declarations {
4557 name: "baz",
4558 package: "com.example.package.baz",
4559 container: "com.android.baz",
4560 srcs: [
4561 "baz.aconfig",
4562 ],
4563 }
4564 android_library {
4565 name: "foo_lib",
4566 srcs: ["a.java"],
4567 sdk_version: "current",
4568 flags_packages: [
4569 "foo",
4570 ],
4571 }
4572 android_library {
4573 name: "bar_lib",
4574 srcs: ["a.java"],
4575 sdk_version: "current",
4576 flags_packages: [
4577 "bar",
4578 ],
4579 }
4580 android_app {
4581 name: "baz_app",
4582 srcs: ["a.java"],
4583 sdk_version: "current",
4584 flags_packages: [
4585 "baz",
4586 ],
4587 static_libs: [
4588 "bar_lib",
4589 ],
4590 libs: [
4591 "foo_lib",
4592 ],
4593 }
4594 `)
4595
Colin Cross90607e92025-02-11 14:58:07 -08004596 bazApp := ctx.ModuleForTests(t, "baz_app", "android_common")
Jihoon Kang9aef7772024-06-14 23:45:06 +00004597
4598 // android_app module depends on aconfig_declarations listed in flags_packages
4599 // and that of static libs, but not libs
4600 aapt2LinkRule := bazApp.Rule("android/soong/java.aapt2Link")
4601 linkInFlags := aapt2LinkRule.Args["inFlags"]
4602 android.AssertStringDoesContain(t,
4603 "aapt2 link command expected to pass feature flags arguments of flags_packages and that of its static libs",
4604 linkInFlags,
4605 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
4606 )
4607 android.AssertStringDoesNotContain(t,
4608 "aapt2 link command expected to not pass feature flags arguments of flags_packages of its libs",
4609 linkInFlags,
4610 "--feature-flags @out/soong/.intermediates/foo/intermediate.txt",
4611 )
4612}
4613
Spandan Das0727ba72024-02-13 16:37:43 +00004614// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
4615func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004616 t.Parallel()
Spandan Das0727ba72024-02-13 16:37:43 +00004617 bp := `
4618 java_sdk_library_import {
4619 name: "sdklib_noimpl",
4620 public: {
4621 jars: ["stub.jar"],
4622 },
4623 }
4624 android_app {
4625 name: "app",
4626 srcs: ["a.java"],
4627 sdk_version: "current",
4628 optional_uses_libs: [
4629 "sdklib_noimpl",
4630 ],
4631 }
4632 `
4633 result := prepareForJavaTest.RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08004634 dexpreopt := result.ModuleForTests(t, "app", "android_common").MaybeRule("dexpreopt").Rule
Spandan Das0727ba72024-02-13 16:37:43 +00004635 android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil)
4636}
yangbill2af0b6e2024-03-15 09:29:29 +00004637
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07004638func TestTestOnlyApp(t *testing.T) {
4639 t.Parallel()
4640 ctx := android.GroupFixturePreparers(
4641 prepareForJavaTest,
4642 ).RunTestWithBp(t, `
4643 // These should be test-only
4644 android_test {
4645 name: "android-test",
4646 }
4647 android_test_helper_app {
4648 name: "helper-app",
4649 }
4650 override_android_test {
4651 name: "override-test",
4652 base: "android-app",
4653 }
4654 // And these should not be
4655 android_app {
4656 name: "android-app",
4657 srcs: ["b.java"],
4658 sdk_version: "current",
4659 }
4660 `)
4661
4662 expectedTestOnly := []string{
4663 "android-test",
4664 "helper-app",
4665 "override-test",
4666 }
4667
4668 expectedTopLevel := []string{
4669 "android-test",
4670 "override-test",
4671 }
4672
4673 assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel)
4674}
4675
Jiyong Parkf528b702024-12-30 16:01:58 +09004676func TestTestConfigTemplate(t *testing.T) {
4677 t.Parallel()
4678 ctx := android.GroupFixturePreparers(
4679 prepareForJavaTest,
4680 ).RunTestWithBp(t, `
4681 android_test {
4682 name: "android-test",
4683 test_config_template: "AndroidTestTemplate.xml",
4684 test_options: {
4685 tradefed_options: [
4686 {
4687 name: "name1",
4688 key: "key1",
4689 value: "value1",
4690 },
4691 {
4692 name: "name2",
4693 key: "key2",
4694 value: "value2",
4695 },
4696 ],
4697 test_runner_options: [
4698 {
4699 name: "name3",
4700 key: "key3",
4701 value: "value3",
4702 },
4703 {
4704 name: "name4",
4705 key: "key4",
4706 value: "value4",
4707 },
4708 ],
4709 },
4710 }
4711 `)
4712 type option struct {
4713 name string
4714 key string
4715 value string
4716 }
4717 re := regexp.MustCompile(`<option name="(.*)" key="(.*)" value="(.*)" />`)
4718 parse_options := func(optionsString string) []option {
4719 lines := strings.Split(optionsString, `\n`)
4720 var ret []option
4721 for _, l := range lines {
4722 sm := re.FindStringSubmatch(l)
4723 if sm == nil {
4724 continue
4725 }
4726 ret = append(ret, option{sm[1], sm[2], sm[3]})
4727 }
4728 return ret
4729 }
Colin Cross90607e92025-02-11 14:58:07 -08004730 rule := ctx.ModuleForTests(t, "android-test", "android_common").Rule("autogenInstrumentationTest")
Jiyong Parkf528b702024-12-30 16:01:58 +09004731 android.AssertSameArray(t, "extraConfigs mismatch",
4732 []option{
4733 {"name1", "key1", "value1"},
4734 {"name2", "key2", "value2"},
4735 },
4736 parse_options(rule.Args["extraConfigs"]))
4737 android.AssertSameArray(t, "extraTestRunnerConfigs mismatch",
4738 []option{
4739 {"name3", "key3", "value3"},
4740 {"name4", "key4", "value4"},
4741 },
4742 parse_options(rule.Args["extraTestRunnerConfigs"]))
4743}
4744
yangbill2af0b6e2024-03-15 09:29:29 +00004745func TestAppStem(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004746 t.Parallel()
yangbill2af0b6e2024-03-15 09:29:29 +00004747 ctx := testApp(t, `
4748 android_app {
4749 name: "foo",
4750 srcs: ["a.java"],
4751 stem: "foo-new",
4752 sdk_version: "current",
4753 }`)
4754
Colin Cross90607e92025-02-11 14:58:07 -08004755 foo := ctx.ModuleForTests(t, "foo", "android_common")
yangbill2af0b6e2024-03-15 09:29:29 +00004756
4757 outputs := fmt.Sprint(foo.AllOutputs())
4758 if !strings.Contains(outputs, "foo-new.apk") {
4759 t.Errorf("Module output does not contain expected apk %s", "foo-new.apk")
4760 }
4761}
Spandan Dasb9c58352024-05-13 18:29:45 +00004762
4763func TestAppMinSdkVersionOverride(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004764 t.Parallel()
Spandan Dasb9c58352024-05-13 18:29:45 +00004765 result := android.GroupFixturePreparers(
4766 PrepareForTestWithJavaDefaultModules,
4767 ).RunTestWithBp(t, `
4768 android_app {
4769 name: "com.android.foo",
4770 srcs: ["a.java"],
4771 sdk_version: "current",
4772 min_sdk_version: "31",
4773 updatable: true,
4774 }
4775 override_android_app {
4776 name: "com.android.go.foo",
4777 base: "com.android.foo",
4778 min_sdk_version: "33",
4779 }
4780 `)
Colin Cross90607e92025-02-11 14:58:07 -08004781 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
4782 fooOverride := result.ModuleForTests(t, "com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
Spandan Dasb9c58352024-05-13 18:29:45 +00004783
4784 android.AssertStringDoesContain(t,
4785 "com.android.foo: expected manifest fixer to set minSdkVersion to T",
4786 foo.BuildParams.Args["args"],
4787 "--minSdkVersion 31",
4788 )
4789 android.AssertStringDoesContain(t,
4790 "com.android.go.foo: expected manifest fixer to set minSdkVersion to T",
4791 fooOverride.BuildParams.Args["args"],
4792 "--minSdkVersion 33",
4793 )
4794
4795}
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004796
4797func TestNotApplyDefaultUpdatableModuleVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004798 t.Parallel()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004799 result := android.GroupFixturePreparers(
4800 PrepareForTestWithJavaDefaultModules,
4801 ).RunTestWithBp(t, `
4802 android_app {
4803 name: "com.android.foo",
4804 srcs: ["a.java"],
4805 sdk_version: "current",
4806 min_sdk_version: "31",
4807 }
4808 `)
Colin Cross90607e92025-02-11 14:58:07 -08004809 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004810 android.AssertStringDoesNotContain(t,
4811 "com.android.foo: expected manifest fixer to not set override-placeholder-version",
4812 foo.BuildParams.Args["args"],
4813 "--override-placeholder-version",
4814 )
4815}
4816
4817func TestNotApplyOverrideApexManifestDefaultVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004818 t.Parallel()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004819 result := android.GroupFixturePreparers(
4820 PrepareForTestWithJavaDefaultModules,
4821 android.FixtureMergeEnv(map[string]string{
4822 "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234",
4823 }),
4824 ).RunTestWithBp(t, `
4825 android_app {
4826 name: "com.android.foo",
4827 srcs: ["a.java"],
4828 sdk_version: "current",
4829 min_sdk_version: "31",
4830 }
4831 `)
Colin Cross90607e92025-02-11 14:58:07 -08004832 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004833 android.AssertStringDoesNotContain(t,
4834 "com.android.foo: expected manifest fixer to not set override-placeholder-version",
4835 foo.BuildParams.Args["args"],
4836 "--override-placeholder-version",
4837 )
4838}
Jihoon Kang1c743042024-10-22 21:34:17 +00004839
4840func TestResourcesWithFlagDirectories(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004841 t.Parallel()
Jihoon Kang1c743042024-10-22 21:34:17 +00004842 result := android.GroupFixturePreparers(
4843 PrepareForTestWithJavaDefaultModules,
4844 android.FixtureMergeMockFs(android.MockFS{
4845 "res/flag(test.package.flag1)/values/bools.xml": nil,
4846 "res/flag(!test.package.flag2)/values/bools.xml": nil,
4847 "res/flag(test.package.flag1)/values-config/strings_google_services.xml": nil,
4848 "res/flags(test.package.flag1)/values/strings.xml": nil,
4849 }),
4850 ).RunTestWithBp(t, `
4851 android_library {
4852 name: "foo",
4853 srcs: ["a.java"],
4854 use_resource_processor: true,
4855 resource_dirs: [
4856 "res",
4857 ],
4858 }
4859 `)
Colin Cross90607e92025-02-11 14:58:07 -08004860 fooModule := result.ModuleForTests(t, "foo", "android_common")
Jihoon Kang1c743042024-10-22 21:34:17 +00004861 compileOutputPaths := fooModule.Rule("aapt2Compile").Outputs.Strings()
4862
4863 android.AssertStringListContains(
4864 t,
4865 "Expected to generate flag path",
4866 compileOutputPaths,
4867 "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(test.package.flag1).arsc.flat",
4868 )
4869 android.AssertStringListContains(
4870 t,
4871 "Expected to generate flag path with ! prefix in name",
4872 compileOutputPaths,
4873 "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(!test.package.flag2).arsc.flat",
4874 )
4875 android.AssertStringListContains(
4876 t,
4877 "Expected to generate flag path with configs",
4878 compileOutputPaths,
4879 "out/soong/.intermediates/foo/android_common/aapt2/res/values-config_strings_google_services.(test.package.flag1).arsc.flat",
4880 )
4881 android.AssertStringListDoesNotContain(
4882 t,
4883 "Expected to not generate flag path with non-flag(flag_name) pattern",
4884 compileOutputPaths,
4885 "out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat",
4886 )
4887}
Spandan Dasde588a32024-12-03 22:52:24 +00004888
4889func TestAutogeneratedStaticRro(t *testing.T) {
4890 t.Parallel()
4891 bp := `
4892android_app {
4893 name: "foo",
4894 srcs: ["foo.java"],
4895 platform_apis: true,
4896}
4897override_android_app {
4898 name: "override_foo",
4899 base: "foo",
4900}
4901`
4902 testCases := []struct {
4903 desc string
4904 preparer android.FixturePreparer
4905 overlayApkExpected bool
4906 }{
4907 {
4908 desc: "No DEVICE_PACKAGE_OVERLAYS, no overlay .apk file",
4909 overlayApkExpected: false,
4910 },
4911 {
4912 desc: "DEVICE_PACKAGE_OVERLAYS exists, but the directory is empty",
4913 overlayApkExpected: false,
4914 preparer: android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4915 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
4916 }),
4917 },
4918 {
4919 desc: "DEVICE_PACKAGE_OVERLAYS exists, directory is non-empty, but does not contain a matching resource dir",
4920 overlayApkExpected: false,
4921 preparer: android.GroupFixturePreparers(
4922 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4923 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
4924 }),
4925 android.MockFS{
4926 "res/foo.xml": nil,
4927 "device/company/test_product/different_res/foo.xml": nil, // different dir
4928 }.AddToFixture(),
4929 ),
4930 },
4931 {
4932 desc: "DEVICE_PACKAGE_OVERLAYS and the directory contain a matching resource dir",
4933 overlayApkExpected: true,
4934 preparer: android.GroupFixturePreparers(
4935 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4936 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
4937 }),
4938 android.MockFS{
4939 "res/foo.xml": nil,
4940 "device/company/test_product/res/foo.xml": nil,
4941 }.AddToFixture(),
4942 ),
4943 },
4944 }
4945 for _, tc := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004946 t.Run(tc.desc, func(t *testing.T) {
4947 t.Parallel()
4948 result := android.GroupFixturePreparers(
4949 PrepareForTestWithJavaDefaultModules,
4950 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4951 variables.EnforceRROTargets = []string{"*"}
4952 }),
4953 android.OptionalFixturePreparer(tc.preparer),
4954 ).RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08004955 vendorOverlayApk := result.ModuleForTests(t, "foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("foo__test_product__auto_generated_rro_vendor.apk")
Colin Cross844cb6a2025-01-29 15:53:21 -08004956 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil)
Colin Cross90607e92025-02-11 14:58:07 -08004957 overrideVendorOverlayApk := result.ModuleForTests(t, "override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("override_foo__test_product__auto_generated_rro_vendor.apk")
Colin Cross844cb6a2025-01-29 15:53:21 -08004958 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil)
4959 })
Spandan Dasde588a32024-12-03 22:52:24 +00004960 }
4961}
Spandan Dasef8b3b22024-12-04 01:34:34 +00004962
4963func TestNoAutogeneratedStaticRroForDisabledOverrideApps(t *testing.T) {
4964 t.Parallel()
4965 bp := `
4966soong_config_module_type {
4967 name: "my_custom_override_android_app",
4968 module_type: "override_android_app",
4969 config_namespace: "my_namespace",
4970 value_variables: ["my_app_enabled"],
4971 properties: ["enabled"],
4972}
4973soong_config_bool_variable {
4974 name: "my_app_enabled",
4975}
4976android_app {
4977 name: "foo",
4978 srcs: ["foo.java"],
4979 platform_apis: true,
4980}
4981my_custom_override_android_app {
4982 name: "override_foo",
4983 base: "foo",
4984 soong_config_variables: {
4985 my_app_enabled: {
4986 enabled: true,
4987 conditions_default: {
4988 enabled: false
4989 },
4990 },
4991 }
4992}
4993`
4994 testCases := []struct {
4995 desc string
4996 preparer android.FixturePreparer
4997 overlayApkExpected bool
4998 }{
4999 {
5000 desc: "my_app_enabled is empty",
5001 overlayApkExpected: false,
5002 },
5003 {
5004 desc: "my_app_enabled is true",
5005 overlayApkExpected: true,
5006 preparer: android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5007 variables.VendorVars = map[string]map[string]string{
5008 "my_namespace": {
5009 "my_app_enabled": "true",
5010 },
5011 }
5012 }),
5013 },
5014 }
5015 for _, tc := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08005016 t.Run(tc.desc, func(t *testing.T) {
5017 t.Parallel()
5018 result := android.GroupFixturePreparers(
5019 PrepareForTestWithJavaDefaultModules,
5020 android.PrepareForTestWithSoongConfigModuleBuildComponents,
5021 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5022 variables.EnforceRROTargets = []string{"*"}
5023 }),
5024 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5025 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
5026 }),
5027 android.MockFS{
5028 "res/foo.xml": nil,
5029 "device/company/test_product/res/foo.xml": nil,
5030 }.AddToFixture(),
5031 android.OptionalFixturePreparer(tc.preparer),
5032 ).RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08005033 overrideVendorOverlayApk := result.ModuleForTests(t, "override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").Module().(*AutogenRuntimeResourceOverlay)
Colin Cross844cb6a2025-01-29 15:53:21 -08005034 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.exportPackage != nil)
5035 })
Spandan Dasef8b3b22024-12-04 01:34:34 +00005036 }
5037}