blob: 4f23f61a4efe72d7a3e8cc30ee0d1128fbf886e6 [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"}: {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001483 "out/soong/.intermediates/lib2/android_common/package-res.apk",
Colin Crossbec85302019-02-13 13:15:46 -08001484 "lib/res/res/values/strings.xml",
1485 "device/vendor/blah/overlay/lib/res/values/strings.xml",
1486 },
Colin Cross5c4791c2019-02-01 11:44:44 -08001487 },
Colin Crossc4441622024-09-18 14:55:49 -07001488 rroDirs: map[moduleAndVariant][]string{
1489 {"foo", "android_common"}: nil,
1490 {"bar", "android_common"}: nil,
Colin Cross5c4791c2019-02-01 11:44:44 -08001491 },
1492 },
1493 {
1494 name: "enforce RRO on foo",
1495 enforceRROTargets: []string{"foo"},
1496 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossc4441622024-09-18 14:55:49 -07001497 resourceFiles: map[moduleAndVariant][]string{
1498 {"foo", "android_common"}: nil,
1499 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
1500 {"lib", "android_common"}: nil,
1501 {"lib", "android_common_rro"}: nil,
1502 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
1503 {"lib2", "android_common_rro"}: {"lib2/res/res/values/strings.xml"},
Colin Crossbec85302019-02-13 13:15:46 -08001504 },
Colin Crossc4441622024-09-18 14:55:49 -07001505 overlayFiles: map[moduleAndVariant][]string{
1506 {"foo", "android_common"}: {
1507 "out/soong/.intermediates/lib2/android_common_rro/package-res.apk",
1508 "out/soong/.intermediates/lib/android_common_rro/package-res.apk",
1509 "out/soong/.intermediates/lib3/android_common_rro/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -08001510 "foo/res/res/values/strings.xml",
1511 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
1512 },
Colin Crossc4441622024-09-18 14:55:49 -07001513 {"bar", "android_common"}: {
Colin Cross5c4791c2019-02-01 11:44:44 -08001514 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
1515 "device/vendor/blah/overlay/bar/res/values/strings.xml",
1516 },
Colin Crossc4441622024-09-18 14:55:49 -07001517 {"lib", "android_common"}: {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001518 "out/soong/.intermediates/lib2/android_common/package-res.apk",
Colin Crossbec85302019-02-13 13:15:46 -08001519 "lib/res/res/values/strings.xml",
Colin Crossc4441622024-09-18 14:55:49 -07001520 "device/vendor/blah/overlay/lib/res/values/strings.xml",
1521 },
1522 {"lib", "android_common_rro"}: {
1523 "out/soong/.intermediates/lib2/android_common_rro/package-res.apk",
1524 "lib/res/res/values/strings.xml",
Colin Crossbec85302019-02-13 13:15:46 -08001525 },
Colin Cross5c4791c2019-02-01 11:44:44 -08001526 },
Colin Crossc1c37552019-01-31 11:42:41 -08001527
Colin Crossc4441622024-09-18 14:55:49 -07001528 rroDirs: map[moduleAndVariant][]string{
1529 {"foo", "android_common"}: {
Anton Hansson53c88442019-03-18 15:53:16 +00001530 "device:device/vendor/blah/overlay/foo/res",
Anton Hansson53c88442019-03-18 15:53:16 +00001531 "product:product/vendor/blah/overlay/foo/res",
Jaewoong Jungc779cd42020-10-06 18:56:10 -07001532 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -08001533 },
Colin Crossc4441622024-09-18 14:55:49 -07001534 {"bar", "android_common"}: nil,
1535 {"lib", "android_common"}: nil,
1536 {"lib", "android_common_rro"}: {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -08001537 },
1538 },
1539 {
1540 name: "enforce RRO on all",
1541 enforceRROTargets: []string{"*"},
1542 enforceRROExcludedOverlays: []string{
1543 // Excluding specific apps/res directories also allowed.
1544 "device/vendor/blah/static_overlay/foo",
1545 "device/vendor/blah/static_overlay/bar/res",
1546 },
Colin Crossc4441622024-09-18 14:55:49 -07001547 resourceFiles: map[moduleAndVariant][]string{
1548 {"foo", "android_common"}: nil,
1549 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"},
1550 {"lib", "android_common"}: nil,
1551 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"},
Colin Crossbec85302019-02-13 13:15:46 -08001552 },
Colin Crossc4441622024-09-18 14:55:49 -07001553 overlayFiles: map[moduleAndVariant][]string{
1554 {"foo", "android_common"}: {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001555 "out/soong/.intermediates/lib2/android_common/package-res.apk",
1556 "out/soong/.intermediates/lib/android_common/package-res.apk",
1557 "out/soong/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -08001558 "foo/res/res/values/strings.xml",
1559 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
1560 },
Colin Crossc4441622024-09-18 14:55:49 -07001561 {"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
1562 {"lib", "android_common"}: {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001563 "out/soong/.intermediates/lib2/android_common/package-res.apk",
Colin Crossbec85302019-02-13 13:15:46 -08001564 "lib/res/res/values/strings.xml",
1565 },
Colin Cross5c4791c2019-02-01 11:44:44 -08001566 },
Colin Crossc4441622024-09-18 14:55:49 -07001567 rroDirs: map[moduleAndVariant][]string{
1568 {"foo", "android_common"}: {
Anton Hansson53c88442019-03-18 15:53:16 +00001569 "device:device/vendor/blah/overlay/foo/res",
1570 "product:product/vendor/blah/overlay/foo/res",
1571 // Lib dep comes after the direct deps
1572 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -08001573 },
Colin Crossc4441622024-09-18 14:55:49 -07001574 {"bar", "android_common"}: {"device:device/vendor/blah/overlay/bar/res"},
1575 {"lib", "android_common"}: {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -08001576 },
1577 },
1578 }
1579
Anton Hansson53c88442019-03-18 15:53:16 +00001580 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -08001581 "device/vendor/blah/overlay",
1582 "device/vendor/blah/overlay2",
1583 "device/vendor/blah/static_overlay",
1584 }
1585
Anton Hansson53c88442019-03-18 15:53:16 +00001586 productResourceOverlays := []string{
1587 "product/vendor/blah/overlay",
1588 }
1589
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001590 fs := android.MockFS{
Colin Cross890ff552017-11-30 20:13:19 -08001591 "foo/res/res/values/strings.xml": nil,
1592 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -08001593 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -08001594 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -08001595 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
1596 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -08001597 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -08001598 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
1599 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
1600 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +00001601 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -08001602 }
1603
1604 bp := `
1605 android_app {
1606 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001607 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -08001608 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +00001609 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -08001610 }
1611
1612 android_app {
1613 name: "bar",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001614 sdk_version: "current",
Colin Cross890ff552017-11-30 20:13:19 -08001615 resource_dirs: ["bar/res"],
1616 }
Colin Cross6ed7dea2019-01-31 14:44:30 -08001617
1618 android_library {
1619 name: "lib",
Jeongik Cha75b83b02019-11-01 15:28:00 +09001620 sdk_version: "current",
Colin Cross6ed7dea2019-01-31 14:44:30 -08001621 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -08001622 static_libs: ["lib2"],
1623 }
1624
1625 android_library {
1626 name: "lib2",
Jeongik Cha75b83b02019-11-01 15:28:00 +09001627 sdk_version: "current",
Colin Crossbec85302019-02-13 13:15:46 -08001628 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -08001629 }
Anton Hansson53c88442019-03-18 15:53:16 +00001630
1631 // This library has the same resources as lib (should not lead to dupe RROs)
1632 android_library {
1633 name: "lib3",
Jeongik Cha75b83b02019-11-01 15:28:00 +09001634 sdk_version: "current",
Anton Hansson53c88442019-03-18 15:53:16 +00001635 resource_dirs: ["lib/res"]
1636 }
Colin Cross890ff552017-11-30 20:13:19 -08001637 `
1638
Colin Cross5c4791c2019-02-01 11:44:44 -08001639 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -08001640 t.Run(testCase.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001641 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001642 result := android.GroupFixturePreparers(
1643 PrepareForTestWithJavaDefaultModules,
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001644 fs.AddToFixture(),
1645 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1646 variables.DeviceResourceOverlays = deviceResourceOverlays
1647 variables.ProductResourceOverlays = productResourceOverlays
1648 if testCase.enforceRROTargets != nil {
1649 variables.EnforceRROTargets = testCase.enforceRROTargets
1650 }
1651 if testCase.enforceRROExcludedOverlays != nil {
1652 variables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
1653 }
1654 }),
1655 ).RunTestWithBp(t, bp)
Colin Cross890ff552017-11-30 20:13:19 -08001656
Colin Crossbec85302019-02-13 13:15:46 -08001657 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
1658 for _, o := range list {
1659 res := module.MaybeOutput(o)
1660 if res.Rule != nil {
Colin Crossc4441622024-09-18 14:55:49 -07001661 // If the overlay is compiled as part of this moduleAndVariant (i.e. a .arsc.flat file),
Colin Crossbec85302019-02-13 13:15:46 -08001662 // verify the inputs to the .arsc.flat rule.
1663 files = append(files, res.Inputs.Strings()...)
1664 } else {
Colin Crossc4441622024-09-18 14:55:49 -07001665 // Otherwise, verify the full path to the output of the other moduleAndVariant
Colin Crossbec85302019-02-13 13:15:46 -08001666 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +00001667 }
Colin Cross890ff552017-11-30 20:13:19 -08001668 }
Colin Crossbec85302019-02-13 13:15:46 -08001669 return files
Colin Cross890ff552017-11-30 20:13:19 -08001670 }
1671
Colin Crossc4441622024-09-18 14:55:49 -07001672 getResources := func(moduleName, variantName string) (resourceFiles, overlayFiles, rroDirs []string) {
Colin Cross90607e92025-02-11 14:58:07 -08001673 module := result.ModuleForTests(t, moduleName, variantName)
Colin Crossbec85302019-02-13 13:15:46 -08001674 resourceList := module.MaybeOutput("aapt2/res.list")
1675 if resourceList.Rule != nil {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001676 resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs))
Anton Hansson0375a4f2019-01-24 14:39:19 +00001677 }
Colin Crossbec85302019-02-13 13:15:46 -08001678 overlayList := module.MaybeOutput("aapt2/overlay.list")
1679 if overlayList.Rule != nil {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001680 overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs))
Colin Crossbec85302019-02-13 13:15:46 -08001681 }
1682
Colin Crossab8d1382023-07-14 17:23:41 +00001683 for _, d := range module.Module().(AndroidLibraryDependency).RRODirsDepSet().ToList() {
Anton Hansson53c88442019-03-18 15:53:16 +00001684 var prefix string
1685 if d.overlayType == device {
1686 prefix = "device:"
1687 } else if d.overlayType == product {
1688 prefix = "product:"
1689 } else {
1690 t.Fatalf("Unexpected overlayType %d", d.overlayType)
1691 }
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00001692 rroDirs = append(rroDirs, prefix+android.PathRelativeToTop(d.path))
Anton Hansson53c88442019-03-18 15:53:16 +00001693 }
Colin Crossbec85302019-02-13 13:15:46 -08001694
1695 return resourceFiles, overlayFiles, rroDirs
1696 }
1697
Colin Crossc4441622024-09-18 14:55:49 -07001698 modules := []moduleAndVariant{
1699 {"foo", "android_common"},
1700 {"foo", "android_common_rro"},
1701 {"bar", "android_common"},
1702 {"bar", "android_common_rro"},
1703 {"lib", "android_common"},
1704 {"lib", "android_common_rro"},
1705 {"lib2", "android_common"},
1706 {"lib2", "android_common_rro"},
1707 }
1708 for _, moduleAndVariant := range modules {
1709 if _, exists := testCase.resourceFiles[moduleAndVariant]; !exists {
1710 continue
1711 }
1712 resourceFiles, overlayFiles, rroDirs := getResources(moduleAndVariant.module, moduleAndVariant.variant)
Colin Crossbec85302019-02-13 13:15:46 -08001713
Colin Crossc4441622024-09-18 14:55:49 -07001714 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[moduleAndVariant]) {
Colin Crossbec85302019-02-13 13:15:46 -08001715 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
Colin Crossc4441622024-09-18 14:55:49 -07001716 moduleAndVariant, testCase.resourceFiles[moduleAndVariant], resourceFiles)
Colin Crossbec85302019-02-13 13:15:46 -08001717 }
Colin Crossc4441622024-09-18 14:55:49 -07001718 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[moduleAndVariant]) {
Colin Crossbec85302019-02-13 13:15:46 -08001719 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
Colin Crossc4441622024-09-18 14:55:49 -07001720 moduleAndVariant, testCase.overlayFiles[moduleAndVariant], overlayFiles)
Colin Crossbec85302019-02-13 13:15:46 -08001721 }
Colin Crossc4441622024-09-18 14:55:49 -07001722 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[moduleAndVariant]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +00001723 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossc4441622024-09-18 14:55:49 -07001724 moduleAndVariant, testCase.rroDirs[moduleAndVariant], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +00001725 }
Colin Cross890ff552017-11-30 20:13:19 -08001726 }
Colin Cross890ff552017-11-30 20:13:19 -08001727 })
1728 }
1729}
Colin Crossd09b0b62018-04-18 11:06:47 -07001730
Paul Duffincdb88a92021-03-14 00:36:50 +00001731func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) {
Colin Cross90607e92025-02-11 14:58:07 -08001732 foo := result.ModuleForTests(t, "foo", "android_common")
Jeongik Cha219141c2020-08-06 23:00:37 +09001733 link := foo.Output("package-res.apk")
1734 linkFlags := strings.Split(link.Args["flags"], " ")
1735 min := android.IndexList("--min-sdk-version", linkFlags)
1736 target := android.IndexList("--target-sdk-version", linkFlags)
1737
1738 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
1739 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
1740 }
1741
1742 gotMinSdkVersion := linkFlags[min+1]
1743 gotTargetSdkVersion := linkFlags[target+1]
1744
Paul Duffincdb88a92021-03-14 00:36:50 +00001745 android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion)
Jeongik Cha219141c2020-08-06 23:00:37 +09001746
Paul Duffincdb88a92021-03-14 00:36:50 +00001747 android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion)
Jeongik Cha219141c2020-08-06 23:00:37 +09001748}
1749
Colin Crossd09b0b62018-04-18 11:06:47 -07001750func TestAppSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001751 t.Parallel()
Colin Crossd09b0b62018-04-18 11:06:47 -07001752 testCases := []struct {
1753 name string
1754 sdkVersion string
1755 platformSdkInt int
1756 platformSdkCodename string
1757 platformSdkFinal bool
Spandan Dasffb31af2023-03-01 19:46:18 +00001758 minSdkVersionBp string
Colin Crossd09b0b62018-04-18 11:06:47 -07001759 expectedMinSdkVersion string
Jeongik Cha538c0d02019-07-11 15:54:27 +09001760 platformApis bool
Dan Albert4f378d72020-07-23 17:32:15 -07001761 activeCodenames []string
Colin Crossd09b0b62018-04-18 11:06:47 -07001762 }{
1763 {
1764 name: "current final SDK",
1765 sdkVersion: "current",
1766 platformSdkInt: 27,
1767 platformSdkCodename: "REL",
1768 platformSdkFinal: true,
1769 expectedMinSdkVersion: "27",
1770 },
1771 {
1772 name: "current non-final SDK",
1773 sdkVersion: "current",
1774 platformSdkInt: 27,
1775 platformSdkCodename: "OMR1",
1776 platformSdkFinal: false,
1777 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001778 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001779 },
1780 {
1781 name: "default final SDK",
1782 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001783 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001784 platformSdkInt: 27,
1785 platformSdkCodename: "REL",
1786 platformSdkFinal: true,
1787 expectedMinSdkVersion: "27",
1788 },
1789 {
1790 name: "default non-final SDK",
1791 sdkVersion: "",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001792 platformApis: true,
Colin Crossd09b0b62018-04-18 11:06:47 -07001793 platformSdkInt: 27,
1794 platformSdkCodename: "OMR1",
1795 platformSdkFinal: false,
1796 expectedMinSdkVersion: "OMR1",
Dan Albert4f378d72020-07-23 17:32:15 -07001797 activeCodenames: []string{"OMR1"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001798 },
1799 {
1800 name: "14",
1801 sdkVersion: "14",
1802 expectedMinSdkVersion: "14",
Dan Albert4f378d72020-07-23 17:32:15 -07001803 platformSdkCodename: "S",
1804 activeCodenames: []string{"S"},
Colin Crossd09b0b62018-04-18 11:06:47 -07001805 },
Spandan Dasffb31af2023-03-01 19:46:18 +00001806 {
1807 name: "two active SDKs",
1808 sdkVersion: "module_current",
1809 minSdkVersionBp: "UpsideDownCake",
1810 expectedMinSdkVersion: "UpsideDownCake", // And not VanillaIceCream
1811 platformSdkCodename: "VanillaIceCream",
1812 activeCodenames: []string{"UpsideDownCake", "VanillaIceCream"},
1813 },
Colin Crossd09b0b62018-04-18 11:06:47 -07001814 }
1815
1816 for _, moduleType := range []string{"android_app", "android_library"} {
1817 for _, test := range testCases {
1818 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001819 t.Parallel()
Jeongik Cha538c0d02019-07-11 15:54:27 +09001820 platformApiProp := ""
1821 if test.platformApis {
1822 platformApiProp = "platform_apis: true,"
1823 }
Spandan Dasffb31af2023-03-01 19:46:18 +00001824 minSdkVersionProp := ""
1825 if test.minSdkVersionBp != "" {
1826 minSdkVersionProp = fmt.Sprintf(` min_sdk_version: "%s",`, test.minSdkVersionBp)
1827 }
Colin Crossd09b0b62018-04-18 11:06:47 -07001828 bp := fmt.Sprintf(`%s {
1829 name: "foo",
1830 srcs: ["a.java"],
1831 sdk_version: "%s",
Jeongik Cha538c0d02019-07-11 15:54:27 +09001832 %s
Spandan Dasffb31af2023-03-01 19:46:18 +00001833 %s
1834 }`, moduleType, test.sdkVersion, platformApiProp, minSdkVersionProp)
Colin Crossd09b0b62018-04-18 11:06:47 -07001835
Paul Duffin71ae5942021-03-22 15:36:52 +00001836 result := android.GroupFixturePreparers(
1837 prepareForJavaTest,
Paul Duffincdb88a92021-03-14 00:36:50 +00001838 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1839 variables.Platform_sdk_version = &test.platformSdkInt
1840 variables.Platform_sdk_codename = &test.platformSdkCodename
1841 variables.Platform_version_active_codenames = test.activeCodenames
1842 variables.Platform_sdk_final = &test.platformSdkFinal
1843 }),
Paul Duffin2645a292021-03-13 02:36:00 +00001844 FixtureWithPrebuiltApis(map[string][]string{
1845 "14": {"foo"},
1846 }),
Paul Duffincdb88a92021-03-14 00:36:50 +00001847 ).RunTestWithBp(t, bp)
Colin Crossd09b0b62018-04-18 11:06:47 -07001848
Paul Duffincdb88a92021-03-14 00:36:50 +00001849 checkSdkVersion(t, result, test.expectedMinSdkVersion)
Colin Crossd09b0b62018-04-18 11:06:47 -07001850 })
1851 }
1852 }
1853}
Colin Crossa4f08812018-10-02 22:03:40 -07001854
Jeongik Cha219141c2020-08-06 23:00:37 +09001855func TestVendorAppSdkVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001856 t.Parallel()
Jeongik Cha219141c2020-08-06 23:00:37 +09001857 testCases := []struct {
1858 name string
1859 sdkVersion string
1860 platformSdkInt int
1861 platformSdkCodename string
1862 platformSdkFinal bool
1863 deviceCurrentApiLevelForVendorModules string
1864 expectedMinSdkVersion string
1865 }{
1866 {
1867 name: "current final SDK",
1868 sdkVersion: "current",
1869 platformSdkInt: 29,
1870 platformSdkCodename: "REL",
1871 platformSdkFinal: true,
1872 deviceCurrentApiLevelForVendorModules: "29",
1873 expectedMinSdkVersion: "29",
1874 },
1875 {
1876 name: "current final SDK",
1877 sdkVersion: "current",
1878 platformSdkInt: 29,
1879 platformSdkCodename: "REL",
1880 platformSdkFinal: true,
1881 deviceCurrentApiLevelForVendorModules: "28",
1882 expectedMinSdkVersion: "28",
1883 },
1884 {
1885 name: "current final SDK",
1886 sdkVersion: "current",
1887 platformSdkInt: 29,
1888 platformSdkCodename: "Q",
1889 platformSdkFinal: false,
Jeongik Cha219141c2020-08-06 23:00:37 +09001890 deviceCurrentApiLevelForVendorModules: "28",
1891 expectedMinSdkVersion: "28",
1892 },
1893 }
1894
1895 for _, moduleType := range []string{"android_app", "android_library"} {
1896 for _, sdkKind := range []string{"", "system_"} {
1897 for _, test := range testCases {
1898 t.Run(moduleType+" "+test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001899 t.Parallel()
Jeongik Cha219141c2020-08-06 23:00:37 +09001900 bp := fmt.Sprintf(`%s {
1901 name: "foo",
1902 srcs: ["a.java"],
1903 sdk_version: "%s%s",
1904 vendor: true,
1905 }`, moduleType, sdkKind, test.sdkVersion)
1906
Paul Duffin71ae5942021-03-22 15:36:52 +00001907 result := android.GroupFixturePreparers(
1908 prepareForJavaTest,
Paul Duffincdb88a92021-03-14 00:36:50 +00001909 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1910 variables.Platform_sdk_version = &test.platformSdkInt
1911 variables.Platform_sdk_codename = &test.platformSdkCodename
1912 variables.Platform_sdk_final = &test.platformSdkFinal
1913 variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
1914 variables.DeviceSystemSdkVersions = []string{"28", "29"}
1915 }),
Paul Duffin2645a292021-03-13 02:36:00 +00001916 FixtureWithPrebuiltApis(map[string][]string{
1917 "28": {"foo"},
1918 "29": {"foo"},
1919 "current": {"foo"},
1920 }),
Paul Duffincdb88a92021-03-14 00:36:50 +00001921 ).RunTestWithBp(t, bp)
1922
1923 checkSdkVersion(t, result, test.expectedMinSdkVersion)
Jeongik Cha219141c2020-08-06 23:00:37 +09001924 })
1925 }
1926 }
1927 }
1928}
1929
Paul Duffin50c217c2019-06-12 13:25:22 +01001930func TestJNIABI(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001931 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07001932 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01001933 cc_library {
1934 name: "libjni",
1935 system_shared_libs: [],
Colin Crossc511bc52020-04-07 16:50:32 +00001936 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01001937 stl: "none",
1938 }
1939
1940 android_test {
1941 name: "test",
1942 sdk_version: "core_platform",
1943 jni_libs: ["libjni"],
1944 }
1945
1946 android_test {
1947 name: "test_first",
1948 sdk_version: "core_platform",
1949 compile_multilib: "first",
1950 jni_libs: ["libjni"],
1951 }
1952
1953 android_test {
1954 name: "test_both",
1955 sdk_version: "core_platform",
1956 compile_multilib: "both",
1957 jni_libs: ["libjni"],
1958 }
1959
1960 android_test {
1961 name: "test_32",
1962 sdk_version: "core_platform",
1963 compile_multilib: "32",
1964 jni_libs: ["libjni"],
1965 }
1966
1967 android_test {
1968 name: "test_64",
1969 sdk_version: "core_platform",
1970 compile_multilib: "64",
1971 jni_libs: ["libjni"],
1972 }
1973 `)
1974
1975 testCases := []struct {
1976 name string
1977 abis []string
1978 }{
1979 {"test", []string{"arm64-v8a"}},
1980 {"test_first", []string{"arm64-v8a"}},
1981 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
1982 {"test_32", []string{"armeabi-v7a"}},
1983 {"test_64", []string{"arm64-v8a"}},
1984 }
1985
1986 for _, test := range testCases {
1987 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08001988 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08001989 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Crossb3168ba2023-07-26 16:14:56 -07001990 jniLibZip := app.Output("jnilibs.zip")
Paul Duffin50c217c2019-06-12 13:25:22 +01001991 var abis []string
1992 args := strings.Fields(jniLibZip.Args["jarArgs"])
1993 for i := 0; i < len(args); i++ {
1994 if args[i] == "-P" {
1995 abis = append(abis, filepath.Base(args[i+1]))
1996 i++
1997 }
1998 }
1999 if !reflect.DeepEqual(abis, test.abis) {
2000 t.Errorf("want abis %v, got %v", test.abis, abis)
2001 }
2002 })
2003 }
2004}
2005
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002006func TestAppSdkVersionByPartition(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002007 t.Parallel()
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002008 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
2009 android_app {
2010 name: "foo",
2011 srcs: ["a.java"],
2012 vendor: true,
2013 platform_apis: true,
2014 }
2015 `)
2016
2017 testJava(t, `
2018 android_app {
2019 name: "bar",
2020 srcs: ["b.java"],
2021 platform_apis: true,
2022 }
2023 `)
2024
2025 for _, enforce := range []bool{true, false} {
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002026 bp := `
2027 android_app {
2028 name: "foo",
2029 srcs: ["a.java"],
2030 product_specific: true,
2031 platform_apis: true,
2032 }
2033 `
Colin Cross98be1bb2019-12-13 20:41:13 -08002034
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002035 errorHandler := android.FixtureExpectsNoErrors
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002036 if enforce {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002037 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 +09002038 }
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002039
2040 android.GroupFixturePreparers(
2041 PrepareForTestWithJavaDefaultModules,
2042 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2043 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
2044 }),
2045 ).
2046 ExtendWithErrorHandler(errorHandler).
2047 RunTestWithBp(t, bp)
Jeongik Cha2cc570d2019-10-29 15:44:45 +09002048 }
2049}
2050
Paul Duffin50c217c2019-06-12 13:25:22 +01002051func TestJNIPackaging(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002052 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002053 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Paul Duffin50c217c2019-06-12 13:25:22 +01002054 cc_library {
2055 name: "libjni",
2056 system_shared_libs: [],
2057 stl: "none",
Colin Cross094cde42020-02-15 10:38:00 -08002058 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002059 }
2060
2061 android_app {
2062 name: "app",
2063 jni_libs: ["libjni"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002064 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002065 }
2066
2067 android_app {
2068 name: "app_noembed",
2069 jni_libs: ["libjni"],
2070 use_embedded_native_libs: false,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002071 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002072 }
2073
2074 android_app {
2075 name: "app_embed",
2076 jni_libs: ["libjni"],
2077 use_embedded_native_libs: true,
Jeongik Cha538c0d02019-07-11 15:54:27 +09002078 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002079 }
2080
2081 android_test {
2082 name: "test",
Colin Crossc511bc52020-04-07 16:50:32 +00002083 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002084 jni_libs: ["libjni"],
2085 }
2086
2087 android_test {
2088 name: "test_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00002089 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002090 jni_libs: ["libjni"],
2091 use_embedded_native_libs: false,
2092 }
2093
2094 android_test_helper_app {
2095 name: "test_helper",
Colin Crossc511bc52020-04-07 16:50:32 +00002096 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002097 jni_libs: ["libjni"],
2098 }
2099
2100 android_test_helper_app {
2101 name: "test_helper_noembed",
Colin Crossc511bc52020-04-07 16:50:32 +00002102 sdk_version: "current",
Paul Duffin50c217c2019-06-12 13:25:22 +01002103 jni_libs: ["libjni"],
2104 use_embedded_native_libs: false,
2105 }
2106 `)
2107
2108 testCases := []struct {
2109 name string
2110 packaged bool
2111 compressed bool
2112 }{
Jiyong Parkd044bb42024-05-15 02:09:54 +09002113 {"app", false, false},
2114 {"app_noembed", false, false},
Paul Duffin50c217c2019-06-12 13:25:22 +01002115 {"app_embed", true, false},
2116 {"test", true, false},
2117 {"test_noembed", true, true},
2118 {"test_helper", true, false},
2119 {"test_helper_noembed", true, true},
2120 }
2121
2122 for _, test := range testCases {
2123 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002124 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08002125 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Crossb3168ba2023-07-26 16:14:56 -07002126 jniLibZip := app.MaybeOutput("jnilibs.zip")
Paul Duffin50c217c2019-06-12 13:25:22 +01002127 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
2128 t.Errorf("expected jni packaged %v, got %v", w, g)
2129 }
2130
2131 if jniLibZip.Rule != nil {
2132 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
2133 t.Errorf("expected jni compressed %v, got %v", w, g)
2134 }
Colin Crossc511bc52020-04-07 16:50:32 +00002135
2136 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
2137 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
2138 }
Paul Duffin50c217c2019-06-12 13:25:22 +01002139 }
2140 })
2141 }
Colin Cross47fa9d32019-03-26 10:51:39 -07002142}
2143
Colin Cross3c007702020-05-08 11:20:24 -07002144func TestJNISDK(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002145 t.Parallel()
Colin Cross3c007702020-05-08 11:20:24 -07002146 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
2147 cc_library {
2148 name: "libjni",
2149 system_shared_libs: [],
2150 stl: "none",
2151 sdk_version: "current",
2152 }
2153
2154 android_test {
2155 name: "app_platform",
2156 jni_libs: ["libjni"],
2157 platform_apis: true,
2158 }
2159
2160 android_test {
2161 name: "app_sdk",
2162 jni_libs: ["libjni"],
2163 sdk_version: "current",
2164 }
2165
2166 android_test {
2167 name: "app_force_platform",
2168 jni_libs: ["libjni"],
2169 sdk_version: "current",
2170 jni_uses_platform_apis: true,
2171 }
2172
2173 android_test {
2174 name: "app_force_sdk",
2175 jni_libs: ["libjni"],
2176 platform_apis: true,
2177 jni_uses_sdk_apis: true,
2178 }
Colin Crossc2d24052020-05-13 11:05:02 -07002179
2180 cc_library {
2181 name: "libvendorjni",
2182 system_shared_libs: [],
2183 stl: "none",
2184 vendor: true,
2185 }
2186
2187 android_test {
2188 name: "app_vendor",
2189 jni_libs: ["libvendorjni"],
2190 sdk_version: "current",
2191 vendor: true,
2192 }
Colin Cross3c007702020-05-08 11:20:24 -07002193 `)
2194
2195 testCases := []struct {
Colin Crossc2d24052020-05-13 11:05:02 -07002196 name string
2197 sdkJNI bool
2198 vendorJNI bool
Colin Cross3c007702020-05-08 11:20:24 -07002199 }{
Colin Crossc2d24052020-05-13 11:05:02 -07002200 {name: "app_platform"},
2201 {name: "app_sdk", sdkJNI: true},
2202 {name: "app_force_platform"},
2203 {name: "app_force_sdk", sdkJNI: true},
2204 {name: "app_vendor", vendorJNI: true},
Colin Cross3c007702020-05-08 11:20:24 -07002205 }
2206
Colin Cross90607e92025-02-11 14:58:07 -08002207 platformJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_shared").
Colin Crossc2d24052020-05-13 11:05:02 -07002208 Output("libjni.so").Output.String()
Colin Cross90607e92025-02-11 14:58:07 -08002209 sdkJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_sdk_shared").
Colin Crossc2d24052020-05-13 11:05:02 -07002210 Output("libjni.so").Output.String()
Colin Cross90607e92025-02-11 14:58:07 -08002211 vendorJNI := ctx.ModuleForTests(t, "libvendorjni", "android_vendor_arm64_armv8-a_shared").
Colin Crossc2d24052020-05-13 11:05:02 -07002212 Output("libvendorjni.so").Output.String()
2213
Colin Cross3c007702020-05-08 11:20:24 -07002214 for _, test := range testCases {
2215 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002216 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08002217 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Cross3c007702020-05-08 11:20:24 -07002218
Colin Crossb3168ba2023-07-26 16:14:56 -07002219 jniLibZip := app.MaybeOutput("jnilibs.zip")
Colin Cross3c007702020-05-08 11:20:24 -07002220 if len(jniLibZip.Implicits) != 1 {
2221 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
2222 }
2223 gotJNI := jniLibZip.Implicits[0].String()
2224
2225 if test.sdkJNI {
2226 if gotJNI != sdkJNI {
2227 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI)
2228 }
Colin Crossc2d24052020-05-13 11:05:02 -07002229 } else if test.vendorJNI {
2230 if gotJNI != vendorJNI {
2231 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI)
2232 }
Colin Cross3c007702020-05-08 11:20:24 -07002233 } else {
2234 if gotJNI != platformJNI {
2235 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI)
2236 }
2237 }
2238 })
2239 }
2240
2241 t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002242 t.Parallel()
Colin Cross3c007702020-05-08 11:20:24 -07002243 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
2244 android_test {
2245 name: "app_platform",
2246 platform_apis: true,
2247 jni_uses_platform_apis: true,
2248 }
2249 `)
2250 })
2251
2252 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002253 t.Parallel()
Colin Cross3c007702020-05-08 11:20:24 -07002254 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
2255 android_test {
2256 name: "app_sdk",
2257 sdk_version: "current",
2258 jni_uses_sdk_apis: true,
2259 }
2260 `)
2261 })
2262
2263}
2264
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002265func TestCertificates(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002266 t.Parallel()
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002267 testCases := []struct {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002268 name string
2269 bp string
Colin Cross5caad2b2022-12-12 15:11:46 -08002270 allowMissingDependencies bool
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002271 certificateOverride string
2272 expectedCertSigningFlags string
2273 expectedCertificate string
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002274 }{
2275 {
2276 name: "default",
2277 bp: `
2278 android_app {
2279 name: "foo",
2280 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002281 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002282 }
2283 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002284 certificateOverride: "",
2285 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002286 expectedCertificate: "build/make/target/product/security/testkey",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002287 },
2288 {
2289 name: "module certificate property",
2290 bp: `
2291 android_app {
2292 name: "foo",
2293 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002294 certificate: ":new_certificate",
2295 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002296 }
2297
2298 android_app_certificate {
2299 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07002300 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002301 }
2302 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002303 certificateOverride: "",
2304 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002305 expectedCertificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002306 },
2307 {
2308 name: "path certificate property",
2309 bp: `
2310 android_app {
2311 name: "foo",
2312 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002313 certificate: "expiredkey",
2314 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002315 }
2316 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002317 certificateOverride: "",
2318 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002319 expectedCertificate: "build/make/target/product/security/expiredkey",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002320 },
2321 {
2322 name: "certificate overrides",
2323 bp: `
2324 android_app {
2325 name: "foo",
2326 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002327 certificate: "expiredkey",
2328 sdk_version: "current",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002329 }
2330
2331 android_app_certificate {
2332 name: "new_certificate",
Colin Cross3c007702020-05-08 11:20:24 -07002333 certificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002334 }
2335 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002336 certificateOverride: "foo:new_certificate",
2337 expectedCertSigningFlags: "",
Colin Cross5caad2b2022-12-12 15:11:46 -08002338 expectedCertificate: "cert/new_cert",
Liz Kammere2b27f42020-05-07 13:24:05 -07002339 },
2340 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002341 name: "certificate signing flags",
Liz Kammere2b27f42020-05-07 13:24:05 -07002342 bp: `
2343 android_app {
2344 name: "foo",
2345 srcs: ["a.java"],
2346 certificate: ":new_certificate",
2347 lineage: "lineage.bin",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002348 rotationMinSdkVersion: "32",
Liz Kammere2b27f42020-05-07 13:24:05 -07002349 sdk_version: "current",
2350 }
2351
2352 android_app_certificate {
2353 name: "new_certificate",
2354 certificate: "cert/new_cert",
2355 }
2356 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002357 certificateOverride: "",
2358 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
Colin Cross5caad2b2022-12-12 15:11:46 -08002359 expectedCertificate: "cert/new_cert",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002360 },
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002361 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002362 name: "cert signing flags from filegroup",
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002363 bp: `
2364 android_app {
2365 name: "foo",
2366 srcs: ["a.java"],
2367 certificate: ":new_certificate",
2368 lineage: ":lineage_bin",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002369 rotationMinSdkVersion: "32",
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002370 sdk_version: "current",
2371 }
2372
2373 android_app_certificate {
2374 name: "new_certificate",
2375 certificate: "cert/new_cert",
2376 }
2377
2378 filegroup {
2379 name: "lineage_bin",
2380 srcs: ["lineage.bin"],
2381 }
2382 `,
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002383 certificateOverride: "",
2384 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
Colin Cross5caad2b2022-12-12 15:11:46 -08002385 expectedCertificate: "cert/new_cert",
2386 },
2387 {
2388 name: "missing with AllowMissingDependencies",
2389 bp: `
2390 android_app {
2391 name: "foo",
2392 srcs: ["a.java"],
2393 certificate: ":new_certificate",
2394 sdk_version: "current",
2395 }
2396 `,
2397 expectedCertificate: "out/soong/.intermediates/foo/android_common/missing",
2398 allowMissingDependencies: true,
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -08002399 },
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002400 }
2401
2402 for _, test := range testCases {
2403 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002404 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002405 result := android.GroupFixturePreparers(
2406 PrepareForTestWithJavaDefaultModules,
2407 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2408 if test.certificateOverride != "" {
2409 variables.CertificateOverrides = []string{test.certificateOverride}
2410 }
Colin Cross5caad2b2022-12-12 15:11:46 -08002411 if test.allowMissingDependencies {
2412 variables.Allow_missing_dependencies = proptools.BoolPtr(true)
2413 }
2414 }),
2415 android.FixtureModifyContext(func(ctx *android.TestContext) {
2416 ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002417 }),
2418 ).RunTestWithBp(t, test.bp)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002419
Colin Cross90607e92025-02-11 14:58:07 -08002420 foo := result.ModuleForTests(t, "foo", "android_common")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002421
Colin Cross5caad2b2022-12-12 15:11:46 -08002422 certificate := foo.Module().(*AndroidApp).certificate
2423 android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key)
2424 // The sign_target_files_apks and check_target_files_signatures
2425 // tools require that certificates have a .x509.pem extension.
2426 android.AssertPathRelativeToTopEquals(t, "certificates pem", test.expectedCertificate+".x509.pem", certificate.Pem)
Liz Kammere2b27f42020-05-07 13:24:05 -07002427
Colin Cross5caad2b2022-12-12 15:11:46 -08002428 signapk := foo.Output("foo.apk")
2429 if signapk.Rule != android.ErrorRule {
2430 signCertificateFlags := signapk.Args["certificates"]
2431 expectedFlags := certificate.Pem.String() + " " + certificate.Key.String()
2432 android.AssertStringEquals(t, "certificates flags", expectedFlags, signCertificateFlags)
2433
2434 certSigningFlags := signapk.Args["flags"]
2435 android.AssertStringEquals(t, "cert signing flags", test.expectedCertSigningFlags, certSigningFlags)
2436 }
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08002437 })
2438 }
2439}
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002440
Songchun Fan688de9a2020-03-24 20:32:24 -07002441func TestRequestV4SigningFlag(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002442 t.Parallel()
Songchun Fan688de9a2020-03-24 20:32:24 -07002443 testCases := []struct {
2444 name string
2445 bp string
2446 expected string
2447 }{
2448 {
2449 name: "default",
2450 bp: `
2451 android_app {
2452 name: "foo",
2453 srcs: ["a.java"],
2454 sdk_version: "current",
2455 }
2456 `,
2457 expected: "",
2458 },
2459 {
2460 name: "default",
2461 bp: `
2462 android_app {
2463 name: "foo",
2464 srcs: ["a.java"],
2465 sdk_version: "current",
2466 v4_signature: false,
2467 }
2468 `,
2469 expected: "",
2470 },
2471 {
2472 name: "module certificate property",
2473 bp: `
2474 android_app {
2475 name: "foo",
2476 srcs: ["a.java"],
2477 sdk_version: "current",
2478 v4_signature: true,
2479 }
2480 `,
2481 expected: "--enable-v4",
2482 },
2483 }
2484
2485 for _, test := range testCases {
2486 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002487 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002488 result := android.GroupFixturePreparers(
2489 PrepareForTestWithJavaDefaultModules,
2490 ).RunTestWithBp(t, test.bp)
Songchun Fan688de9a2020-03-24 20:32:24 -07002491
Colin Cross90607e92025-02-11 14:58:07 -08002492 foo := result.ModuleForTests(t, "foo", "android_common")
Songchun Fan688de9a2020-03-24 20:32:24 -07002493
2494 signapk := foo.Output("foo.apk")
2495 signFlags := signapk.Args["flags"]
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002496 android.AssertStringEquals(t, "signing flags", test.expected, signFlags)
Songchun Fan688de9a2020-03-24 20:32:24 -07002497 })
2498 }
2499}
2500
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002501func TestPackageNameOverride(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002502 t.Parallel()
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002503 testCases := []struct {
2504 name string
2505 bp string
2506 packageNameOverride string
2507 expected []string
2508 }{
2509 {
2510 name: "default",
2511 bp: `
2512 android_app {
2513 name: "foo",
2514 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002515 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002516 }
2517 `,
2518 packageNameOverride: "",
2519 expected: []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002520 "out/soong/.intermediates/foo/android_common/foo.apk",
Cole Faust6b7075f2024-12-17 10:42:42 -08002521 "out/target/product/test_device/system/app/foo/foo.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002522 },
2523 },
2524 {
Jooyung Han29e2f6d2022-01-08 12:13:59 +09002525 name: "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002526 bp: `
2527 android_app {
2528 name: "foo",
2529 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002530 sdk_version: "current",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002531 }
2532 `,
2533 packageNameOverride: "foo:bar",
2534 expected: []string{
2535 // The package apk should be still be the original name for test dependencies.
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002536 "out/soong/.intermediates/foo/android_common/bar.apk",
Cole Faust6b7075f2024-12-17 10:42:42 -08002537 "out/target/product/test_device/system/app/bar/bar.apk",
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002538 },
2539 },
Jooyung Han29e2f6d2022-01-08 12:13:59 +09002540 {
2541 name: "overridden via stem",
2542 bp: `
2543 android_app {
2544 name: "foo",
2545 srcs: ["a.java"],
2546 sdk_version: "current",
2547 stem: "bar",
2548 }
2549 `,
2550 packageNameOverride: "",
2551 expected: []string{
2552 "out/soong/.intermediates/foo/android_common/bar.apk",
Cole Faust6b7075f2024-12-17 10:42:42 -08002553 "out/target/product/test_device/system/app/bar/bar.apk",
Jooyung Han29e2f6d2022-01-08 12:13:59 +09002554 },
2555 },
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002556 }
2557
2558 for _, test := range testCases {
2559 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002560 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002561 result := android.GroupFixturePreparers(
2562 PrepareForTestWithJavaDefaultModules,
2563 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2564 if test.packageNameOverride != "" {
2565 variables.PackageNameOverrides = []string{test.packageNameOverride}
2566 }
2567 }),
2568 ).RunTestWithBp(t, test.bp)
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002569
Colin Cross90607e92025-02-11 14:58:07 -08002570 foo := result.ModuleForTests(t, "foo", "android_common")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002571
Lukacs T. Berkifbaf7252021-08-19 09:36:42 +02002572 outSoongDir := result.Config.SoongOutDir()
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002573
2574 outputs := foo.AllOutputs()
2575 outputMap := make(map[string]bool)
2576 for _, o := range outputs {
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002577 outputMap[android.StringPathRelativeToTop(outSoongDir, o)] = true
Jaewoong Jung9d22a912019-01-23 16:27:47 -08002578 }
2579 for _, e := range test.expected {
2580 if _, exist := outputMap[e]; !exist {
2581 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
2582 }
2583 }
2584 })
2585 }
2586}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002587
2588func TestInstrumentationTargetOverridden(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002589 t.Parallel()
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002590 bp := `
2591 android_app {
2592 name: "foo",
2593 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002594 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002595 }
2596
2597 android_test {
2598 name: "bar",
2599 instrumentation_for: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09002600 sdk_version: "current",
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002601 }
2602 `
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002603
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002604 result := android.GroupFixturePreparers(
2605 PrepareForTestWithJavaDefaultModules,
2606 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2607 variables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
2608 }),
2609 ).RunTestWithBp(t, bp)
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002610
Colin Cross90607e92025-02-11 14:58:07 -08002611 bar := result.ModuleForTests(t, "bar", "android_common")
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08002612 res := bar.Output("package-res.apk")
2613 aapt2Flags := res.Args["flags"]
2614 e := "--rename-instrumentation-target-package org.dandroid.bp"
2615 if !strings.Contains(aapt2Flags, e) {
2616 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
2617 }
2618}
Jaewoong Jung525443a2019-02-28 15:35:54 -08002619
2620func TestOverrideAndroidApp(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002621 t.Parallel()
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002622 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
2623 t, `
Jaewoong Jung525443a2019-02-28 15:35:54 -08002624 android_app {
2625 name: "foo",
2626 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -07002627 certificate: "expiredkey",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002628 overrides: ["qux"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002629 sdk_version: "current",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002630 }
2631
2632 override_android_app {
2633 name: "bar",
2634 base: "foo",
2635 certificate: ":new_certificate",
Liz Kammere2b27f42020-05-07 13:24:05 -07002636 lineage: "lineage.bin",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002637 rotationMinSdkVersion: "32",
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08002638 logging_parent: "bah",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002639 }
2640
2641 android_app_certificate {
2642 name: "new_certificate",
2643 certificate: "cert/new_cert",
2644 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002645
2646 override_android_app {
2647 name: "baz",
2648 base: "foo",
2649 package_name: "org.dandroid.bp",
2650 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00002651
2652 override_android_app {
2653 name: "baz_no_rename_resources",
2654 base: "foo",
2655 package_name: "org.dandroid.bp",
2656 rename_resources_package: false,
2657 }
2658
2659 android_app {
2660 name: "foo_no_rename_resources",
2661 srcs: ["a.java"],
2662 certificate: "expiredkey",
2663 overrides: ["qux"],
2664 rename_resources_package: false,
2665 sdk_version: "current",
2666 }
2667
2668 override_android_app {
2669 name: "baz_base_no_rename_resources",
2670 base: "foo_no_rename_resources",
2671 package_name: "org.dandroid.bp",
2672 }
2673
2674 override_android_app {
2675 name: "baz_override_base_rename_resources",
2676 base: "foo_no_rename_resources",
2677 package_name: "org.dandroid.bp",
2678 rename_resources_package: true,
2679 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08002680 `)
2681
2682 expectedVariants := []struct {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002683 name string
2684 moduleName string
2685 variantName string
2686 apkName string
2687 apkPath string
2688 certFlag string
2689 certSigningFlags string
2690 overrides []string
2691 packageFlag string
2692 renameResources bool
2693 logging_parent string
Jaewoong Jung525443a2019-02-28 15:35:54 -08002694 }{
2695 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002696 name: "foo",
2697 moduleName: "foo",
2698 variantName: "android_common",
Cole Faust6b7075f2024-12-17 10:42:42 -08002699 apkPath: "out/target/product/test_device/system/app/foo/foo.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002700 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2701 certSigningFlags: "",
2702 overrides: []string{"qux"},
2703 packageFlag: "",
2704 renameResources: false,
2705 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002706 },
2707 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002708 name: "foo",
2709 moduleName: "bar",
2710 variantName: "android_common_bar",
Cole Faust6b7075f2024-12-17 10:42:42 -08002711 apkPath: "out/target/product/test_device/system/app/bar/bar.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002712 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
2713 certSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
2714 overrides: []string{"qux", "foo"},
2715 packageFlag: "",
2716 renameResources: false,
2717 logging_parent: "bah",
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002718 },
2719 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002720 name: "foo",
2721 moduleName: "baz",
2722 variantName: "android_common_baz",
Cole Faust6b7075f2024-12-17 10:42:42 -08002723 apkPath: "out/target/product/test_device/system/app/baz/baz.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002724 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2725 certSigningFlags: "",
2726 overrides: []string{"qux", "foo"},
2727 packageFlag: "org.dandroid.bp",
2728 renameResources: true,
2729 logging_parent: "",
Liz Kammer9f9fd022020-06-18 19:44:06 +00002730 },
2731 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002732 name: "foo",
2733 moduleName: "baz_no_rename_resources",
2734 variantName: "android_common_baz_no_rename_resources",
Cole Faust6b7075f2024-12-17 10:42:42 -08002735 apkPath: "out/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002736 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2737 certSigningFlags: "",
2738 overrides: []string{"qux", "foo"},
2739 packageFlag: "org.dandroid.bp",
2740 renameResources: false,
2741 logging_parent: "",
Liz Kammer9f9fd022020-06-18 19:44:06 +00002742 },
2743 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002744 name: "foo_no_rename_resources",
2745 moduleName: "baz_base_no_rename_resources",
2746 variantName: "android_common_baz_base_no_rename_resources",
Cole Faust6b7075f2024-12-17 10:42:42 -08002747 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 -04002748 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2749 certSigningFlags: "",
2750 overrides: []string{"qux", "foo_no_rename_resources"},
2751 packageFlag: "org.dandroid.bp",
2752 renameResources: false,
2753 logging_parent: "",
Liz Kammer9f9fd022020-06-18 19:44:06 +00002754 },
2755 {
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002756 name: "foo_no_rename_resources",
2757 moduleName: "baz_override_base_rename_resources",
2758 variantName: "android_common_baz_override_base_rename_resources",
Cole Faust6b7075f2024-12-17 10:42:42 -08002759 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 -04002760 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
2761 certSigningFlags: "",
2762 overrides: []string{"qux", "foo_no_rename_resources"},
2763 packageFlag: "org.dandroid.bp",
2764 renameResources: true,
2765 logging_parent: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08002766 },
2767 }
2768 for _, expected := range expectedVariants {
Colin Cross90607e92025-02-11 14:58:07 -08002769 variant := result.ModuleForTests(t, expected.name, expected.variantName)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002770
2771 // Check the final apk name
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002772 variant.Output(expected.apkPath)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002773
2774 // Check the certificate paths
Jaewoong Jung5a498812019-11-07 14:14:38 -08002775 signapk := variant.Output(expected.moduleName + ".apk")
Liz Kammere2b27f42020-05-07 13:24:05 -07002776 certFlag := signapk.Args["certificates"]
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002777 android.AssertStringEquals(t, "certificates flags", expected.certFlag, certFlag)
Liz Kammere2b27f42020-05-07 13:24:05 -07002778
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04002779 // Check the cert signing flags
2780 certSigningFlags := signapk.Args["flags"]
2781 android.AssertStringEquals(t, "cert signing flags", expected.certSigningFlags, certSigningFlags)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002782
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002783 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -08002784 mod := variant.Module().(*AndroidApp)
zhidoua2ce78f2022-02-17 02:33:12 +00002785 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002786
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08002787 // Test Overridable property: Logging_parent
2788 logging_parent := mod.aapt.LoggingParent
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00002789 android.AssertStringEquals(t, "overrides property value for logging parent", expected.logging_parent, logging_parent)
Baligh Uddin5b16dfb2020-02-11 17:27:19 -08002790
Liz Kammer1d5983b2020-05-19 19:15:37 +00002791 // Check the package renaming flag, if exists.
Jaewoong Jung6f373f62019-03-13 10:13:24 -07002792 res := variant.Output("package-res.apk")
2793 aapt2Flags := res.Args["flags"]
Liz Kammer9f9fd022020-06-18 19:44:06 +00002794 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
2795 expectedPackage := expected.packageFlag
2796 if !expected.renameResources {
2797 expectedPackage = ""
Liz Kammer1d5983b2020-05-19 19:15:37 +00002798 }
Liz Kammer9f9fd022020-06-18 19:44:06 +00002799 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
Jaewoong Jung525443a2019-02-28 15:35:54 -08002800 }
2801}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07002802
zhidoua2ce78f2022-02-17 02:33:12 +00002803func TestOverrideAndroidAppOverrides(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002804 t.Parallel()
zhidoua2ce78f2022-02-17 02:33:12 +00002805 ctx, _ := testJava(
2806 t, `
2807 android_app {
2808 name: "foo",
2809 srcs: ["a.java"],
2810 sdk_version: "current",
2811 overrides: ["qux"]
2812 }
2813
2814 android_app {
2815 name: "bar",
2816 srcs: ["b.java"],
2817 sdk_version: "current",
2818 overrides: ["foo"]
2819 }
2820
2821 override_android_app {
2822 name: "foo_override",
2823 base: "foo",
2824 overrides: ["bar"]
2825 }
2826 `)
2827
2828 expectedVariants := []struct {
2829 name string
2830 moduleName string
2831 variantName string
2832 overrides []string
2833 }{
2834 {
2835 name: "foo",
2836 moduleName: "foo",
2837 variantName: "android_common",
2838 overrides: []string{"qux"},
2839 },
2840 {
2841 name: "bar",
2842 moduleName: "bar",
2843 variantName: "android_common",
2844 overrides: []string{"foo"},
2845 },
2846 {
2847 name: "foo",
2848 moduleName: "foo_override",
2849 variantName: "android_common_foo_override",
2850 overrides: []string{"bar", "foo"},
2851 },
2852 }
2853 for _, expected := range expectedVariants {
Colin Cross90607e92025-02-11 14:58:07 -08002854 variant := ctx.ModuleForTests(t, expected.name, expected.variantName)
zhidoua2ce78f2022-02-17 02:33:12 +00002855
2856 // Check if the overrides field values are correctly aggregated.
2857 mod := variant.Module().(*AndroidApp)
2858 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
2859 }
2860}
2861
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002862func TestOverrideAndroidAppWithPrebuilt(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002863 t.Parallel()
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002864 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
2865 t, `
2866 android_app {
2867 name: "foo",
2868 srcs: ["a.java"],
2869 sdk_version: "current",
2870 }
2871
2872 override_android_app {
2873 name: "bar",
2874 base: "foo",
2875 }
2876
2877 android_app_import {
2878 name: "bar",
2879 prefer: true,
2880 apk: "bar.apk",
2881 presigned: true,
2882 }
2883 `)
2884
2885 // An app that has an override that also has a prebuilt should not be hidden.
Colin Cross90607e92025-02-11 14:58:07 -08002886 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002887 if foo.Module().IsHideFromMake() {
2888 t.Errorf("expected foo to have HideFromMake false")
2889 }
2890
2891 // An override that also has a prebuilt should be hidden.
Colin Cross90607e92025-02-11 14:58:07 -08002892 barOverride := result.ModuleForTests(t, "foo", "android_common_bar")
Colin Crossaaa0c1f2022-05-16 16:19:54 -07002893 if !barOverride.Module().IsHideFromMake() {
2894 t.Errorf("expected bar override variant of foo to have HideFromMake true")
2895 }
2896}
2897
Jooyung Han01d80d82022-01-08 12:16:32 +09002898func TestOverrideAndroidAppStem(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002899 t.Parallel()
Jooyung Han01d80d82022-01-08 12:16:32 +09002900 ctx, _ := testJava(t, `
2901 android_app {
2902 name: "foo",
2903 srcs: ["a.java"],
2904 sdk_version: "current",
2905 }
2906 override_android_app {
2907 name: "bar",
2908 base: "foo",
2909 }
2910 override_android_app {
2911 name: "baz",
2912 base: "foo",
2913 stem: "baz_stem",
2914 }
2915 android_app {
2916 name: "foo2",
2917 srcs: ["a.java"],
2918 sdk_version: "current",
2919 stem: "foo2_stem",
2920 }
2921 override_android_app {
2922 name: "bar2",
2923 base: "foo2",
2924 }
2925 override_android_app {
2926 name: "baz2",
2927 base: "foo2",
2928 stem: "baz2_stem",
2929 }
2930 `)
2931 for _, expected := range []struct {
2932 moduleName string
2933 variantName string
2934 apkPath string
2935 }{
2936 {
2937 moduleName: "foo",
2938 variantName: "android_common",
Cole Faust6b7075f2024-12-17 10:42:42 -08002939 apkPath: "out/target/product/test_device/system/app/foo/foo.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002940 },
2941 {
2942 moduleName: "foo",
2943 variantName: "android_common_bar",
Cole Faust6b7075f2024-12-17 10:42:42 -08002944 apkPath: "out/target/product/test_device/system/app/bar/bar.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002945 },
2946 {
2947 moduleName: "foo",
2948 variantName: "android_common_baz",
Cole Faust6b7075f2024-12-17 10:42:42 -08002949 apkPath: "out/target/product/test_device/system/app/baz_stem/baz_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002950 },
2951 {
2952 moduleName: "foo2",
2953 variantName: "android_common",
Cole Faust6b7075f2024-12-17 10:42:42 -08002954 apkPath: "out/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002955 },
2956 {
2957 moduleName: "foo2",
2958 variantName: "android_common_bar2",
2959 // Note that this may cause the duplicate output error.
Cole Faust6b7075f2024-12-17 10:42:42 -08002960 apkPath: "out/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002961 },
2962 {
2963 moduleName: "foo2",
2964 variantName: "android_common_baz2",
Cole Faust6b7075f2024-12-17 10:42:42 -08002965 apkPath: "out/target/product/test_device/system/app/baz2_stem/baz2_stem.apk",
Jooyung Han01d80d82022-01-08 12:16:32 +09002966 },
2967 } {
Colin Cross90607e92025-02-11 14:58:07 -08002968 variant := ctx.ModuleForTests(t, expected.moduleName, expected.variantName)
Jooyung Han01d80d82022-01-08 12:16:32 +09002969 variant.Output(expected.apkPath)
2970 }
2971}
2972
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002973func TestOverrideAndroidAppDependency(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08002974 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07002975 ctx, _ := testJava(t, `
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002976 android_app {
2977 name: "foo",
2978 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09002979 sdk_version: "current",
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07002980 }
2981
2982 override_android_app {
2983 name: "bar",
2984 base: "foo",
2985 package_name: "org.dandroid.bp",
2986 }
2987
2988 android_test {
2989 name: "baz",
2990 srcs: ["b.java"],
2991 instrumentation_for: "foo",
2992 }
2993
2994 android_test {
2995 name: "qux",
2996 srcs: ["b.java"],
2997 instrumentation_for: "bar",
2998 }
2999 `)
3000
3001 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
Colin Cross90607e92025-02-11 14:58:07 -08003002 javac := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003003 fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07003004 if !strings.Contains(javac.Args["classpath"], fooTurbine) {
3005 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
3006 }
3007
3008 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
Colin Cross90607e92025-02-11 14:58:07 -08003009 javac = ctx.ModuleForTests(t, "qux", "android_common").Rule("javac")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003010 barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07003011 if !strings.Contains(javac.Args["classpath"], barTurbine) {
3012 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
3013 }
3014}
3015
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003016func TestOverrideAndroidTest(t *testing.T) {
3017 ctx, _ := testJava(t, `
3018 android_app {
3019 name: "foo",
3020 srcs: ["a.java"],
3021 package_name: "com.android.foo",
3022 sdk_version: "current",
3023 }
3024
3025 override_android_app {
3026 name: "bar",
3027 base: "foo",
3028 package_name: "com.android.bar",
3029 }
3030
3031 android_test {
3032 name: "foo_test",
3033 srcs: ["b.java"],
3034 instrumentation_for: "foo",
3035 }
3036
3037 override_android_test {
3038 name: "bar_test",
3039 base: "foo_test",
3040 package_name: "com.android.bar.test",
3041 instrumentation_for: "bar",
3042 instrumentation_target_package: "com.android.bar",
3043 }
3044 `)
3045
3046 expectedVariants := []struct {
3047 moduleName string
3048 variantName string
3049 apkPath string
3050 overrides []string
3051 targetVariant string
3052 packageFlag string
3053 targetPackageFlag string
3054 }{
3055 {
3056 variantName: "android_common",
Jaewoong Jung326a9412019-11-21 10:41:00 -08003057 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003058 overrides: nil,
3059 targetVariant: "android_common",
3060 packageFlag: "",
3061 targetPackageFlag: "",
3062 },
3063 {
3064 variantName: "android_common_bar_test",
Jaewoong Jung326a9412019-11-21 10:41:00 -08003065 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003066 overrides: []string{"foo_test"},
3067 targetVariant: "android_common_bar",
3068 packageFlag: "com.android.bar.test",
3069 targetPackageFlag: "com.android.bar",
3070 },
3071 }
3072 for _, expected := range expectedVariants {
Colin Cross90607e92025-02-11 14:58:07 -08003073 variant := ctx.ModuleForTests(t, "foo_test", expected.variantName)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003074
3075 // Check the final apk name
Cole Faust6b7075f2024-12-17 10:42:42 -08003076 variant.Output("out" + expected.apkPath)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003077
3078 // Check if the overrides field values are correctly aggregated.
3079 mod := variant.Module().(*AndroidTest)
zhidoua2ce78f2022-02-17 02:33:12 +00003080 if !reflect.DeepEqual(expected.overrides, mod.overridableAppProperties.Overrides) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003081 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
zhidoua2ce78f2022-02-17 02:33:12 +00003082 expected.overrides, mod.overridableAppProperties.Overrides)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003083 }
3084
3085 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
Paul Duffina71a67a2021-03-29 00:42:57 +01003086 javac := variant.Rule("javac")
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003087 turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003088 if !strings.Contains(javac.Args["classpath"], turbine) {
3089 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
3090 }
3091
3092 // Check aapt2 flags.
3093 res := variant.Output("package-res.apk")
3094 aapt2Flags := res.Args["flags"]
3095 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
Liz Kammer9f9fd022020-06-18 19:44:06 +00003096 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003097 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
3098 }
3099}
3100
Jaewoong Jung39982342020-01-14 10:27:18 -08003101func TestAndroidTest_FixTestConfig(t *testing.T) {
3102 ctx, _ := testJava(t, `
3103 android_app {
3104 name: "foo",
3105 srcs: ["a.java"],
3106 package_name: "com.android.foo",
3107 sdk_version: "current",
3108 }
3109
3110 android_test {
3111 name: "foo_test",
3112 srcs: ["b.java"],
3113 instrumentation_for: "foo",
3114 }
3115
3116 android_test {
3117 name: "bar_test",
3118 srcs: ["b.java"],
3119 package_name: "com.android.bar.test",
3120 instrumentation_for: "foo",
Seth Moorec6f4b532023-02-02 13:22:26 -08003121 mainline_package_name: "com.android.bar",
Jaewoong Jung39982342020-01-14 10:27:18 -08003122 }
3123
3124 override_android_test {
3125 name: "baz_test",
3126 base: "foo_test",
3127 package_name: "com.android.baz.test",
Seth Moorec6f4b532023-02-02 13:22:26 -08003128 mainline_package_name: "com.android.baz",
Jaewoong Jung39982342020-01-14 10:27:18 -08003129 }
3130 `)
3131
3132 testCases := []struct {
3133 moduleName string
3134 variantName string
3135 expectedFlags []string
3136 }{
3137 {
3138 moduleName: "foo_test",
3139 variantName: "android_common",
3140 },
3141 {
3142 moduleName: "bar_test",
3143 variantName: "android_common",
3144 expectedFlags: []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003145 "--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
Jaewoong Jung39982342020-01-14 10:27:18 -08003146 "--package-name com.android.bar.test",
Seth Moorec6f4b532023-02-02 13:22:26 -08003147 "--mainline-package-name com.android.bar",
Jaewoong Jung39982342020-01-14 10:27:18 -08003148 },
3149 },
3150 {
3151 moduleName: "foo_test",
3152 variantName: "android_common_baz_test",
3153 expectedFlags: []string{
Paul Duffinfb0fe9f2021-03-22 17:31:52 +00003154 "--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
Jaewoong Jung39982342020-01-14 10:27:18 -08003155 "--package-name com.android.baz.test",
3156 "--test-file-name baz_test.apk",
Seth Moorec6f4b532023-02-02 13:22:26 -08003157 "out/soong/.intermediates/foo_test/android_common_baz_test/test_config_fixer/AndroidTest.xml",
3158 "--mainline-package-name com.android.baz",
Jaewoong Jung39982342020-01-14 10:27:18 -08003159 },
3160 },
3161 }
3162
3163 for _, test := range testCases {
Colin Cross90607e92025-02-11 14:58:07 -08003164 variant := ctx.ModuleForTests(t, test.moduleName, test.variantName)
Paul Duffina71a67a2021-03-29 00:42:57 +01003165 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
Jaewoong Jung39982342020-01-14 10:27:18 -08003166
3167 if len(test.expectedFlags) > 0 {
3168 if params.Rule == nil {
3169 t.Errorf("test_config_fixer was expected to run, but didn't")
3170 } else {
3171 for _, flag := range test.expectedFlags {
3172 if !strings.Contains(params.RuleParams.Command, flag) {
3173 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
3174 }
3175 }
3176 }
3177 } else {
3178 if params.Rule != nil {
3179 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
3180 }
3181 }
Jaewoong Jung39982342020-01-14 10:27:18 -08003182 }
3183}
3184
Paul Duffin53a70a42022-01-11 14:35:55 +00003185func TestInstrumentationTargetPrebuilt(t *testing.T) {
3186 bp := `
3187 android_app_import {
3188 name: "foo",
3189 apk: "foo.apk",
3190 presigned: true,
3191 }
3192
3193 android_test {
3194 name: "bar",
3195 srcs: ["a.java"],
3196 instrumentation_for: "foo",
3197 sdk_version: "current",
3198 }
3199 `
3200
3201 android.GroupFixturePreparers(
3202 PrepareForTestWithJavaDefaultModules,
3203 ).ExtendWithErrorHandler(
3204 android.FixtureExpectsAtLeastOneErrorMatchingPattern(
3205 "instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property")).
3206 RunTestWithBp(t, bp)
3207}
3208
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003209func TestStl(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003210 t.Parallel()
Jaewoong Jungf9a04432019-07-17 11:15:09 -07003211 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003212 cc_library {
3213 name: "libjni",
Peter Collingbournead84f972019-12-17 16:46:18 -08003214 sdk_version: "current",
3215 stl: "c++_shared",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003216 }
3217
3218 android_test {
3219 name: "stl",
3220 jni_libs: ["libjni"],
3221 compile_multilib: "both",
3222 sdk_version: "current",
3223 stl: "c++_shared",
3224 }
3225
3226 android_test {
3227 name: "system",
3228 jni_libs: ["libjni"],
3229 compile_multilib: "both",
3230 sdk_version: "current",
3231 }
3232 `)
3233
3234 testCases := []struct {
3235 name string
3236 jnis []string
3237 }{
3238 {"stl",
3239 []string{
3240 "libjni.so",
Jaewoong Jung710756a2019-06-04 11:53:47 -07003241 "libc++_shared.so",
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003242 },
3243 },
3244 {"system",
3245 []string{
3246 "libjni.so",
3247 },
3248 },
3249 }
3250
3251 for _, test := range testCases {
3252 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003253 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08003254 app := ctx.ModuleForTests(t, test.name, "android_common")
Colin Crossb3168ba2023-07-26 16:14:56 -07003255 jniLibZip := app.Output("jnilibs.zip")
Jaewoong Jungbc625cd2019-05-06 15:48:44 -07003256 var jnis []string
3257 args := strings.Fields(jniLibZip.Args["jarArgs"])
3258 for i := 0; i < len(args); i++ {
3259 if args[i] == "-f" {
3260 jnis = append(jnis, args[i+1])
3261 i += 1
3262 }
3263 }
3264 jnisJoined := strings.Join(jnis, " ")
3265 for _, jni := range test.jnis {
3266 if !strings.Contains(jnisJoined, jni) {
3267 t.Errorf("missing jni %q in %q", jni, jnis)
3268 }
3269 }
3270 })
3271 }
3272}
Colin Cross50ddcc42019-05-16 12:28:22 -07003273
3274func TestUsesLibraries(t *testing.T) {
3275 bp := `
3276 java_sdk_library {
3277 name: "foo",
3278 srcs: ["a.java"],
3279 api_packages: ["foo"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003280 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07003281 }
3282
3283 java_sdk_library {
Paul Duffin859fe962020-05-15 10:20:31 +01003284 name: "qux",
3285 srcs: ["a.java"],
3286 api_packages: ["qux"],
3287 sdk_version: "current",
3288 }
3289
3290 java_sdk_library {
3291 name: "quuz",
3292 srcs: ["a.java"],
3293 api_packages: ["quuz"],
3294 sdk_version: "current",
3295 }
3296
3297 java_sdk_library {
Ulya Trafimovich65b03192020-12-03 16:50:22 +00003298 name: "fred",
3299 srcs: ["a.java"],
3300 api_packages: ["fred"],
3301 sdk_version: "current",
3302 }
3303
3304 java_sdk_library {
Colin Cross50ddcc42019-05-16 12:28:22 -07003305 name: "bar",
3306 srcs: ["a.java"],
3307 api_packages: ["bar"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003308 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07003309 }
3310
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01003311 java_sdk_library {
3312 name: "runtime-library",
3313 srcs: ["a.java"],
3314 sdk_version: "current",
3315 }
3316
3317 java_library {
3318 name: "static-runtime-helper",
3319 srcs: ["a.java"],
Jihoon Kang28c96572024-09-11 23:44:44 +00003320 libs: ["runtime-library.impl"],
Ulya Trafimovich4b6d4c12020-08-19 14:58:01 +01003321 sdk_version: "current",
3322 }
3323
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003324 java_library {
3325 name: "runtime-required-x",
3326 srcs: ["a.java"],
3327 installable: true,
3328 sdk_version: "current",
3329 }
3330
3331 java_library {
3332 name: "runtime-optional-x",
3333 srcs: ["a.java"],
3334 installable: true,
3335 sdk_version: "current",
3336 }
3337
3338 android_library {
3339 name: "static-x",
3340 uses_libs: ["runtime-required-x"],
3341 optional_uses_libs: ["runtime-optional-x"],
3342 sdk_version: "current",
3343 }
3344
3345 java_library {
3346 name: "runtime-required-y",
3347 srcs: ["a.java"],
3348 installable: true,
3349 sdk_version: "current",
3350 }
3351
3352 java_library {
3353 name: "runtime-optional-y",
3354 srcs: ["a.java"],
3355 installable: true,
3356 sdk_version: "current",
3357 }
3358
3359 java_library {
3360 name: "static-y",
3361 srcs: ["a.java"],
3362 uses_libs: ["runtime-required-y"],
Jiakai Zhang36937082024-04-15 11:15:50 +00003363 optional_uses_libs: [
3364 "runtime-optional-y",
3365 "missing-lib-a",
3366 ],
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003367 sdk_version: "current",
3368 }
3369
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003370 // A library that has to use "provides_uses_lib", because:
3371 // - it is not an SDK library
3372 // - its library name is different from its module name
3373 java_library {
3374 name: "non-sdk-lib",
3375 provides_uses_lib: "com.non.sdk.lib",
3376 installable: true,
3377 srcs: ["a.java"],
3378 }
3379
Colin Cross50ddcc42019-05-16 12:28:22 -07003380 android_app {
3381 name: "app",
3382 srcs: ["a.java"],
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003383 libs: [
Jihoon Kang28c96572024-09-11 23:44:44 +00003384 "qux.impl",
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003385 "quuz.stubs"
3386 ],
Ulya Trafimovich65b03192020-12-03 16:50:22 +00003387 static_libs: [
3388 "static-runtime-helper",
3389 // statically linked component libraries should not pull their SDK libraries,
3390 // so "fred" should not be added to class loader context
3391 "fred.stubs",
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003392 "static-x",
3393 "static-y",
Ulya Trafimovich65b03192020-12-03 16:50:22 +00003394 ],
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003395 uses_libs: [
3396 "foo",
3397 "non-sdk-lib"
3398 ],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003399 sdk_version: "current",
Colin Cross50ddcc42019-05-16 12:28:22 -07003400 optional_uses_libs: [
3401 "bar",
Jiakai Zhangf98da192024-04-15 11:15:41 +00003402 "missing-lib-b",
Colin Cross50ddcc42019-05-16 12:28:22 -07003403 ],
3404 }
3405
3406 android_app_import {
3407 name: "prebuilt",
3408 apk: "prebuilts/apk/app.apk",
3409 certificate: "platform",
Ulya Trafimovich861a8962021-02-26 14:49:07 +00003410 uses_libs: [
3411 "foo",
3412 "non-sdk-lib",
3413 "android.test.runner"
3414 ],
Colin Cross50ddcc42019-05-16 12:28:22 -07003415 optional_uses_libs: [
3416 "bar",
Jiakai Zhangf98da192024-04-15 11:15:41 +00003417 "missing-lib-b",
Colin Cross50ddcc42019-05-16 12:28:22 -07003418 ],
3419 }
3420 `
3421
Paul Duffin71ae5942021-03-22 15:36:52 +00003422 result := android.GroupFixturePreparers(
3423 prepareForJavaTest,
Paul Duffin2645a292021-03-13 02:36:00 +00003424 PrepareForTestWithJavaSdkLibraryFiles,
3425 FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"),
Jiakai Zhang48203e32023-06-02 23:42:21 +01003426 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3427 variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"}
3428 }),
Paul Duffind234b412021-03-12 23:04:46 +00003429 ).RunTestWithBp(t, bp)
Colin Cross50ddcc42019-05-16 12:28:22 -07003430
Colin Cross90607e92025-02-11 14:58:07 -08003431 app := result.ModuleForTests(t, "app", "android_common")
3432 prebuilt := result.ModuleForTests(t, "prebuilt", "android_common")
Colin Cross50ddcc42019-05-16 12:28:22 -07003433
Paul Duffin859fe962020-05-15 10:20:31 +01003434 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01003435 // These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
3436 // propagated from dependencies.
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003437 actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
Jiyong Parkd044bb42024-05-15 02:09:54 +09003438 expectManifestFixerArgs := `--extract-native-libs=true ` +
3439 `--uses-library foo ` +
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01003440 `--uses-library com.non.sdk.lib ` +
Jiakai Zhangf98da192024-04-15 11:15:41 +00003441 `--uses-library qux ` +
3442 `--uses-library quuz ` +
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01003443 `--uses-library runtime-library ` +
3444 `--uses-library runtime-required-x ` +
3445 `--uses-library runtime-required-y ` +
3446 `--optional-uses-library bar ` +
3447 `--optional-uses-library runtime-optional-x ` +
3448 `--optional-uses-library runtime-optional-y`
Gurpreet Singh75d65f32022-01-24 17:44:05 +00003449 android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs)
Paul Duffin859fe962020-05-15 10:20:31 +01003450
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003451 // Test that all libraries are verified (library order matters).
3452 verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command
3453 verifyArgs := `--uses-library foo ` +
Ulya Trafimovicheea486a2021-02-26 11:38:21 +00003454 `--uses-library com.non.sdk.lib ` +
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003455 `--uses-library qux ` +
3456 `--uses-library quuz ` +
3457 `--uses-library runtime-library ` +
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003458 `--uses-library runtime-required-x ` +
3459 `--uses-library runtime-required-y ` +
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003460 `--optional-uses-library bar ` +
Ulya Trafimoviche4432872021-08-18 16:57:11 +01003461 `--optional-uses-library runtime-optional-x ` +
Jiakai Zhangf98da192024-04-15 11:15:41 +00003462 `--optional-uses-library runtime-optional-y ` +
Jiakai Zhang36937082024-04-15 11:15:50 +00003463 `--missing-optional-uses-library missing-lib-b ` +
3464 `--missing-optional-uses-library missing-lib-a`
Paul Duffind234b412021-03-12 23:04:46 +00003465 android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
Colin Cross50ddcc42019-05-16 12:28:22 -07003466
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003467 // Test that all libraries are verified for an APK (library order matters).
3468 verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00003469 verifyApkArgs := `--uses-library foo ` +
3470 `--uses-library com.non.sdk.lib ` +
3471 `--uses-library android.test.runner ` +
3472 `--optional-uses-library bar ` +
Jiakai Zhangf98da192024-04-15 11:15:41 +00003473 `--missing-optional-uses-library missing-lib-b `
Paul Duffind234b412021-03-12 23:04:46 +00003474 android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
Colin Cross50ddcc42019-05-16 12:28:22 -07003475
Jiakai Zhanga4496782023-05-17 16:57:30 +01003476 // Test that necessary args are passed for constructing CLC in Ninja phase.
Ulya Trafimovich2eaf5c52021-02-26 12:05:11 +00003477 cmd := app.Rule("dexpreopt").RuleParams.Command
Jiakai Zhanga4496782023-05-17 16:57:30 +01003478 android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=")
3479 android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd,
Spandan Das2069c3f2023-12-06 19:40:24 +00003480 "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt")
Colin Cross50ddcc42019-05-16 12:28:22 -07003481}
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003482
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003483func TestDexpreoptBcp(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003484 t.Parallel()
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003485 bp := `
3486 java_sdk_library {
3487 name: "foo",
3488 srcs: ["a.java"],
3489 api_packages: ["foo"],
3490 sdk_version: "current",
3491 }
3492
3493 java_sdk_library {
3494 name: "bar",
3495 srcs: ["a.java"],
3496 api_packages: ["bar"],
3497 permitted_packages: ["bar"],
3498 sdk_version: "current",
3499 }
3500
3501 android_app {
3502 name: "app",
3503 srcs: ["a.java"],
3504 sdk_version: "current",
3505 }
3506 `
3507
3508 testCases := []struct {
3509 name string
3510 with bool
3511 expect string
3512 }{
3513 {
3514 name: "with updatable bcp",
3515 with: true,
3516 expect: "/system/framework/foo.jar:/system/framework/bar.jar",
3517 },
3518 {
3519 name: "without updatable bcp",
3520 with: false,
3521 expect: "/system/framework/foo.jar",
3522 },
3523 }
3524
3525 for _, test := range testCases {
3526 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003527 t.Parallel()
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003528 result := android.GroupFixturePreparers(
3529 prepareForJavaTest,
3530 PrepareForTestWithJavaSdkLibraryFiles,
3531 FixtureWithLastReleaseApis("runtime-library", "foo", "bar"),
3532 dexpreopt.FixtureSetBootJars("platform:foo"),
satayevd604b212021-07-21 14:23:52 +01003533 dexpreopt.FixtureSetApexBootJars("platform:bar"),
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003534 dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with),
3535 ).RunTestWithBp(t, bp)
3536
Colin Cross90607e92025-02-11 14:58:07 -08003537 app := result.ModuleForTests(t, "app", "android_common")
Ulya Trafimovich9023b022021-03-22 16:02:28 +00003538 cmd := app.Rule("dexpreopt").RuleParams.Command
3539 bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters
3540 android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp)
3541 })
3542 }
3543}
3544
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003545func TestCodelessApp(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003546 t.Parallel()
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003547 testCases := []struct {
3548 name string
3549 bp string
3550 noCode bool
3551 }{
3552 {
3553 name: "normal",
3554 bp: `
3555 android_app {
3556 name: "foo",
3557 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003558 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003559 }
3560 `,
3561 noCode: false,
3562 },
3563 {
3564 name: "app without sources",
3565 bp: `
3566 android_app {
3567 name: "foo",
Jeongik Cha538c0d02019-07-11 15:54:27 +09003568 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003569 }
3570 `,
3571 noCode: true,
3572 },
3573 {
3574 name: "app with libraries",
3575 bp: `
3576 android_app {
3577 name: "foo",
3578 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003579 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003580 }
3581
3582 java_library {
3583 name: "lib",
3584 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003585 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003586 }
3587 `,
3588 noCode: false,
3589 },
3590 {
3591 name: "app with sourceless libraries",
3592 bp: `
3593 android_app {
3594 name: "foo",
3595 static_libs: ["lib"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003596 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003597 }
3598
3599 java_library {
3600 name: "lib",
Jeongik Cha538c0d02019-07-11 15:54:27 +09003601 sdk_version: "current",
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003602 }
3603 `,
3604 // TODO(jungjw): this should probably be true
3605 noCode: false,
3606 },
3607 }
3608
3609 for _, test := range testCases {
3610 t.Run(test.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003611 t.Parallel()
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003612 ctx := testApp(t, test.bp)
3613
Colin Cross90607e92025-02-11 14:58:07 -08003614 foo := ctx.ModuleForTests(t, "foo", "android_common")
Jaewoong Jungc27ab662019-05-30 15:51:14 -07003615 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3616 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
3617 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
3618 }
3619 })
3620 }
3621}
Jaewoong Jung5b425e22019-06-17 17:40:56 -07003622
Colin Cross53a87f52019-06-25 13:35:30 -07003623func TestUncompressDex(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003624 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003625 testCases := []struct {
3626 name string
3627 bp string
3628
3629 uncompressedPlatform bool
3630 uncompressedUnbundled bool
3631 }{
3632 {
3633 name: "normal",
3634 bp: `
3635 android_app {
3636 name: "foo",
3637 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003638 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003639 }
3640 `,
3641 uncompressedPlatform: true,
3642 uncompressedUnbundled: false,
3643 },
3644 {
3645 name: "use_embedded_dex",
3646 bp: `
3647 android_app {
3648 name: "foo",
3649 use_embedded_dex: true,
3650 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003651 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003652 }
3653 `,
3654 uncompressedPlatform: true,
3655 uncompressedUnbundled: true,
3656 },
3657 {
3658 name: "privileged",
3659 bp: `
3660 android_app {
3661 name: "foo",
3662 privileged: true,
3663 srcs: ["a.java"],
Jeongik Cha538c0d02019-07-11 15:54:27 +09003664 sdk_version: "current",
Colin Cross53a87f52019-06-25 13:35:30 -07003665 }
3666 `,
3667 uncompressedPlatform: true,
3668 uncompressedUnbundled: true,
3669 },
David Srbeckye033cba2020-05-20 22:20:28 +01003670 {
3671 name: "normal_uncompress_dex_true",
3672 bp: `
3673 android_app {
3674 name: "foo",
3675 srcs: ["a.java"],
3676 sdk_version: "current",
3677 uncompress_dex: true,
3678 }
3679 `,
3680 uncompressedPlatform: true,
3681 uncompressedUnbundled: true,
3682 },
3683 {
3684 name: "normal_uncompress_dex_false",
3685 bp: `
3686 android_app {
3687 name: "foo",
3688 srcs: ["a.java"],
3689 sdk_version: "current",
3690 uncompress_dex: false,
3691 }
3692 `,
3693 uncompressedPlatform: false,
3694 uncompressedUnbundled: false,
3695 },
Colin Cross53a87f52019-06-25 13:35:30 -07003696 }
3697
3698 test := func(t *testing.T, bp string, want bool, unbundled bool) {
3699 t.Helper()
3700
Paul Duffin71ae5942021-03-22 15:36:52 +00003701 result := android.GroupFixturePreparers(
3702 prepareForJavaTest,
Paul Duffin2645a292021-03-13 02:36:00 +00003703 PrepareForTestWithPrebuiltsOfCurrentApi,
Paul Duffincdb88a92021-03-14 00:36:50 +00003704 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3705 if unbundled {
3706 variables.Unbundled_build = proptools.BoolPtr(true)
3707 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
3708 }
3709 }),
3710 ).RunTestWithBp(t, bp)
Colin Cross53a87f52019-06-25 13:35:30 -07003711
Colin Cross90607e92025-02-11 14:58:07 -08003712 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross53a87f52019-06-25 13:35:30 -07003713 dex := foo.Rule("r8")
3714 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
3715 aligned := foo.MaybeRule("zipalign").Rule != nil
3716
Paul Duffincdb88a92021-03-14 00:36:50 +00003717 android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar)
Colin Cross53a87f52019-06-25 13:35:30 -07003718
Paul Duffincdb88a92021-03-14 00:36:50 +00003719 android.AssertBoolEquals(t, "aligne", want, aligned)
Colin Cross53a87f52019-06-25 13:35:30 -07003720 }
3721
3722 for _, tt := range testCases {
3723 t.Run(tt.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003724 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003725 t.Run("platform", 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.uncompressedPlatform, false)
3728 })
3729 t.Run("unbundled", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003730 t.Parallel()
Colin Cross53a87f52019-06-25 13:35:30 -07003731 test(t, tt.bp, tt.uncompressedUnbundled, true)
3732 })
3733 })
3734 }
3735}
Jaewoong Jung26dedd32019-06-06 08:45:58 -07003736
3737func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
3738 if expectedValue != "" {
3739 expectedFlag := "--" + flagName + " " + expectedValue
3740 if !strings.Contains(aapt2Flags, expectedFlag) {
3741 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
3742 }
3743 } else {
3744 unexpectedFlag := "--" + flagName
3745 if strings.Contains(aapt2Flags, unexpectedFlag) {
3746 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
3747 }
3748 }
3749}
Jaewoong Jung9befb0c2020-01-18 10:33:43 -08003750
Cole Faust9a631312020-10-22 21:05:24 +00003751func TestExportedProguardFlagFiles(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003752 t.Parallel()
Cole Faust9a631312020-10-22 21:05:24 +00003753 ctx, _ := testJava(t, `
3754 android_app {
3755 name: "foo",
3756 sdk_version: "current",
Colin Crosscde55342024-03-27 14:11:51 -07003757 static_libs: [
3758 "lib1",
3759 "lib3",
3760 ],
Cole Faust9a631312020-10-22 21:05:24 +00003761 }
3762
3763 android_library {
3764 name: "lib1",
3765 sdk_version: "current",
3766 optimize: {
3767 proguard_flags_files: ["lib1proguard.cfg"],
Colin Crosscde55342024-03-27 14:11:51 -07003768 },
3769 static_libs: ["lib2"],
3770 }
3771
3772 android_library {
3773 name: "lib2",
3774 sdk_version: "current",
3775 optimize: {
3776 proguard_flags_files: ["lib2proguard.cfg"],
Cole Faust9a631312020-10-22 21:05:24 +00003777 }
3778 }
Colin Crosscde55342024-03-27 14:11:51 -07003779
3780 android_library_import {
3781 name: "lib3",
3782 sdk_version: "current",
3783 aars: ["lib3.aar"],
3784 static_libs: ["lib4"],
3785 }
3786
3787 android_library {
3788 name: "lib4",
3789 sdk_version: "current",
3790 optimize: {
3791 proguard_flags_files: ["lib4proguard.cfg"],
3792 }
3793 }
3794
3795
Cole Faust9a631312020-10-22 21:05:24 +00003796 `)
3797
Colin Cross90607e92025-02-11 14:58:07 -08003798 m := ctx.ModuleForTests(t, "foo", "android_common")
Colin Crosscde55342024-03-27 14:11:51 -07003799 r8 := m.Rule("java.r8")
3800 implicits := r8.Implicits.RelativeToTop().Strings()
3801 android.AssertStringListContains(t, "r8 implicits", implicits, "lib1proguard.cfg")
3802 android.AssertStringListContains(t, "r8 implicits", implicits, "lib2proguard.cfg")
3803 android.AssertStringListContains(t, "r8 implicits", implicits, "lib4proguard.cfg")
3804 android.AssertStringListContains(t, "r8 implicits", implicits, "out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
Cole Faust9a631312020-10-22 21:05:24 +00003805
Colin Crosscde55342024-03-27 14:11:51 -07003806 flags := r8.Args["r8Flags"]
3807 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib1proguard.cfg")
3808 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib2proguard.cfg")
3809 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib4proguard.cfg")
3810 android.AssertStringDoesContain(t, "r8 flags", flags, "-include out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
Cole Faust9a631312020-10-22 21:05:24 +00003811}
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003812
3813func TestTargetSdkVersionManifestFixer(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003814 t.Parallel()
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003815 platform_sdk_codename := "Tiramisu"
Spandan Dasfb6a1ee2023-04-27 16:08:26 +00003816 platform_sdk_version := 33
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003817 testCases := []struct {
3818 name string
3819 targetSdkVersionInBp string
3820 targetSdkVersionExpected string
3821 unbundledBuild bool
Spandan Dasfb6a1ee2023-04-27 16:08:26 +00003822 platformSdkFinal bool
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003823 }{
3824 {
3825 name: "Non-Unbundled build: Android.bp has targetSdkVersion",
3826 targetSdkVersionInBp: "30",
3827 targetSdkVersionExpected: "30",
3828 unbundledBuild: false,
3829 },
3830 {
3831 name: "Unbundled build: Android.bp has targetSdkVersion",
3832 targetSdkVersionInBp: "30",
3833 targetSdkVersionExpected: "30",
3834 unbundledBuild: true,
3835 },
3836 {
3837 name: "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
3838 targetSdkVersionInBp: platform_sdk_codename,
3839 targetSdkVersionExpected: platform_sdk_codename,
3840 unbundledBuild: false,
3841 },
3842 {
3843 name: "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
3844 targetSdkVersionInBp: platform_sdk_codename,
3845 targetSdkVersionExpected: "10000",
3846 unbundledBuild: true,
3847 },
3848
3849 {
3850 name: "Non-Unbundled build: Android.bp has no targetSdkVersion",
3851 targetSdkVersionExpected: platform_sdk_codename,
3852 unbundledBuild: false,
3853 },
3854 {
3855 name: "Unbundled build: Android.bp has no targetSdkVersion",
3856 targetSdkVersionExpected: "10000",
3857 unbundledBuild: true,
3858 },
Spandan Dasfb6a1ee2023-04-27 16:08:26 +00003859 {
3860 name: "Bundled build in REL branches",
3861 targetSdkVersionExpected: "33",
3862 unbundledBuild: false,
3863 platformSdkFinal: true,
3864 },
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003865 }
3866 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08003867 t.Run(testCase.name, func(t *testing.T) {
3868 t.Parallel()
3869 targetSdkVersionTemplate := ""
3870 if testCase.targetSdkVersionInBp != "" {
3871 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
3872 }
3873 bp := fmt.Sprintf(`
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003874 android_app {
3875 name: "foo",
3876 sdk_version: "current",
Spandan Dasca70fc42023-03-01 23:38:49 +00003877 %s
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003878 }
Spandan Dasca70fc42023-03-01 23:38:49 +00003879 `, targetSdkVersionTemplate)
Colin Cross844cb6a2025-01-29 15:53:21 -08003880 fixture := android.GroupFixturePreparers(
3881 prepareForJavaTest,
3882 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3883 if testCase.platformSdkFinal {
3884 variables.Platform_sdk_final = proptools.BoolPtr(true)
3885 }
3886 // explicitly set platform_sdk_codename to make the test deterministic
3887 variables.Platform_sdk_codename = &platform_sdk_codename
3888 variables.Platform_sdk_version = &platform_sdk_version
3889 variables.Platform_version_active_codenames = []string{platform_sdk_codename}
3890 // create a non-empty list if unbundledBuild==true
3891 if testCase.unbundledBuild {
3892 variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
3893 }
3894 }),
3895 )
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003896
Colin Cross844cb6a2025-01-29 15:53:21 -08003897 result := fixture.RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08003898 foo := result.ModuleForTests(t, "foo", "android_common")
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003899
Colin Cross844cb6a2025-01-29 15:53:21 -08003900 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3901 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
3902 })
Spandan Dasc8cb0c32021-12-08 17:00:38 +00003903 }
3904}
Colin Cross412436f2022-04-07 17:40:07 -07003905
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003906func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08003907 t.Parallel()
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003908 platform_sdk_codename := "Tiramisu"
3909 platform_sdk_version := 33
3910 testCases := []struct {
3911 name string
3912 platform_sdk_final bool
3913 targetSdkVersionInBp *string
3914 targetSdkVersionExpected *string
3915 updatable bool
3916 }{
3917 {
3918 name: "Non-Updatable Module: Android.bp has older targetSdkVersion",
3919 targetSdkVersionInBp: proptools.StringPtr("29"),
3920 targetSdkVersionExpected: proptools.StringPtr("29"),
3921 updatable: false,
3922 },
3923 {
3924 name: "Updatable Module: Android.bp has older targetSdkVersion",
3925 targetSdkVersionInBp: proptools.StringPtr("30"),
3926 targetSdkVersionExpected: proptools.StringPtr("30"),
3927 updatable: true,
3928 },
3929 {
3930 name: "Updatable Module: Android.bp has no targetSdkVersion",
3931 targetSdkVersionExpected: proptools.StringPtr("10000"),
3932 updatable: true,
3933 },
3934 {
3935 name: "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion",
3936 platform_sdk_final: true,
3937 targetSdkVersionInBp: proptools.StringPtr("30"),
3938 targetSdkVersionExpected: proptools.StringPtr("30"),
3939 updatable: false,
3940 },
3941 {
3942 name: "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion",
3943 platform_sdk_final: true,
3944 targetSdkVersionInBp: proptools.StringPtr("30"),
3945 targetSdkVersionExpected: proptools.StringPtr("30"),
3946 updatable: true,
3947 },
3948 {
3949 name: "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename",
3950 platform_sdk_final: true,
3951 targetSdkVersionInBp: proptools.StringPtr(platform_sdk_codename),
3952 targetSdkVersionExpected: proptools.StringPtr("33"),
3953 updatable: true,
3954 },
3955 {
3956 name: "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion",
3957 platform_sdk_final: true,
3958 targetSdkVersionExpected: proptools.StringPtr("33"),
3959 updatable: true,
3960 },
3961 }
3962 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08003963 t.Run(testCase.name, func(t *testing.T) {
3964 t.Parallel()
3965 targetSdkVersionTemplate := ""
3966 if testCase.targetSdkVersionInBp != nil {
3967 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
3968 }
3969 bp := fmt.Sprintf(`
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003970 android_app {
3971 name: "foo",
3972 sdk_version: "current",
3973 min_sdk_version: "29",
Spandan Dasca70fc42023-03-01 23:38:49 +00003974 %s
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003975 updatable: %t,
3976 enforce_default_target_sdk_version: %t
3977 }
Spandan Dasca70fc42023-03-01 23:38:49 +00003978 `, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003979
Colin Cross844cb6a2025-01-29 15:53:21 -08003980 fixture := android.GroupFixturePreparers(
3981 PrepareForTestWithJavaDefaultModules,
3982 android.PrepareForTestWithAllowMissingDependencies,
3983 android.PrepareForTestWithAndroidMk,
3984 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3985 // explicitly set following platform variables to make the test deterministic
3986 variables.Platform_sdk_final = &testCase.platform_sdk_final
3987 variables.Platform_sdk_version = &platform_sdk_version
3988 variables.Platform_sdk_codename = &platform_sdk_codename
3989 variables.Platform_version_active_codenames = []string{platform_sdk_codename}
3990 variables.Unbundled_build = proptools.BoolPtr(true)
3991 variables.Unbundled_build_apps = []string{"sampleModule"}
3992 }),
3993 )
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003994
Colin Cross844cb6a2025-01-29 15:53:21 -08003995 result := fixture.RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08003996 foo := result.ModuleForTests(t, "foo", "android_common")
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00003997
Colin Cross844cb6a2025-01-29 15:53:21 -08003998 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3999 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
4000 })
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004001 }
4002}
4003
4004func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004005 t.Parallel()
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004006 platform_sdk_codename := "Tiramisu"
4007 platform_sdk_version := 33
4008 testCases := []struct {
4009 name string
4010 enforceDefaultTargetSdkVersion bool
4011 expectedError string
4012 platform_sdk_final bool
4013 targetSdkVersionInBp string
4014 targetSdkVersionExpected string
4015 updatable bool
4016 }{
4017 {
4018 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
4019 enforceDefaultTargetSdkVersion: false,
4020 targetSdkVersionInBp: "29",
4021 targetSdkVersionExpected: "29",
4022 updatable: false,
4023 },
4024 {
4025 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
4026 enforceDefaultTargetSdkVersion: true,
4027 platform_sdk_final: true,
4028 targetSdkVersionInBp: "current",
4029 targetSdkVersionExpected: "33",
4030 updatable: true,
4031 },
4032 {
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004033 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004034 enforceDefaultTargetSdkVersion: true,
4035 platform_sdk_final: false,
4036 targetSdkVersionInBp: "current",
4037 targetSdkVersionExpected: "10000",
4038 updatable: false,
4039 },
4040 {
4041 name: "Not enforcing Target SDK Version for Updatable app",
4042 enforceDefaultTargetSdkVersion: false,
4043 expectedError: "Updatable apps must enforce default target sdk version",
4044 targetSdkVersionInBp: "29",
4045 targetSdkVersionExpected: "29",
4046 updatable: true,
4047 },
4048 }
4049 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004050 t.Run(testCase.name, func(t *testing.T) {
4051 t.Parallel()
4052 errExpected := testCase.expectedError != ""
4053 bp := fmt.Sprintf(`
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004054 android_app {
4055 name: "foo",
4056 enforce_default_target_sdk_version: %t,
4057 sdk_version: "current",
4058 min_sdk_version: "29",
4059 target_sdk_version: "%v",
4060 updatable: %t
4061 }
4062 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
4063
Colin Cross844cb6a2025-01-29 15:53:21 -08004064 fixture := android.GroupFixturePreparers(
4065 PrepareForTestWithJavaDefaultModules,
4066 android.PrepareForTestWithAllowMissingDependencies,
4067 android.PrepareForTestWithAndroidMk,
4068 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4069 // explicitly set following platform variables to make the test deterministic
4070 variables.Platform_sdk_final = &testCase.platform_sdk_final
4071 variables.Platform_sdk_version = &platform_sdk_version
4072 variables.Platform_sdk_codename = &platform_sdk_codename
4073 variables.Unbundled_build = proptools.BoolPtr(true)
4074 variables.Unbundled_build_apps = []string{"sampleModule"}
4075 }),
4076 )
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004077
Colin Cross844cb6a2025-01-29 15:53:21 -08004078 errorHandler := android.FixtureExpectsNoErrors
4079 if errExpected {
4080 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
4081 }
4082 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004083
Colin Cross844cb6a2025-01-29 15:53:21 -08004084 if !errExpected {
Colin Cross90607e92025-02-11 14:58:07 -08004085 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross844cb6a2025-01-29 15:53:21 -08004086 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
4087 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
4088 }
4089 })
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00004090 }
4091}
4092
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004093func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004094 t.Parallel()
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004095 platform_sdk_codename := "Tiramisu"
4096 platform_sdk_version := 33
4097 testCases := []struct {
4098 name string
4099 enforceDefaultTargetSdkVersion bool
4100 expectedError string
4101 platform_sdk_final bool
4102 targetSdkVersionInBp string
4103 targetSdkVersionExpected string
4104 }{
4105 {
4106 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
4107 enforceDefaultTargetSdkVersion: false,
4108 targetSdkVersionInBp: "29",
4109 targetSdkVersionExpected: "29",
4110 },
4111 {
4112 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
4113 enforceDefaultTargetSdkVersion: true,
4114 platform_sdk_final: true,
4115 targetSdkVersionInBp: "current",
4116 targetSdkVersionExpected: "33",
4117 },
4118 {
4119 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
4120 enforceDefaultTargetSdkVersion: true,
4121 platform_sdk_final: false,
4122 targetSdkVersionInBp: "current",
4123 targetSdkVersionExpected: "10000",
4124 },
4125 }
4126 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004127 t.Run(testCase.name, func(t *testing.T) {
4128 t.Parallel()
4129 errExpected := testCase.expectedError != ""
4130 bp := fmt.Sprintf(`
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004131 android_test {
4132 name: "foo",
4133 enforce_default_target_sdk_version: %t,
4134 min_sdk_version: "29",
4135 target_sdk_version: "%v",
4136 }
4137 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp)
4138
Colin Cross844cb6a2025-01-29 15:53:21 -08004139 fixture := android.GroupFixturePreparers(
4140 PrepareForTestWithJavaDefaultModules,
4141 android.PrepareForTestWithAllowMissingDependencies,
4142 android.PrepareForTestWithAndroidMk,
4143 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4144 // explicitly set following platform variables to make the test deterministic
4145 variables.Platform_sdk_final = &testCase.platform_sdk_final
4146 variables.Platform_sdk_version = &platform_sdk_version
4147 variables.Platform_sdk_codename = &platform_sdk_codename
4148 variables.Unbundled_build = proptools.BoolPtr(true)
4149 variables.Unbundled_build_apps = []string{"sampleModule"}
4150 }),
4151 )
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004152
Colin Cross844cb6a2025-01-29 15:53:21 -08004153 errorHandler := android.FixtureExpectsNoErrors
4154 if errExpected {
4155 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
4156 }
4157 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004158
Colin Cross844cb6a2025-01-29 15:53:21 -08004159 if !errExpected {
Colin Cross90607e92025-02-11 14:58:07 -08004160 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross844cb6a2025-01-29 15:53:21 -08004161 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
4162 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
4163 }
4164 })
Harshit Mahajan8f202ad2023-01-09 20:45:55 +00004165 }
4166}
4167
Colin Cross412436f2022-04-07 17:40:07 -07004168func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004169 t.Parallel()
Colin Cross412436f2022-04-07 17:40:07 -07004170 result := android.GroupFixturePreparers(
4171 PrepareForTestWithJavaDefaultModules,
4172 android.PrepareForTestWithAllowMissingDependencies,
4173 android.PrepareForTestWithAndroidMk,
4174 ).RunTestWithBp(t, `
4175 android_app {
4176 name: "foo",
4177 srcs: ["a.java"],
4178 certificate: ":missing_certificate",
4179 sdk_version: "current",
Zyan Wub7550aa2023-05-18 15:46:31 +08004180 }
4181
4182 android_app {
4183 name: "bar",
4184 srcs: ["a.java"],
4185 certificate: ":missing_certificate",
4186 product_specific: true,
4187 sdk_version: "current",
Colin Cross412436f2022-04-07 17:40:07 -07004188 }`)
4189
Colin Cross90607e92025-02-11 14:58:07 -08004190 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross412436f2022-04-07 17:40:07 -07004191 fooApk := foo.Output("foo.apk")
4192 if fooApk.Rule != android.ErrorRule {
4193 t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
4194 }
4195 android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
4196}
Sam Delmerico82602492022-06-10 17:05:42 +00004197
4198func TestAppIncludesJniPackages(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004199 t.Parallel()
Sam Delmerico82602492022-06-10 17:05:42 +00004200 ctx := android.GroupFixturePreparers(
4201 PrepareForTestWithJavaDefaultModules,
4202 ).RunTestWithBp(t, `
4203 android_library_import {
4204 name: "aary-nodeps",
4205 aars: ["aary.aar"],
4206 extract_jni: true,
4207 }
4208
4209 android_library {
4210 name: "aary-lib",
4211 sdk_version: "current",
4212 min_sdk_version: "21",
4213 static_libs: ["aary-nodeps"],
4214 }
4215
4216 android_app {
4217 name: "aary-lib-dep",
4218 sdk_version: "current",
4219 min_sdk_version: "21",
4220 manifest: "AndroidManifest.xml",
4221 static_libs: ["aary-lib"],
4222 use_embedded_native_libs: true,
4223 }
4224
4225 android_app {
4226 name: "aary-import-dep",
4227 sdk_version: "current",
4228 min_sdk_version: "21",
4229 manifest: "AndroidManifest.xml",
4230 static_libs: ["aary-nodeps"],
4231 use_embedded_native_libs: true,
4232 }
4233
4234 android_app {
4235 name: "aary-no-use-embedded",
4236 sdk_version: "current",
4237 min_sdk_version: "21",
4238 manifest: "AndroidManifest.xml",
4239 static_libs: ["aary-nodeps"],
4240 }`)
4241
4242 testCases := []struct {
4243 name string
4244 hasPackage bool
4245 }{
4246 {
4247 name: "aary-import-dep",
4248 hasPackage: true,
4249 },
4250 {
4251 name: "aary-lib-dep",
4252 hasPackage: true,
4253 },
4254 {
4255 name: "aary-no-use-embedded",
Jiyong Parkd044bb42024-05-15 02:09:54 +09004256 hasPackage: false,
Sam Delmerico82602492022-06-10 17:05:42 +00004257 },
4258 }
4259
4260 for _, tc := range testCases {
4261 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004262 t.Parallel()
Colin Cross90607e92025-02-11 14:58:07 -08004263 app := ctx.ModuleForTests(t, tc.name, "android_common")
Sam Delmerico82602492022-06-10 17:05:42 +00004264
4265 outputFile := "jnilibs.zip"
4266 jniOutputLibZip := app.MaybeOutput(outputFile)
4267 if jniOutputLibZip.Rule == nil && !tc.hasPackage {
4268 return
4269 }
4270
4271 jniPackage := "arm64-v8a_jni.zip"
4272 inputs := jniOutputLibZip.Inputs
4273 foundPackage := false
4274 for i := 0; i < len(inputs); i++ {
4275 if strings.Contains(inputs[i].String(), jniPackage) {
4276 foundPackage = true
4277 }
4278 }
4279 if foundPackage != tc.hasPackage {
4280 t.Errorf("expected to find %v in %v inputs; inputs = %v", jniPackage, outputFile, inputs)
4281 }
4282 })
4283 }
4284}
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004285
4286func TestTargetSdkVersionMtsTests(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004287 t.Parallel()
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004288 platformSdkCodename := "Tiramisu"
4289 android_test := "android_test"
4290 android_test_helper_app := "android_test_helper_app"
4291 bpTemplate := `
4292 %v {
4293 name: "mytest",
Spandan Dasb0410872024-06-25 03:30:03 +00004294 min_sdk_version: "34",
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004295 target_sdk_version: "%v",
4296 test_suites: ["othersuite", "%v"],
4297 }
4298 `
4299 testCases := []struct {
4300 desc string
4301 moduleType string
4302 targetSdkVersionInBp string
4303 targetSdkVersionExpected string
4304 testSuites string
4305 }{
4306 {
4307 desc: "Non-MTS android_test_apps targeting current should not be upgraded to 10000",
4308 moduleType: android_test,
4309 targetSdkVersionInBp: "current",
4310 targetSdkVersionExpected: platformSdkCodename,
4311 testSuites: "non-mts-suite",
4312 },
4313 {
4314 desc: "MTS android_test_apps targeting released sdks should not be upgraded to 10000",
4315 moduleType: android_test,
4316 targetSdkVersionInBp: "29",
4317 targetSdkVersionExpected: "29",
4318 testSuites: "mts-suite",
4319 },
4320 {
4321 desc: "MTS android_test_apps targeting current should be upgraded to 10000",
4322 moduleType: android_test,
4323 targetSdkVersionInBp: "current",
4324 targetSdkVersionExpected: "10000",
4325 testSuites: "mts-suite",
4326 },
4327 {
4328 desc: "MTS android_test_helper_apps targeting current should be upgraded to 10000",
4329 moduleType: android_test_helper_app,
4330 targetSdkVersionInBp: "current",
4331 targetSdkVersionExpected: "10000",
4332 testSuites: "mts-suite",
4333 },
4334 }
4335 fixture := android.GroupFixturePreparers(
4336 prepareForJavaTest,
4337 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4338 variables.Platform_sdk_codename = &platformSdkCodename
4339 variables.Platform_version_active_codenames = []string{platformSdkCodename}
4340 }),
4341 )
4342 for _, testCase := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004343 t.Run(testCase.desc, func(t *testing.T) {
4344 t.Parallel()
4345 result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
Colin Cross90607e92025-02-11 14:58:07 -08004346 mytest := result.ModuleForTests(t, "mytest", "android_common")
Colin Cross844cb6a2025-01-29 15:53:21 -08004347 manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
4348 android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
4349 })
Spandan Das9f7ae7f2022-07-25 00:34:18 +00004350 }
4351}
Andrei Onea580636b2022-08-17 16:53:46 +00004352
4353func TestPrivappAllowlist(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004354 t.Parallel()
Andrei Onea580636b2022-08-17 16:53:46 +00004355 testJavaError(t, "privileged must be set in order to use privapp_allowlist", `
4356 android_app {
4357 name: "foo",
4358 srcs: ["a.java"],
4359 privapp_allowlist: "perms.xml",
4360 }
4361 `)
4362
4363 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
4364 t,
4365 `
4366 android_app {
4367 name: "foo",
4368 srcs: ["a.java"],
Sam Delmerico15809f82023-05-15 17:21:47 -04004369 privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
Andrei Onea580636b2022-08-17 16:53:46 +00004370 privileged: true,
Andrei Onea580636b2022-08-17 16:53:46 +00004371 sdk_version: "current",
4372 }
4373 override_android_app {
4374 name: "bar",
4375 base: "foo",
4376 package_name: "com.google.android.foo",
4377 }
4378 `,
4379 )
Colin Cross90607e92025-02-11 14:58:07 -08004380 app := result.ModuleForTests(t, "foo", "android_common")
4381 overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
Andrei Onea580636b2022-08-17 16:53:46 +00004382
Sam Delmerico15809f82023-05-15 17:21:47 -04004383 // verify that privapp allowlist is created for override apps
Andrei Onea580636b2022-08-17 16:53:46 +00004384 overrideApp.Output("out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml")
Sam Delmerico15809f82023-05-15 17:21:47 -04004385 expectedAllowlistInput := "privapp_allowlist_com.android.foo.xml"
4386 overrideActualAllowlistInput := overrideApp.Rule("modifyAllowlist").Input.String()
4387 if expectedAllowlistInput != overrideActualAllowlistInput {
4388 t.Errorf("expected override allowlist to be %q; got %q", expectedAllowlistInput, overrideActualAllowlistInput)
Andrei Onea580636b2022-08-17 16:53:46 +00004389 }
4390
4391 // verify that permissions are copied to device
Cole Faust6b7075f2024-12-17 10:42:42 -08004392 app.Output("out/target/product/test_device/system/etc/permissions/foo.xml")
4393 overrideApp.Output("out/target/product/test_device/system/etc/permissions/bar.xml")
Andrei Onea580636b2022-08-17 16:53:46 +00004394}
Sam Delmericob1daccd2023-05-25 14:45:30 -04004395
4396func TestPrivappAllowlistAndroidMk(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004397 t.Parallel()
Sam Delmericob1daccd2023-05-25 14:45:30 -04004398 result := android.GroupFixturePreparers(
4399 PrepareForTestWithJavaDefaultModules,
4400 android.PrepareForTestWithAndroidMk,
4401 ).RunTestWithBp(
4402 t,
4403 `
4404 android_app {
4405 name: "foo",
4406 srcs: ["a.java"],
4407 privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
4408 privileged: true,
4409 sdk_version: "current",
4410 }
4411 override_android_app {
4412 name: "bar",
4413 base: "foo",
4414 package_name: "com.google.android.foo",
4415 }
4416 `,
4417 )
Colin Cross90607e92025-02-11 14:58:07 -08004418 baseApp := result.ModuleForTests(t, "foo", "android_common")
4419 overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
Sam Delmericob1daccd2023-05-25 14:45:30 -04004420
4421 baseAndroidApp := baseApp.Module().(*AndroidApp)
4422 baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0]
4423 android.AssertStringMatches(
4424 t,
4425 "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find foo.apk",
4426 baseEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
4427 "\\S+foo.apk",
4428 )
4429 android.AssertStringMatches(
4430 t,
4431 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include foo.apk",
4432 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4433 "\\S+foo.apk",
4434 )
4435 android.AssertStringMatches(
4436 t,
4437 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
4438 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4439 "\\S+foo.apk:\\S+/target/product/test_device/system/priv-app/foo/foo.apk",
4440 )
4441 android.AssertStringMatches(
4442 t,
4443 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
4444 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
Anton Hansson0e486a42023-06-01 16:38:35 +00004445 "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml",
Sam Delmericob1daccd2023-05-25 14:45:30 -04004446 )
4447
4448 overrideAndroidApp := overrideApp.Module().(*AndroidApp)
4449 overrideEntries := android.AndroidMkEntriesForTest(t, result.TestContext, overrideAndroidApp)[0]
4450 android.AssertStringMatches(
4451 t,
4452 "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find bar.apk",
4453 overrideEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
4454 "\\S+bar.apk",
4455 )
4456 android.AssertStringMatches(
4457 t,
4458 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include bar.apk",
4459 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4460 "\\S+bar.apk",
4461 )
4462 android.AssertStringMatches(
4463 t,
4464 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
4465 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
4466 "\\S+bar.apk:\\S+/target/product/test_device/system/priv-app/bar/bar.apk",
4467 )
4468 android.AssertStringMatches(
4469 t,
4470 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
4471 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
Anton Hansson0e486a42023-06-01 16:38:35 +00004472 "\\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 -04004473 )
4474}
Sam Delmerico0e0d96e2023-08-18 22:43:28 +00004475
Jihoon Kang84b25892023-12-01 22:01:06 +00004476func TestAppFlagsPackages(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004477 t.Parallel()
Jihoon Kang98ea8362024-07-16 18:20:03 +00004478 ctx := android.GroupFixturePreparers(
4479 prepareForJavaTest,
4480 android.FixtureMergeMockFs(
4481 map[string][]byte{
4482 "res/layout/layout.xml": nil,
4483 "res/values/strings.xml": nil,
4484 "res/values-en-rUS/strings.xml": nil,
4485 },
4486 ),
4487 ).RunTestWithBp(t, `
Jihoon Kang84b25892023-12-01 22:01:06 +00004488 android_app {
4489 name: "foo",
4490 srcs: ["a.java"],
4491 sdk_version: "current",
4492 flags_packages: [
4493 "bar",
4494 "baz",
4495 ],
4496 }
4497 aconfig_declarations {
4498 name: "bar",
Dennis Shen4e7773d2024-01-05 19:06:50 +00004499 package: "com.example.package.bar",
Yu Liu315a53c2024-04-24 16:41:57 +00004500 container: "com.android.foo",
Jihoon Kang84b25892023-12-01 22:01:06 +00004501 srcs: [
4502 "bar.aconfig",
4503 ],
4504 }
4505 aconfig_declarations {
4506 name: "baz",
Dennis Shen4e7773d2024-01-05 19:06:50 +00004507 package: "com.example.package.baz",
Yu Liu315a53c2024-04-24 16:41:57 +00004508 container: "com.android.foo",
Jihoon Kang84b25892023-12-01 22:01:06 +00004509 srcs: [
4510 "baz.aconfig",
4511 ],
4512 }
4513 `)
4514
Colin Cross90607e92025-02-11 14:58:07 -08004515 foo := ctx.ModuleForTests(t, "foo", "android_common")
Jihoon Kang84b25892023-12-01 22:01:06 +00004516
4517 // android_app module depends on aconfig_declarations listed in flags_packages
4518 android.AssertBoolEquals(t, "foo expected to depend on bar", true,
Jihoon Kang98ea8362024-07-16 18:20:03 +00004519 CheckModuleHasDependency(t, ctx.TestContext, "foo", "android_common", "bar"))
Jihoon Kang84b25892023-12-01 22:01:06 +00004520
4521 android.AssertBoolEquals(t, "foo expected to depend on baz", true,
Jihoon Kang98ea8362024-07-16 18:20:03 +00004522 CheckModuleHasDependency(t, ctx.TestContext, "foo", "android_common", "baz"))
Jihoon Kang84b25892023-12-01 22:01:06 +00004523
4524 aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
4525 linkInFlags := aapt2LinkRule.Args["inFlags"]
4526 android.AssertStringDoesContain(t,
4527 "aapt2 link command expected to pass feature flags arguments",
4528 linkInFlags,
4529 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
4530 )
Jihoon Kang98ea8362024-07-16 18:20:03 +00004531
4532 aapt2CompileRule := foo.Rule("android/soong/java.aapt2Compile")
4533 compileFlags := aapt2CompileRule.Args["cFlags"]
4534 android.AssertStringDoesContain(t,
4535 "aapt2 compile command expected to pass feature flags arguments",
4536 compileFlags,
4537 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
4538 )
Jihoon Kang84b25892023-12-01 22:01:06 +00004539}
Spandan Das0727ba72024-02-13 16:37:43 +00004540
Jihoon Kang9aef7772024-06-14 23:45:06 +00004541func TestAppFlagsPackagesPropagation(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004542 t.Parallel()
Jihoon Kang9aef7772024-06-14 23:45:06 +00004543 ctx := testApp(t, `
4544 aconfig_declarations {
4545 name: "foo",
4546 package: "com.example.package.foo",
4547 container: "com.android.foo",
4548 srcs: [
4549 "foo.aconfig",
4550 ],
4551 }
4552 aconfig_declarations {
4553 name: "bar",
4554 package: "com.example.package.bar",
4555 container: "com.android.bar",
4556 srcs: [
4557 "bar.aconfig",
4558 ],
4559 }
4560 aconfig_declarations {
4561 name: "baz",
4562 package: "com.example.package.baz",
4563 container: "com.android.baz",
4564 srcs: [
4565 "baz.aconfig",
4566 ],
4567 }
4568 android_library {
4569 name: "foo_lib",
4570 srcs: ["a.java"],
4571 sdk_version: "current",
4572 flags_packages: [
4573 "foo",
4574 ],
4575 }
4576 android_library {
4577 name: "bar_lib",
4578 srcs: ["a.java"],
4579 sdk_version: "current",
4580 flags_packages: [
4581 "bar",
4582 ],
4583 }
4584 android_app {
4585 name: "baz_app",
4586 srcs: ["a.java"],
4587 sdk_version: "current",
4588 flags_packages: [
4589 "baz",
4590 ],
4591 static_libs: [
4592 "bar_lib",
4593 ],
4594 libs: [
4595 "foo_lib",
4596 ],
4597 }
4598 `)
4599
Colin Cross90607e92025-02-11 14:58:07 -08004600 bazApp := ctx.ModuleForTests(t, "baz_app", "android_common")
Jihoon Kang9aef7772024-06-14 23:45:06 +00004601
4602 // android_app module depends on aconfig_declarations listed in flags_packages
4603 // and that of static libs, but not libs
4604 aapt2LinkRule := bazApp.Rule("android/soong/java.aapt2Link")
4605 linkInFlags := aapt2LinkRule.Args["inFlags"]
4606 android.AssertStringDoesContain(t,
4607 "aapt2 link command expected to pass feature flags arguments of flags_packages and that of its static libs",
4608 linkInFlags,
4609 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
4610 )
4611 android.AssertStringDoesNotContain(t,
4612 "aapt2 link command expected to not pass feature flags arguments of flags_packages of its libs",
4613 linkInFlags,
4614 "--feature-flags @out/soong/.intermediates/foo/intermediate.txt",
4615 )
4616}
4617
Spandan Das0727ba72024-02-13 16:37:43 +00004618// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
4619func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004620 t.Parallel()
Spandan Das0727ba72024-02-13 16:37:43 +00004621 bp := `
4622 java_sdk_library_import {
4623 name: "sdklib_noimpl",
4624 public: {
4625 jars: ["stub.jar"],
4626 },
4627 }
4628 android_app {
4629 name: "app",
4630 srcs: ["a.java"],
4631 sdk_version: "current",
4632 optional_uses_libs: [
4633 "sdklib_noimpl",
4634 ],
4635 }
4636 `
4637 result := prepareForJavaTest.RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08004638 dexpreopt := result.ModuleForTests(t, "app", "android_common").MaybeRule("dexpreopt").Rule
Spandan Das0727ba72024-02-13 16:37:43 +00004639 android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil)
4640}
yangbill2af0b6e2024-03-15 09:29:29 +00004641
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07004642func TestTestOnlyApp(t *testing.T) {
4643 t.Parallel()
4644 ctx := android.GroupFixturePreparers(
4645 prepareForJavaTest,
4646 ).RunTestWithBp(t, `
4647 // These should be test-only
4648 android_test {
4649 name: "android-test",
4650 }
4651 android_test_helper_app {
4652 name: "helper-app",
4653 }
4654 override_android_test {
4655 name: "override-test",
4656 base: "android-app",
4657 }
4658 // And these should not be
4659 android_app {
4660 name: "android-app",
4661 srcs: ["b.java"],
4662 sdk_version: "current",
4663 }
4664 `)
4665
4666 expectedTestOnly := []string{
4667 "android-test",
4668 "helper-app",
4669 "override-test",
4670 }
4671
4672 expectedTopLevel := []string{
4673 "android-test",
4674 "override-test",
4675 }
4676
4677 assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel)
4678}
4679
Jiyong Parkf528b702024-12-30 16:01:58 +09004680func TestTestConfigTemplate(t *testing.T) {
4681 t.Parallel()
4682 ctx := android.GroupFixturePreparers(
4683 prepareForJavaTest,
4684 ).RunTestWithBp(t, `
4685 android_test {
4686 name: "android-test",
4687 test_config_template: "AndroidTestTemplate.xml",
4688 test_options: {
4689 tradefed_options: [
4690 {
4691 name: "name1",
4692 key: "key1",
4693 value: "value1",
4694 },
4695 {
4696 name: "name2",
4697 key: "key2",
4698 value: "value2",
4699 },
4700 ],
4701 test_runner_options: [
4702 {
4703 name: "name3",
4704 key: "key3",
4705 value: "value3",
4706 },
4707 {
4708 name: "name4",
4709 key: "key4",
4710 value: "value4",
4711 },
4712 ],
4713 },
4714 }
4715 `)
4716 type option struct {
4717 name string
4718 key string
4719 value string
4720 }
4721 re := regexp.MustCompile(`<option name="(.*)" key="(.*)" value="(.*)" />`)
4722 parse_options := func(optionsString string) []option {
4723 lines := strings.Split(optionsString, `\n`)
4724 var ret []option
4725 for _, l := range lines {
4726 sm := re.FindStringSubmatch(l)
4727 if sm == nil {
4728 continue
4729 }
4730 ret = append(ret, option{sm[1], sm[2], sm[3]})
4731 }
4732 return ret
4733 }
Colin Cross90607e92025-02-11 14:58:07 -08004734 rule := ctx.ModuleForTests(t, "android-test", "android_common").Rule("autogenInstrumentationTest")
Jiyong Parkf528b702024-12-30 16:01:58 +09004735 android.AssertSameArray(t, "extraConfigs mismatch",
4736 []option{
4737 {"name1", "key1", "value1"},
4738 {"name2", "key2", "value2"},
4739 },
4740 parse_options(rule.Args["extraConfigs"]))
4741 android.AssertSameArray(t, "extraTestRunnerConfigs mismatch",
4742 []option{
4743 {"name3", "key3", "value3"},
4744 {"name4", "key4", "value4"},
4745 },
4746 parse_options(rule.Args["extraTestRunnerConfigs"]))
4747}
4748
yangbill2af0b6e2024-03-15 09:29:29 +00004749func TestAppStem(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004750 t.Parallel()
yangbill2af0b6e2024-03-15 09:29:29 +00004751 ctx := testApp(t, `
4752 android_app {
4753 name: "foo",
4754 srcs: ["a.java"],
4755 stem: "foo-new",
4756 sdk_version: "current",
4757 }`)
4758
Colin Cross90607e92025-02-11 14:58:07 -08004759 foo := ctx.ModuleForTests(t, "foo", "android_common")
yangbill2af0b6e2024-03-15 09:29:29 +00004760
4761 outputs := fmt.Sprint(foo.AllOutputs())
4762 if !strings.Contains(outputs, "foo-new.apk") {
4763 t.Errorf("Module output does not contain expected apk %s", "foo-new.apk")
4764 }
4765}
Spandan Dasb9c58352024-05-13 18:29:45 +00004766
4767func TestAppMinSdkVersionOverride(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004768 t.Parallel()
Spandan Dasb9c58352024-05-13 18:29:45 +00004769 result := android.GroupFixturePreparers(
4770 PrepareForTestWithJavaDefaultModules,
4771 ).RunTestWithBp(t, `
4772 android_app {
4773 name: "com.android.foo",
4774 srcs: ["a.java"],
4775 sdk_version: "current",
4776 min_sdk_version: "31",
4777 updatable: true,
4778 }
4779 override_android_app {
4780 name: "com.android.go.foo",
4781 base: "com.android.foo",
4782 min_sdk_version: "33",
4783 }
4784 `)
Colin Cross90607e92025-02-11 14:58:07 -08004785 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
4786 fooOverride := result.ModuleForTests(t, "com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
Spandan Dasb9c58352024-05-13 18:29:45 +00004787
4788 android.AssertStringDoesContain(t,
4789 "com.android.foo: expected manifest fixer to set minSdkVersion to T",
4790 foo.BuildParams.Args["args"],
4791 "--minSdkVersion 31",
4792 )
4793 android.AssertStringDoesContain(t,
4794 "com.android.go.foo: expected manifest fixer to set minSdkVersion to T",
4795 fooOverride.BuildParams.Args["args"],
4796 "--minSdkVersion 33",
4797 )
4798
4799}
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004800
4801func TestNotApplyDefaultUpdatableModuleVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004802 t.Parallel()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004803 result := android.GroupFixturePreparers(
4804 PrepareForTestWithJavaDefaultModules,
4805 ).RunTestWithBp(t, `
4806 android_app {
4807 name: "com.android.foo",
4808 srcs: ["a.java"],
4809 sdk_version: "current",
4810 min_sdk_version: "31",
4811 }
4812 `)
Colin Cross90607e92025-02-11 14:58:07 -08004813 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004814 android.AssertStringDoesNotContain(t,
4815 "com.android.foo: expected manifest fixer to not set override-placeholder-version",
4816 foo.BuildParams.Args["args"],
4817 "--override-placeholder-version",
4818 )
4819}
4820
4821func TestNotApplyOverrideApexManifestDefaultVersion(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004822 t.Parallel()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004823 result := android.GroupFixturePreparers(
4824 PrepareForTestWithJavaDefaultModules,
4825 android.FixtureMergeEnv(map[string]string{
4826 "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234",
4827 }),
4828 ).RunTestWithBp(t, `
4829 android_app {
4830 name: "com.android.foo",
4831 srcs: ["a.java"],
4832 sdk_version: "current",
4833 min_sdk_version: "31",
4834 }
4835 `)
Colin Cross90607e92025-02-11 14:58:07 -08004836 foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +00004837 android.AssertStringDoesNotContain(t,
4838 "com.android.foo: expected manifest fixer to not set override-placeholder-version",
4839 foo.BuildParams.Args["args"],
4840 "--override-placeholder-version",
4841 )
4842}
Jihoon Kang1c743042024-10-22 21:34:17 +00004843
4844func TestResourcesWithFlagDirectories(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -08004845 t.Parallel()
Jihoon Kang1c743042024-10-22 21:34:17 +00004846 result := android.GroupFixturePreparers(
4847 PrepareForTestWithJavaDefaultModules,
4848 android.FixtureMergeMockFs(android.MockFS{
4849 "res/flag(test.package.flag1)/values/bools.xml": nil,
4850 "res/flag(!test.package.flag2)/values/bools.xml": nil,
4851 "res/flag(test.package.flag1)/values-config/strings_google_services.xml": nil,
4852 "res/flags(test.package.flag1)/values/strings.xml": nil,
4853 }),
4854 ).RunTestWithBp(t, `
4855 android_library {
4856 name: "foo",
4857 srcs: ["a.java"],
4858 use_resource_processor: true,
4859 resource_dirs: [
4860 "res",
4861 ],
4862 }
4863 `)
Colin Cross90607e92025-02-11 14:58:07 -08004864 fooModule := result.ModuleForTests(t, "foo", "android_common")
Jihoon Kang1c743042024-10-22 21:34:17 +00004865 compileOutputPaths := fooModule.Rule("aapt2Compile").Outputs.Strings()
4866
4867 android.AssertStringListContains(
4868 t,
4869 "Expected to generate flag path",
4870 compileOutputPaths,
4871 "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(test.package.flag1).arsc.flat",
4872 )
4873 android.AssertStringListContains(
4874 t,
4875 "Expected to generate flag path with ! prefix in name",
4876 compileOutputPaths,
4877 "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(!test.package.flag2).arsc.flat",
4878 )
4879 android.AssertStringListContains(
4880 t,
4881 "Expected to generate flag path with configs",
4882 compileOutputPaths,
4883 "out/soong/.intermediates/foo/android_common/aapt2/res/values-config_strings_google_services.(test.package.flag1).arsc.flat",
4884 )
4885 android.AssertStringListDoesNotContain(
4886 t,
4887 "Expected to not generate flag path with non-flag(flag_name) pattern",
4888 compileOutputPaths,
4889 "out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat",
4890 )
4891}
Spandan Dasde588a32024-12-03 22:52:24 +00004892
4893func TestAutogeneratedStaticRro(t *testing.T) {
4894 t.Parallel()
4895 bp := `
4896android_app {
4897 name: "foo",
4898 srcs: ["foo.java"],
4899 platform_apis: true,
4900}
4901override_android_app {
4902 name: "override_foo",
4903 base: "foo",
4904}
4905`
4906 testCases := []struct {
4907 desc string
4908 preparer android.FixturePreparer
4909 overlayApkExpected bool
4910 }{
4911 {
4912 desc: "No DEVICE_PACKAGE_OVERLAYS, no overlay .apk file",
4913 overlayApkExpected: false,
4914 },
4915 {
4916 desc: "DEVICE_PACKAGE_OVERLAYS exists, but the directory is empty",
4917 overlayApkExpected: false,
4918 preparer: android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4919 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
4920 }),
4921 },
4922 {
4923 desc: "DEVICE_PACKAGE_OVERLAYS exists, directory is non-empty, but does not contain a matching resource dir",
4924 overlayApkExpected: false,
4925 preparer: android.GroupFixturePreparers(
4926 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4927 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
4928 }),
4929 android.MockFS{
4930 "res/foo.xml": nil,
4931 "device/company/test_product/different_res/foo.xml": nil, // different dir
4932 }.AddToFixture(),
4933 ),
4934 },
4935 {
4936 desc: "DEVICE_PACKAGE_OVERLAYS and the directory contain a matching resource dir",
4937 overlayApkExpected: true,
4938 preparer: android.GroupFixturePreparers(
4939 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4940 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
4941 }),
4942 android.MockFS{
4943 "res/foo.xml": nil,
4944 "device/company/test_product/res/foo.xml": nil,
4945 }.AddToFixture(),
4946 ),
4947 },
4948 }
4949 for _, tc := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08004950 t.Run(tc.desc, func(t *testing.T) {
4951 t.Parallel()
4952 result := android.GroupFixturePreparers(
4953 PrepareForTestWithJavaDefaultModules,
4954 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4955 variables.EnforceRROTargets = []string{"*"}
4956 }),
4957 android.OptionalFixturePreparer(tc.preparer),
4958 ).RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08004959 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 -08004960 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil)
Colin Cross90607e92025-02-11 14:58:07 -08004961 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 -08004962 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil)
4963 })
Spandan Dasde588a32024-12-03 22:52:24 +00004964 }
4965}
Spandan Dasef8b3b22024-12-04 01:34:34 +00004966
4967func TestNoAutogeneratedStaticRroForDisabledOverrideApps(t *testing.T) {
4968 t.Parallel()
4969 bp := `
4970soong_config_module_type {
4971 name: "my_custom_override_android_app",
4972 module_type: "override_android_app",
4973 config_namespace: "my_namespace",
4974 value_variables: ["my_app_enabled"],
4975 properties: ["enabled"],
4976}
4977soong_config_bool_variable {
4978 name: "my_app_enabled",
4979}
4980android_app {
4981 name: "foo",
4982 srcs: ["foo.java"],
4983 platform_apis: true,
4984}
4985my_custom_override_android_app {
4986 name: "override_foo",
4987 base: "foo",
4988 soong_config_variables: {
4989 my_app_enabled: {
4990 enabled: true,
4991 conditions_default: {
4992 enabled: false
4993 },
4994 },
4995 }
4996}
4997`
4998 testCases := []struct {
4999 desc string
5000 preparer android.FixturePreparer
5001 overlayApkExpected bool
5002 }{
5003 {
5004 desc: "my_app_enabled is empty",
5005 overlayApkExpected: false,
5006 },
5007 {
5008 desc: "my_app_enabled is true",
5009 overlayApkExpected: true,
5010 preparer: android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5011 variables.VendorVars = map[string]map[string]string{
5012 "my_namespace": {
5013 "my_app_enabled": "true",
5014 },
5015 }
5016 }),
5017 },
5018 }
5019 for _, tc := range testCases {
Colin Cross844cb6a2025-01-29 15:53:21 -08005020 t.Run(tc.desc, func(t *testing.T) {
5021 t.Parallel()
5022 result := android.GroupFixturePreparers(
5023 PrepareForTestWithJavaDefaultModules,
5024 android.PrepareForTestWithSoongConfigModuleBuildComponents,
5025 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5026 variables.EnforceRROTargets = []string{"*"}
5027 }),
5028 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5029 variables.DeviceResourceOverlays = []string{"device/company/test_product"}
5030 }),
5031 android.MockFS{
5032 "res/foo.xml": nil,
5033 "device/company/test_product/res/foo.xml": nil,
5034 }.AddToFixture(),
5035 android.OptionalFixturePreparer(tc.preparer),
5036 ).RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -08005037 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 -08005038 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.exportPackage != nil)
5039 })
Spandan Dasef8b3b22024-12-04 01:34:34 +00005040 }
5041}