blob: 1d497703a8310995e892b4ab9762815bdd908a2c [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 (
18 "android/soong/android"
Colin Cross47fa9d32019-03-26 10:51:39 -070019 "android/soong/cc"
20
Colin Crossd09b0b62018-04-18 11:06:47 -070021 "fmt"
Colin Crossa4f08812018-10-02 22:03:40 -070022 "path/filepath"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080023 "reflect"
Colin Crossb69301e2017-12-01 10:48:26 -080024 "sort"
Colin Crossd09b0b62018-04-18 11:06:47 -070025 "strings"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080026 "testing"
Colin Cross43377ee2019-06-25 13:35:30 -070027
28 "github.com/google/blueprint/proptools"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080029)
30
31var (
32 resourceFiles = []string{
33 "res/layout/layout.xml",
34 "res/values/strings.xml",
35 "res/values-en-rUS/strings.xml",
36 }
37
38 compiledResourceFiles = []string{
39 "aapt2/res/layout_layout.xml.flat",
40 "aapt2/res/values_strings.arsc.flat",
41 "aapt2/res/values-en-rUS_strings.arsc.flat",
42 }
43)
44
Colin Cross527012a2017-11-30 22:56:16 -080045func testAppContext(config android.Config, bp string, fs map[string][]byte) *android.TestContext {
46 appFS := map[string][]byte{}
47 for k, v := range fs {
48 appFS[k] = v
Colin Cross3bc7ffa2017-11-22 16:19:37 -080049 }
50
Colin Cross527012a2017-11-30 22:56:16 -080051 for _, file := range resourceFiles {
52 appFS[file] = nil
53 }
54
55 return testContext(config, bp, appFS)
56}
57
58func testApp(t *testing.T, bp string) *android.TestContext {
59 config := testConfig(nil)
60
61 ctx := testAppContext(config, bp, nil)
62
63 run(t, ctx, config)
64
65 return ctx
Colin Cross3bc7ffa2017-11-22 16:19:37 -080066}
67
68func TestApp(t *testing.T) {
Colin Crossa97c5d32018-03-28 14:58:31 -070069 for _, moduleType := range []string{"android_app", "android_library"} {
70 t.Run(moduleType, func(t *testing.T) {
71 ctx := testApp(t, moduleType+` {
72 name: "foo",
73 srcs: ["a.java"],
74 }
75 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080076
Colin Crossa97c5d32018-03-28 14:58:31 -070077 foo := ctx.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080078
Colin Cross31656952018-05-24 16:11:20 -070079 var expectedLinkImplicits []string
80
81 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
82 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080083
Colin Crossa97c5d32018-03-28 14:58:31 -070084 frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
85 expectedLinkImplicits = append(expectedLinkImplicits,
86 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080087
Colin Crossa97c5d32018-03-28 14:58:31 -070088 // Test the mapping from input files to compiled output file names
89 compile := foo.Output(compiledResourceFiles[0])
90 if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
91 t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
92 resourceFiles, compile.Inputs.Strings())
93 }
Colin Crossb69301e2017-12-01 10:48:26 -080094
Colin Crossa97c5d32018-03-28 14:58:31 -070095 compiledResourceOutputs := compile.Outputs.Strings()
96 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -080097
Colin Crossa97c5d32018-03-28 14:58:31 -070098 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080099
Colin Crossa97c5d32018-03-28 14:58:31 -0700100 list := foo.Output("aapt2/res.list")
101 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800102
Colin Crossa97c5d32018-03-28 14:58:31 -0700103 // Check that the link rule uses
104 res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
105 if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
106 t.Errorf("expected aapt2 link implicits expected:\n %#v\n got:\n %#v",
107 expectedLinkImplicits, res.Implicits.Strings())
108 }
109 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800110 }
111}
Colin Cross890ff552017-11-30 20:13:19 -0800112
Colin Crosse560c4a2019-03-19 16:03:11 -0700113func TestAppSplits(t *testing.T) {
114 ctx := testApp(t, `
115 android_app {
116 name: "foo",
117 srcs: ["a.java"],
118 package_splits: ["v4", "v7,hdpi"],
119 }`)
120
121 foo := ctx.ModuleForTests("foo", "android_common")
122
123 expectedOutputs := []string{
124 filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
125 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
126 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
127 }
128 for _, expectedOutput := range expectedOutputs {
129 foo.Output(expectedOutput)
130 }
131
132 if g, w := foo.Module().(*AndroidApp).Srcs().Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
133 t.Errorf("want Srcs() = %q, got %q", w, g)
134 }
135}
136
Sasha Smundak85390232020-04-23 09:49:59 -0700137func TestAndroidAppSet(t *testing.T) {
138 config := testConfig(nil)
139 config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
140 ctx := testAppContext(config, `
141 android_app_set {
142 name: "foo",
143 set: "prebuilts/apks/app.apks",
144 prerelease: true,
145 }`, nil)
146 run(t, ctx, config)
147 module := ctx.ModuleForTests("foo", "android_common")
148 const packedSplitApks = "extracted.zip"
149 params := module.Output(packedSplitApks)
150 if params.Rule == nil {
151 t.Errorf("expected output %s is missing", packedSplitApks)
152 }
153 if s := params.Args["allow-prereleased"]; s != "true" {
154 t.Errorf("wrong allow-prereleased value: '%s', expected 'true'", s)
155 }
Jaewoong Jung9cd42162020-06-29 19:18:44 -0700156 if s := params.Args["partition"]; s != "system" {
157 t.Errorf("wrong partition value: '%s', expected 'system'", s)
158 }
Sasha Smundak85390232020-04-23 09:49:59 -0700159}
160
161func TestAndroidAppSet_Variants(t *testing.T) {
162 bp := `
163 android_app_set {
164 name: "foo",
165 set: "prebuilts/apks/app.apks",
166 }`
167 testCases := []struct {
168 name string
169 deviceArch *string
170 deviceSecondaryArch *string
171 aaptPrebuiltDPI []string
172 sdkVersion int
173 expected map[string]string
174 }{
175 {
176 name: "One",
177 deviceArch: proptools.StringPtr("x86"),
178 aaptPrebuiltDPI: []string{"ldpi", "xxhdpi"},
179 sdkVersion: 29,
180 expected: map[string]string{
181 "abis": "X86",
182 "allow-prereleased": "false",
183 "screen-densities": "LDPI,XXHDPI",
184 "sdk-version": "29",
185 "stem": "foo",
186 },
187 },
188 {
189 name: "Two",
190 deviceArch: proptools.StringPtr("x86_64"),
191 deviceSecondaryArch: proptools.StringPtr("x86"),
192 aaptPrebuiltDPI: nil,
193 sdkVersion: 30,
194 expected: map[string]string{
195 "abis": "X86_64,X86",
196 "allow-prereleased": "false",
197 "screen-densities": "all",
198 "sdk-version": "30",
199 "stem": "foo",
200 },
201 },
202 }
203
204 for _, test := range testCases {
205 config := testConfig(nil)
206 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
207 config.TestProductVariables.Platform_sdk_version = &test.sdkVersion
208 config.TestProductVariables.DeviceArch = test.deviceArch
209 config.TestProductVariables.DeviceSecondaryArch = test.deviceSecondaryArch
210 ctx := testAppContext(config, bp, nil)
211 run(t, ctx, config)
212 module := ctx.ModuleForTests("foo", "android_common")
213 const packedSplitApks = "extracted.zip"
214 params := module.Output(packedSplitApks)
215 for k, v := range test.expected {
216 if actual := params.Args[k]; actual != v {
217 t.Errorf("%s: bad build arg value for '%s': '%s', expected '%s'",
218 test.name, k, actual, v)
219 }
220 }
221 }
222}
223
Colin Cross0ddae7f2019-02-07 15:30:01 -0800224func TestResourceDirs(t *testing.T) {
225 testCases := []struct {
226 name string
227 prop string
228 resources []string
229 }{
230 {
231 name: "no resource_dirs",
232 prop: "",
233 resources: []string{"res/res/values/strings.xml"},
234 },
235 {
236 name: "resource_dirs",
237 prop: `resource_dirs: ["res"]`,
238 resources: []string{"res/res/values/strings.xml"},
239 },
240 {
241 name: "empty resource_dirs",
242 prop: `resource_dirs: []`,
243 resources: nil,
244 },
245 }
246
247 fs := map[string][]byte{
248 "res/res/values/strings.xml": nil,
249 }
250
251 bp := `
252 android_app {
253 name: "foo",
254 %s
255 }
256 `
257
258 for _, testCase := range testCases {
259 t.Run(testCase.name, func(t *testing.T) {
260 config := testConfig(nil)
261 ctx := testContext(config, fmt.Sprintf(bp, testCase.prop), fs)
262 run(t, ctx, config)
263
264 module := ctx.ModuleForTests("foo", "android_common")
265 resourceList := module.MaybeOutput("aapt2/res.list")
266
267 var resources []string
268 if resourceList.Rule != nil {
269 for _, compiledResource := range resourceList.Inputs.Strings() {
270 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
271 }
272 }
273
274 if !reflect.DeepEqual(resources, testCase.resources) {
275 t.Errorf("expected resource files %q, got %q",
276 testCase.resources, resources)
277 }
278 })
279 }
280}
281
Colin Crossbec85302019-02-13 13:15:46 -0800282func TestAndroidResources(t *testing.T) {
Colin Cross5c4791c2019-02-01 11:44:44 -0800283 testCases := []struct {
284 name string
285 enforceRROTargets []string
286 enforceRROExcludedOverlays []string
Colin Crossbec85302019-02-13 13:15:46 -0800287 resourceFiles map[string][]string
Colin Cross5c4791c2019-02-01 11:44:44 -0800288 overlayFiles map[string][]string
289 rroDirs map[string][]string
290 }{
291 {
292 name: "no RRO",
293 enforceRROTargets: nil,
294 enforceRROExcludedOverlays: nil,
Colin Crossbec85302019-02-13 13:15:46 -0800295 resourceFiles: map[string][]string{
296 "foo": nil,
297 "bar": {"bar/res/res/values/strings.xml"},
298 "lib": nil,
299 "lib2": {"lib2/res/res/values/strings.xml"},
300 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800301 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800302 "foo": {
303 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800304 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000305 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800306 "foo/res/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800307 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
308 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Anton Hansson53c88442019-03-18 15:53:16 +0000309 "product/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800310 },
Colin Crossbec85302019-02-13 13:15:46 -0800311 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800312 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
313 "device/vendor/blah/overlay/bar/res/values/strings.xml",
314 },
Colin Crossbec85302019-02-13 13:15:46 -0800315 "lib": {
316 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
317 "lib/res/res/values/strings.xml",
318 "device/vendor/blah/overlay/lib/res/values/strings.xml",
319 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800320 },
321 rroDirs: map[string][]string{
322 "foo": nil,
323 "bar": nil,
324 },
325 },
326 {
327 name: "enforce RRO on foo",
328 enforceRROTargets: []string{"foo"},
329 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossbec85302019-02-13 13:15:46 -0800330 resourceFiles: map[string][]string{
331 "foo": nil,
332 "bar": {"bar/res/res/values/strings.xml"},
333 "lib": nil,
334 "lib2": {"lib2/res/res/values/strings.xml"},
335 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800336 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800337 "foo": {
338 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800339 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000340 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800341 "foo/res/res/values/strings.xml",
342 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
343 },
Colin Crossbec85302019-02-13 13:15:46 -0800344 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800345 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
346 "device/vendor/blah/overlay/bar/res/values/strings.xml",
347 },
Colin Crossbec85302019-02-13 13:15:46 -0800348 "lib": {
349 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
350 "lib/res/res/values/strings.xml",
351 "device/vendor/blah/overlay/lib/res/values/strings.xml",
352 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800353 },
Colin Crossc1c37552019-01-31 11:42:41 -0800354
Colin Cross5c4791c2019-02-01 11:44:44 -0800355 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800356 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000357 "device:device/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800358 // Enforce RRO on "foo" could imply RRO on static dependencies, but for now it doesn't.
359 // "device/vendor/blah/overlay/lib/res",
Anton Hansson53c88442019-03-18 15:53:16 +0000360 "product:product/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800361 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800362 "bar": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800363 "lib": nil,
Colin Cross5c4791c2019-02-01 11:44:44 -0800364 },
365 },
366 {
367 name: "enforce RRO on all",
368 enforceRROTargets: []string{"*"},
369 enforceRROExcludedOverlays: []string{
370 // Excluding specific apps/res directories also allowed.
371 "device/vendor/blah/static_overlay/foo",
372 "device/vendor/blah/static_overlay/bar/res",
373 },
Colin Crossbec85302019-02-13 13:15:46 -0800374 resourceFiles: map[string][]string{
375 "foo": nil,
376 "bar": {"bar/res/res/values/strings.xml"},
377 "lib": nil,
378 "lib2": {"lib2/res/res/values/strings.xml"},
379 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800380 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800381 "foo": {
382 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800383 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000384 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800385 "foo/res/res/values/strings.xml",
386 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
387 },
Colin Crossbec85302019-02-13 13:15:46 -0800388 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
389 "lib": {
390 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
391 "lib/res/res/values/strings.xml",
392 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800393 },
394 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800395 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000396 "device:device/vendor/blah/overlay/foo/res",
397 "product:product/vendor/blah/overlay/foo/res",
398 // Lib dep comes after the direct deps
399 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800400 },
Anton Hansson53c88442019-03-18 15:53:16 +0000401 "bar": {"device:device/vendor/blah/overlay/bar/res"},
402 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800403 },
404 },
405 }
406
Anton Hansson53c88442019-03-18 15:53:16 +0000407 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -0800408 "device/vendor/blah/overlay",
409 "device/vendor/blah/overlay2",
410 "device/vendor/blah/static_overlay",
411 }
412
Anton Hansson53c88442019-03-18 15:53:16 +0000413 productResourceOverlays := []string{
414 "product/vendor/blah/overlay",
415 }
416
Colin Cross890ff552017-11-30 20:13:19 -0800417 fs := map[string][]byte{
418 "foo/res/res/values/strings.xml": nil,
419 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800420 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800421 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800422 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
423 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800424 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800425 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
426 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
427 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +0000428 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800429 }
430
431 bp := `
432 android_app {
433 name: "foo",
434 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +0000435 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -0800436 }
437
438 android_app {
439 name: "bar",
440 resource_dirs: ["bar/res"],
441 }
Colin Cross6ed7dea2019-01-31 14:44:30 -0800442
443 android_library {
444 name: "lib",
445 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -0800446 static_libs: ["lib2"],
447 }
448
449 android_library {
450 name: "lib2",
451 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -0800452 }
Anton Hansson53c88442019-03-18 15:53:16 +0000453
454 // This library has the same resources as lib (should not lead to dupe RROs)
455 android_library {
456 name: "lib3",
457 resource_dirs: ["lib/res"]
458 }
Colin Cross890ff552017-11-30 20:13:19 -0800459 `
460
Colin Cross5c4791c2019-02-01 11:44:44 -0800461 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -0800462 t.Run(testCase.name, func(t *testing.T) {
463 config := testConfig(nil)
Anton Hansson53c88442019-03-18 15:53:16 +0000464 config.TestProductVariables.DeviceResourceOverlays = deviceResourceOverlays
465 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800466 if testCase.enforceRROTargets != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800467 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800468 }
469 if testCase.enforceRROExcludedOverlays != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800470 config.TestProductVariables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800471 }
472
473 ctx := testAppContext(config, bp, fs)
474 run(t, ctx, config)
475
Colin Crossbec85302019-02-13 13:15:46 -0800476 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
477 for _, o := range list {
478 res := module.MaybeOutput(o)
479 if res.Rule != nil {
480 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
481 // verify the inputs to the .arsc.flat rule.
482 files = append(files, res.Inputs.Strings()...)
483 } else {
484 // Otherwise, verify the full path to the output of the other module
485 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +0000486 }
Colin Cross890ff552017-11-30 20:13:19 -0800487 }
Colin Crossbec85302019-02-13 13:15:46 -0800488 return files
Colin Cross890ff552017-11-30 20:13:19 -0800489 }
490
Colin Crossbec85302019-02-13 13:15:46 -0800491 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
492 module := ctx.ModuleForTests(moduleName, "android_common")
493 resourceList := module.MaybeOutput("aapt2/res.list")
494 if resourceList.Rule != nil {
495 resourceFiles = resourceListToFiles(module, resourceList.Inputs.Strings())
Anton Hansson0375a4f2019-01-24 14:39:19 +0000496 }
Colin Crossbec85302019-02-13 13:15:46 -0800497 overlayList := module.MaybeOutput("aapt2/overlay.list")
498 if overlayList.Rule != nil {
499 overlayFiles = resourceListToFiles(module, overlayList.Inputs.Strings())
500 }
501
Anton Hansson53c88442019-03-18 15:53:16 +0000502 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
503 var prefix string
504 if d.overlayType == device {
505 prefix = "device:"
506 } else if d.overlayType == product {
507 prefix = "product:"
508 } else {
509 t.Fatalf("Unexpected overlayType %d", d.overlayType)
510 }
511 rroDirs = append(rroDirs, prefix+d.path.String())
512 }
Colin Crossbec85302019-02-13 13:15:46 -0800513
514 return resourceFiles, overlayFiles, rroDirs
515 }
516
517 modules := []string{"foo", "bar", "lib", "lib2"}
518 for _, module := range modules {
519 resourceFiles, overlayFiles, rroDirs := getResources(module)
520
521 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
522 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
523 module, testCase.resourceFiles[module], resourceFiles)
524 }
525 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
526 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
527 module, testCase.overlayFiles[module], overlayFiles)
528 }
529 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +0000530 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossbec85302019-02-13 13:15:46 -0800531 module, testCase.rroDirs[module], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +0000532 }
Colin Cross890ff552017-11-30 20:13:19 -0800533 }
Colin Cross890ff552017-11-30 20:13:19 -0800534 })
535 }
536}
Colin Crossd09b0b62018-04-18 11:06:47 -0700537
538func TestAppSdkVersion(t *testing.T) {
539 testCases := []struct {
540 name string
541 sdkVersion string
542 platformSdkInt int
543 platformSdkCodename string
544 platformSdkFinal bool
545 expectedMinSdkVersion string
546 }{
547 {
548 name: "current final SDK",
549 sdkVersion: "current",
550 platformSdkInt: 27,
551 platformSdkCodename: "REL",
552 platformSdkFinal: true,
553 expectedMinSdkVersion: "27",
554 },
555 {
556 name: "current non-final SDK",
557 sdkVersion: "current",
558 platformSdkInt: 27,
559 platformSdkCodename: "OMR1",
560 platformSdkFinal: false,
561 expectedMinSdkVersion: "OMR1",
562 },
563 {
564 name: "default final SDK",
565 sdkVersion: "",
566 platformSdkInt: 27,
567 platformSdkCodename: "REL",
568 platformSdkFinal: true,
569 expectedMinSdkVersion: "27",
570 },
571 {
572 name: "default non-final SDK",
573 sdkVersion: "",
574 platformSdkInt: 27,
575 platformSdkCodename: "OMR1",
576 platformSdkFinal: false,
577 expectedMinSdkVersion: "OMR1",
578 },
579 {
580 name: "14",
581 sdkVersion: "14",
582 expectedMinSdkVersion: "14",
583 },
584 }
585
586 for _, moduleType := range []string{"android_app", "android_library"} {
587 for _, test := range testCases {
588 t.Run(moduleType+" "+test.name, func(t *testing.T) {
589 bp := fmt.Sprintf(`%s {
590 name: "foo",
591 srcs: ["a.java"],
592 sdk_version: "%s",
593 }`, moduleType, test.sdkVersion)
594
595 config := testConfig(nil)
596 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
597 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
598 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
599
600 ctx := testAppContext(config, bp, nil)
601
602 run(t, ctx, config)
603
604 foo := ctx.ModuleForTests("foo", "android_common")
605 link := foo.Output("package-res.apk")
606 linkFlags := strings.Split(link.Args["flags"], " ")
607 min := android.IndexList("--min-sdk-version", linkFlags)
608 target := android.IndexList("--target-sdk-version", linkFlags)
609
610 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
611 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
612 }
613
614 gotMinSdkVersion := linkFlags[min+1]
615 gotTargetSdkVersion := linkFlags[target+1]
616
617 if gotMinSdkVersion != test.expectedMinSdkVersion {
618 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
619 test.expectedMinSdkVersion, gotMinSdkVersion)
620 }
621
622 if gotTargetSdkVersion != test.expectedMinSdkVersion {
623 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
624 test.expectedMinSdkVersion, gotTargetSdkVersion)
625 }
626 })
627 }
628 }
629}
Colin Crossa4f08812018-10-02 22:03:40 -0700630
Colin Cross47fa9d32019-03-26 10:51:39 -0700631func TestJNIABI(t *testing.T) {
632 ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Colin Crossa4f08812018-10-02 22:03:40 -0700633 cc_library {
634 name: "libjni",
635 system_shared_libs: [],
636 stl: "none",
637 }
638
639 android_test {
640 name: "test",
641 no_framework_libs: true,
642 jni_libs: ["libjni"],
643 }
644
645 android_test {
646 name: "test_first",
647 no_framework_libs: true,
648 compile_multilib: "first",
649 jni_libs: ["libjni"],
650 }
651
652 android_test {
653 name: "test_both",
654 no_framework_libs: true,
655 compile_multilib: "both",
656 jni_libs: ["libjni"],
657 }
658
659 android_test {
660 name: "test_32",
661 no_framework_libs: true,
662 compile_multilib: "32",
663 jni_libs: ["libjni"],
664 }
665
666 android_test {
667 name: "test_64",
668 no_framework_libs: true,
669 compile_multilib: "64",
670 jni_libs: ["libjni"],
671 }
672 `)
673
Colin Crossa4f08812018-10-02 22:03:40 -0700674 testCases := []struct {
675 name string
676 abis []string
677 }{
678 {"test", []string{"arm64-v8a"}},
679 {"test_first", []string{"arm64-v8a"}},
680 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
681 {"test_32", []string{"armeabi-v7a"}},
682 {"test_64", []string{"arm64-v8a"}},
683 }
684
685 for _, test := range testCases {
686 t.Run(test.name, func(t *testing.T) {
687 app := ctx.ModuleForTests(test.name, "android_common")
688 jniLibZip := app.Output("jnilibs.zip")
689 var abis []string
690 args := strings.Fields(jniLibZip.Args["jarArgs"])
691 for i := 0; i < len(args); i++ {
692 if args[i] == "-P" {
693 abis = append(abis, filepath.Base(args[i+1]))
694 i++
695 }
696 }
697 if !reflect.DeepEqual(abis, test.abis) {
698 t.Errorf("want abis %v, got %v", test.abis, abis)
699 }
700 })
701 }
702}
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800703
Colin Cross47fa9d32019-03-26 10:51:39 -0700704func TestJNIPackaging(t *testing.T) {
705 ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
706 cc_library {
707 name: "libjni",
708 system_shared_libs: [],
709 stl: "none",
710 }
711
712 android_app {
713 name: "app",
714 jni_libs: ["libjni"],
715 }
716
717 android_app {
718 name: "app_noembed",
719 jni_libs: ["libjni"],
720 use_embedded_native_libs: false,
721 }
722
723 android_app {
724 name: "app_embed",
725 jni_libs: ["libjni"],
726 use_embedded_native_libs: true,
727 }
728
729 android_test {
730 name: "test",
731 no_framework_libs: true,
732 jni_libs: ["libjni"],
733 }
734
735 android_test {
736 name: "test_noembed",
737 no_framework_libs: true,
738 jni_libs: ["libjni"],
739 use_embedded_native_libs: false,
740 }
741
742 android_test_helper_app {
743 name: "test_helper",
744 no_framework_libs: true,
745 jni_libs: ["libjni"],
746 }
747
748 android_test_helper_app {
749 name: "test_helper_noembed",
750 no_framework_libs: true,
751 jni_libs: ["libjni"],
752 use_embedded_native_libs: false,
753 }
754 `)
755
756 testCases := []struct {
757 name string
758 packaged bool
759 compressed bool
760 }{
761 {"app", false, false},
762 {"app_noembed", false, false},
763 {"app_embed", true, false},
764 {"test", true, false},
765 {"test_noembed", true, true},
766 {"test_helper", true, false},
767 {"test_helper_noembed", true, true},
768 }
769
770 for _, test := range testCases {
771 t.Run(test.name, func(t *testing.T) {
772 app := ctx.ModuleForTests(test.name, "android_common")
773 jniLibZip := app.MaybeOutput("jnilibs.zip")
774 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
775 t.Errorf("expected jni packaged %v, got %v", w, g)
776 }
777
778 if jniLibZip.Rule != nil {
779 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
780 t.Errorf("expected jni compressed %v, got %v", w, g)
781 }
782 }
783 })
784 }
785
786}
787
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800788func TestCertificates(t *testing.T) {
789 testCases := []struct {
790 name string
791 bp string
792 certificateOverride string
793 expected string
794 }{
795 {
796 name: "default",
797 bp: `
798 android_app {
799 name: "foo",
800 srcs: ["a.java"],
801 }
802 `,
803 certificateOverride: "",
804 expected: "build/target/product/security/testkey.x509.pem build/target/product/security/testkey.pk8",
805 },
806 {
807 name: "module certificate property",
808 bp: `
809 android_app {
810 name: "foo",
811 srcs: ["a.java"],
812 certificate: ":new_certificate"
813 }
814
815 android_app_certificate {
816 name: "new_certificate",
817 certificate: "cert/new_cert",
818 }
819 `,
820 certificateOverride: "",
821 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
822 },
823 {
824 name: "path certificate property",
825 bp: `
826 android_app {
827 name: "foo",
828 srcs: ["a.java"],
829 certificate: "expiredkey"
830 }
831 `,
832 certificateOverride: "",
833 expected: "build/target/product/security/expiredkey.x509.pem build/target/product/security/expiredkey.pk8",
834 },
835 {
836 name: "certificate overrides",
837 bp: `
838 android_app {
839 name: "foo",
840 srcs: ["a.java"],
841 certificate: "expiredkey"
842 }
843
844 android_app_certificate {
845 name: "new_certificate",
846 certificate: "cert/new_cert",
847 }
848 `,
849 certificateOverride: "foo:new_certificate",
850 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
851 },
852 }
853
854 for _, test := range testCases {
855 t.Run(test.name, func(t *testing.T) {
856 config := testConfig(nil)
857 if test.certificateOverride != "" {
858 config.TestProductVariables.CertificateOverrides = []string{test.certificateOverride}
859 }
860 ctx := testAppContext(config, test.bp, nil)
861
862 run(t, ctx, config)
863 foo := ctx.ModuleForTests("foo", "android_common")
864
865 signapk := foo.Output("foo.apk")
866 signFlags := signapk.Args["certificates"]
867 if test.expected != signFlags {
868 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
869 }
870 })
871 }
872}
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800873
874func TestPackageNameOverride(t *testing.T) {
875 testCases := []struct {
876 name string
877 bp string
878 packageNameOverride string
879 expected []string
880 }{
881 {
882 name: "default",
883 bp: `
884 android_app {
885 name: "foo",
886 srcs: ["a.java"],
887 }
888 `,
889 packageNameOverride: "",
890 expected: []string{
891 buildDir + "/.intermediates/foo/android_common/foo.apk",
892 buildDir + "/target/product/test_device/system/app/foo/foo.apk",
893 },
894 },
895 {
896 name: "overridden",
897 bp: `
898 android_app {
899 name: "foo",
900 srcs: ["a.java"],
901 }
902 `,
903 packageNameOverride: "foo:bar",
904 expected: []string{
905 // The package apk should be still be the original name for test dependencies.
906 buildDir + "/.intermediates/foo/android_common/foo.apk",
907 buildDir + "/target/product/test_device/system/app/bar/bar.apk",
908 },
909 },
910 }
911
912 for _, test := range testCases {
913 t.Run(test.name, func(t *testing.T) {
914 config := testConfig(nil)
915 if test.packageNameOverride != "" {
916 config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
917 }
918 ctx := testAppContext(config, test.bp, nil)
919
920 run(t, ctx, config)
921 foo := ctx.ModuleForTests("foo", "android_common")
922
923 outputs := foo.AllOutputs()
924 outputMap := make(map[string]bool)
925 for _, o := range outputs {
926 outputMap[o] = true
927 }
928 for _, e := range test.expected {
929 if _, exist := outputMap[e]; !exist {
930 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
931 }
932 }
933 })
934 }
935}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800936
937func TestInstrumentationTargetOverridden(t *testing.T) {
938 bp := `
939 android_app {
940 name: "foo",
941 srcs: ["a.java"],
942 }
943
944 android_test {
945 name: "bar",
946 instrumentation_for: "foo",
947 }
948 `
949 config := testConfig(nil)
950 config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
951 ctx := testAppContext(config, bp, nil)
952
953 run(t, ctx, config)
954
955 bar := ctx.ModuleForTests("bar", "android_common")
956 res := bar.Output("package-res.apk")
957 aapt2Flags := res.Args["flags"]
958 e := "--rename-instrumentation-target-package org.dandroid.bp"
959 if !strings.Contains(aapt2Flags, e) {
960 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
961 }
962}
Jaewoong Jung525443a2019-02-28 15:35:54 -0800963
964func TestOverrideAndroidApp(t *testing.T) {
965 ctx := testJava(t, `
966 android_app {
967 name: "foo",
968 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -0700969 certificate: "expiredkey",
Jaewoong Jung525443a2019-02-28 15:35:54 -0800970 overrides: ["baz"],
971 }
972
973 override_android_app {
974 name: "bar",
975 base: "foo",
976 certificate: ":new_certificate",
977 }
978
979 android_app_certificate {
980 name: "new_certificate",
981 certificate: "cert/new_cert",
982 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700983
984 override_android_app {
985 name: "baz",
986 base: "foo",
987 package_name: "org.dandroid.bp",
988 }
Jaewoong Jung525443a2019-02-28 15:35:54 -0800989 `)
990
991 expectedVariants := []struct {
992 variantName string
993 apkName string
994 apkPath string
995 signFlag string
996 overrides []string
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700997 aaptFlag string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800998 }{
999 {
1000 variantName: "android_common",
1001 apkPath: "/target/product/test_device/system/app/foo/foo.apk",
Jaewoong Junga641ee92019-03-27 11:17:14 -07001002 signFlag: "build/target/product/security/expiredkey.x509.pem build/target/product/security/expiredkey.pk8",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001003 overrides: []string{"baz"},
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001004 aaptFlag: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001005 },
1006 {
1007 variantName: "bar_android_common",
1008 apkPath: "/target/product/test_device/system/app/bar/bar.apk",
1009 signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
1010 overrides: []string{"baz", "foo"},
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001011 aaptFlag: "",
1012 },
1013 {
1014 variantName: "baz_android_common",
1015 apkPath: "/target/product/test_device/system/app/baz/baz.apk",
Jaewoong Junga641ee92019-03-27 11:17:14 -07001016 signFlag: "build/target/product/security/expiredkey.x509.pem build/target/product/security/expiredkey.pk8",
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001017 overrides: []string{"baz", "foo"},
1018 aaptFlag: "--rename-manifest-package org.dandroid.bp",
Jaewoong Jung525443a2019-02-28 15:35:54 -08001019 },
1020 }
1021 for _, expected := range expectedVariants {
1022 variant := ctx.ModuleForTests("foo", expected.variantName)
1023
1024 // Check the final apk name
1025 outputs := variant.AllOutputs()
1026 expectedApkPath := buildDir + expected.apkPath
1027 found := false
1028 for _, o := range outputs {
1029 if o == expectedApkPath {
1030 found = true
1031 break
1032 }
1033 }
1034 if !found {
1035 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
1036 }
1037
1038 // Check the certificate paths
1039 signapk := variant.Output("foo.apk")
1040 signFlag := signapk.Args["certificates"]
1041 if expected.signFlag != signFlag {
1042 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.signFlag, signFlag)
1043 }
1044
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001045 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -08001046 mod := variant.Module().(*AndroidApp)
1047 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
1048 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
1049 expected.overrides, mod.appProperties.Overrides)
1050 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -07001051
1052 // Check the package renaming flag, if exists.
1053 res := variant.Output("package-res.apk")
1054 aapt2Flags := res.Args["flags"]
1055 if !strings.Contains(aapt2Flags, expected.aaptFlag) {
1056 t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", expected.aaptFlag, aapt2Flags)
1057 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001058 }
1059}
Jaewoong Jung5c6572e2019-06-17 17:40:56 -07001060
1061func TestEmbedNotice(t *testing.T) {
1062 ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
1063 android_app {
1064 name: "foo",
1065 srcs: ["a.java"],
1066 static_libs: ["javalib"],
1067 jni_libs: ["libjni"],
1068 notice: "APP_NOTICE",
1069 embed_notices: true,
1070 }
1071
1072 // No embed_notice flag
1073 android_app {
1074 name: "bar",
1075 srcs: ["a.java"],
1076 jni_libs: ["libjni"],
1077 notice: "APP_NOTICE",
1078 }
1079
1080 // No NOTICE files
1081 android_app {
1082 name: "baz",
1083 srcs: ["a.java"],
1084 embed_notices: true,
1085 }
1086
1087 cc_library {
1088 name: "libjni",
1089 system_shared_libs: [],
1090 stl: "none",
1091 notice: "LIB_NOTICE",
1092 }
1093
1094 java_library {
1095 name: "javalib",
1096 srcs: [
1097 ":gen",
1098 ],
1099 }
1100
1101 genrule {
1102 name: "gen",
1103 tools: ["gentool"],
1104 out: ["gen.java"],
1105 notice: "GENRULE_NOTICE",
1106 }
1107
1108 java_binary_host {
1109 name: "gentool",
1110 srcs: ["b.java"],
1111 notice: "TOOL_NOTICE",
1112 }
1113 `)
1114
1115 // foo has NOTICE files to process, and embed_notices is true.
1116 foo := ctx.ModuleForTests("foo", "android_common")
1117 // verify merge notices rule.
1118 mergeNotices := foo.Rule("mergeNoticesRule")
1119 noticeInputs := mergeNotices.Inputs.Strings()
1120 // TOOL_NOTICE should be excluded as it's a host module.
1121 if len(mergeNotices.Inputs) != 3 {
1122 t.Errorf("number of input notice files: expected = 3, actual = %q", noticeInputs)
1123 }
1124 if !inList("APP_NOTICE", noticeInputs) {
1125 t.Errorf("APP_NOTICE is missing from notice files, %q", noticeInputs)
1126 }
1127 if !inList("LIB_NOTICE", noticeInputs) {
1128 t.Errorf("LIB_NOTICE is missing from notice files, %q", noticeInputs)
1129 }
1130 if !inList("GENRULE_NOTICE", noticeInputs) {
1131 t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs)
1132 }
1133 // aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets.
1134 res := foo.Output("package-res.apk")
1135 aapt2Flags := res.Args["flags"]
1136 e := "-A " + buildDir + "/.intermediates/foo/android_common/NOTICE"
1137 if !strings.Contains(aapt2Flags, e) {
1138 t.Errorf("asset dir flag for NOTICE, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
1139 }
1140
1141 // bar has NOTICE files to process, but embed_notices is not set.
1142 bar := ctx.ModuleForTests("bar", "android_common")
1143 mergeNotices = bar.MaybeRule("mergeNoticesRule")
1144 if mergeNotices.Rule != nil {
1145 t.Errorf("mergeNotices shouldn't have run for bar")
1146 }
1147
1148 // baz's embed_notice is true, but it doesn't have any NOTICE files.
1149 baz := ctx.ModuleForTests("baz", "android_common")
1150 mergeNotices = baz.MaybeRule("mergeNoticesRule")
1151 if mergeNotices.Rule != nil {
1152 t.Errorf("mergeNotices shouldn't have run for baz")
1153 }
1154}
Colin Cross43377ee2019-06-25 13:35:30 -07001155
1156func TestUncompressDex(t *testing.T) {
1157 testCases := []struct {
1158 name string
1159 bp string
1160
1161 uncompressedPlatform bool
1162 uncompressedUnbundled bool
1163 }{
1164 {
1165 name: "normal",
1166 bp: `
1167 android_app {
1168 name: "foo",
1169 srcs: ["a.java"],
1170 }
1171 `,
1172 uncompressedPlatform: true,
1173 uncompressedUnbundled: false,
1174 },
1175 {
1176 name: "use_embedded_dex",
1177 bp: `
1178 android_app {
1179 name: "foo",
1180 use_embedded_dex: true,
1181 srcs: ["a.java"],
1182 }
1183 `,
1184 uncompressedPlatform: true,
1185 uncompressedUnbundled: true,
1186 },
1187 {
1188 name: "privileged",
1189 bp: `
1190 android_app {
1191 name: "foo",
1192 privileged: true,
1193 srcs: ["a.java"],
1194 }
1195 `,
1196 uncompressedPlatform: true,
1197 uncompressedUnbundled: true,
1198 },
1199 }
1200
1201 test := func(t *testing.T, bp string, want bool, unbundled bool) {
1202 t.Helper()
1203
1204 config := testConfig(nil)
1205 if unbundled {
1206 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
1207 }
1208
1209 ctx := testAppContext(config, bp, nil)
1210
1211 run(t, ctx, config)
1212
1213 foo := ctx.ModuleForTests("foo", "android_common")
1214 dex := foo.Rule("r8")
1215 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
1216 aligned := foo.MaybeRule("zipalign").Rule != nil
1217
1218 if uncompressedInDexJar != want {
1219 t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar)
1220 }
1221
1222 if aligned != want {
1223 t.Errorf("want aligned %v, got %v", want, aligned)
1224 }
1225 }
1226
1227 for _, tt := range testCases {
1228 t.Run(tt.name, func(t *testing.T) {
1229 t.Run("platform", func(t *testing.T) {
1230 test(t, tt.bp, tt.uncompressedPlatform, false)
1231 })
1232 t.Run("unbundled", func(t *testing.T) {
1233 test(t, tt.bp, tt.uncompressedUnbundled, true)
1234 })
1235 })
1236 }
1237}