• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 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	"reflect"
19	"strings"
20	"testing"
21
22	"android/soong/android"
23	"android/soong/shared"
24)
25
26func TestRuntimeResourceOverlay(t *testing.T) {
27	t.Parallel()
28	fs := android.MockFS{
29		"baz/res/res/values/strings.xml": nil,
30		"bar/res/res/values/strings.xml": nil,
31	}
32	bp := `
33		runtime_resource_overlay {
34			name: "foo",
35			certificate: "platform",
36			lineage: "lineage.bin",
37			rotationMinSdkVersion: "32",
38			product_specific: true,
39			static_libs: ["bar"],
40			resource_libs: ["baz"],
41			aaptflags: ["--keep-raw-values"],
42		}
43
44		runtime_resource_overlay {
45			name: "foo_themed",
46			certificate: "platform",
47			product_specific: true,
48			theme: "faza",
49			overrides: ["foo"],
50		}
51
52		android_library {
53			name: "bar",
54			resource_dirs: ["bar/res"],
55		}
56
57		android_app {
58			name: "baz",
59			sdk_version: "current",
60			resource_dirs: ["baz/res"],
61		}
62	`
63
64	result := android.GroupFixturePreparers(
65		PrepareForTestWithJavaDefaultModules,
66		android.FixtureModifyConfig(android.SetKatiEnabledForTests),
67		fs.AddToFixture(),
68	).RunTestWithBp(t, bp)
69
70	m := result.ModuleForTests(t, "foo", "android_common")
71
72	// Check AAPT2 link flags.
73	aapt2Flags := m.Output("package-res.apk").Args["flags"]
74	expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
75	absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
76	if len(absentFlags) > 0 {
77		t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
78	}
79
80	// Check overlay.list output for static_libs dependency.
81	overlayList := android.PathsRelativeToTop(m.Output("aapt2/overlay.list").Inputs)
82	staticLibPackage := "out/soong/.intermediates/bar/android_common/package-res.apk"
83	if !inList(staticLibPackage, overlayList) {
84		t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
85	}
86
87	// Check AAPT2 link flags for resource_libs dependency.
88	resourceLibFlag := "-I " + "out/soong/.intermediates/baz/android_common/package-res.apk"
89	if !strings.Contains(aapt2Flags, resourceLibFlag) {
90		t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
91	}
92
93	// Check cert signing flags.
94	signedApk := m.Output("signed/foo.apk")
95	actualCertSigningFlags := signedApk.Args["flags"]
96	expectedCertSigningFlags := "--lineage lineage.bin --rotation-min-sdk-version 32"
97	if expectedCertSigningFlags != actualCertSigningFlags {
98		t.Errorf("Incorrect cert signing flags, expected: %q, got: %q", expectedCertSigningFlags, actualCertSigningFlags)
99	}
100
101	signingFlag := signedApk.Args["certificates"]
102	expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
103	if expected != signingFlag {
104		t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
105	}
106	androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
107	path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
108	expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
109	if !reflect.DeepEqual(path, expectedPath) {
110		t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
111	}
112
113	// Check device location.
114	path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
115	expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
116	android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
117
118	// A themed module has a different device location
119	m = result.ModuleForTests(t, "foo_themed", "android_common")
120	androidMkEntries = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
121	path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
122	expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay/faza")}
123	android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
124
125	overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
126	expectedOverrides := []string{"foo"}
127	if !reflect.DeepEqual(overrides, expectedOverrides) {
128		t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
129	}
130}
131
132func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
133	t.Parallel()
134	result := android.GroupFixturePreparers(
135		PrepareForTestWithJavaDefaultModules,
136		android.FixtureModifyConfig(android.SetKatiEnabledForTests),
137	).RunTestWithBp(t, `
138		java_defaults {
139			name: "rro_defaults",
140			theme: "default_theme",
141			product_specific: true,
142			aaptflags: ["--keep-raw-values"],
143		}
144
145		runtime_resource_overlay {
146			name: "foo_with_defaults",
147			defaults: ["rro_defaults"],
148		}
149
150		runtime_resource_overlay {
151			name: "foo_barebones",
152		}
153		`)
154
155	//
156	// RRO module with defaults
157	//
158	m := result.ModuleForTests(t, "foo_with_defaults", "android_common")
159
160	// Check AAPT2 link flags.
161	aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
162	expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
163	absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
164	if len(absentFlags) > 0 {
165		t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
166	}
167
168	// Check device location.
169	path := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
170	expectedPath := []string{shared.JoinPath("out/target/product/test_device/product/overlay/default_theme")}
171	android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
172
173	//
174	// RRO module without defaults
175	//
176	m = result.ModuleForTests(t, "foo_barebones", "android_common")
177
178	// Check AAPT2 link flags.
179	aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
180	unexpectedFlags := "--keep-raw-values"
181	if inList(unexpectedFlags, aapt2Flags) {
182		t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
183	}
184
185	// Check device location.
186	path = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
187	expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
188	android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
189}
190
191func TestOverrideRuntimeResourceOverlay(t *testing.T) {
192	ctx, _ := testJava(t, `
193		runtime_resource_overlay {
194			name: "foo_overlay",
195			certificate: "platform",
196			product_specific: true,
197			sdk_version: "current",
198		}
199
200		override_runtime_resource_overlay {
201			name: "bar_overlay",
202			base: "foo_overlay",
203			package_name: "com.android.bar.overlay",
204			target_package_name: "com.android.bar",
205			category: "mycategory",
206		}
207		`)
208
209	expectedVariants := []struct {
210		moduleName        string
211		variantName       string
212		apkPath           string
213		overrides         []string
214		targetVariant     string
215		packageFlag       string
216		targetPackageFlag string
217		categoryFlag      string
218	}{
219		{
220			variantName:       "android_common",
221			apkPath:           "out/target/product/test_device/product/overlay/foo_overlay.apk",
222			overrides:         nil,
223			targetVariant:     "android_common",
224			packageFlag:       "",
225			targetPackageFlag: "",
226		},
227		{
228			variantName:       "android_common_bar_overlay",
229			apkPath:           "out/target/product/test_device/product/overlay/bar_overlay.apk",
230			overrides:         []string{"foo_overlay"},
231			targetVariant:     "android_common_bar",
232			packageFlag:       "com.android.bar.overlay",
233			targetPackageFlag: "com.android.bar",
234			categoryFlag:      "mycategory",
235		},
236	}
237	for _, expected := range expectedVariants {
238		variant := ctx.ModuleForTests(t, "foo_overlay", expected.variantName)
239
240		// Check the final apk name
241		variant.Output(expected.apkPath)
242
243		// Check if the overrides field values are correctly aggregated.
244		mod := variant.Module().(*RuntimeResourceOverlay)
245		if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
246			t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
247				expected.overrides, mod.properties.Overrides)
248		}
249
250		// Check aapt2 flags.
251		res := variant.Output("package-res.apk")
252		aapt2Flags := res.Args["flags"]
253		checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
254		checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
255		checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
256		checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-category", expected.categoryFlag)
257	}
258}
259
260func TestRuntimeResourceOverlayPartition(t *testing.T) {
261	bp := `
262		runtime_resource_overlay {
263			name: "device_specific",
264			device_specific: true,
265		}
266		runtime_resource_overlay {
267			name: "soc_specific",
268			soc_specific: true,
269		}
270		runtime_resource_overlay {
271			name: "system_ext_specific",
272			system_ext_specific: true,
273		}
274		runtime_resource_overlay {
275			name: "product_specific",
276			product_specific: true,
277		}
278		runtime_resource_overlay {
279			name: "default"
280		}
281	`
282	testCases := []struct {
283		name         string
284		expectedPath string
285	}{
286		{
287			name:         "device_specific",
288			expectedPath: "out/target/product/test_device/odm/overlay",
289		},
290		{
291			name:         "soc_specific",
292			expectedPath: "out/target/product/test_device/vendor/overlay",
293		},
294		{
295			name:         "system_ext_specific",
296			expectedPath: "out/target/product/test_device/system_ext/overlay",
297		},
298		{
299			name:         "product_specific",
300			expectedPath: "out/target/product/test_device/product/overlay",
301		},
302		{
303			name:         "default",
304			expectedPath: "out/target/product/test_device/product/overlay",
305		},
306	}
307	for _, testCase := range testCases {
308		ctx, _ := testJava(t, bp)
309		mod := ctx.ModuleForTests(t, testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
310		android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
311	}
312}
313
314func TestRuntimeResourceOverlayFlagsPackages(t *testing.T) {
315	result := android.GroupFixturePreparers(
316		prepareForJavaTest,
317	).RunTestWithBp(t, `
318		runtime_resource_overlay {
319			name: "foo",
320			sdk_version: "current",
321			flags_packages: [
322				"bar",
323				"baz",
324			],
325		}
326		aconfig_declarations {
327			name: "bar",
328			package: "com.example.package.bar",
329			container: "com.android.foo",
330			srcs: [
331				"bar.aconfig",
332			],
333		}
334		aconfig_declarations {
335			name: "baz",
336			package: "com.example.package.baz",
337			container: "com.android.foo",
338			srcs: [
339				"baz.aconfig",
340			],
341		}
342	`)
343
344	foo := result.ModuleForTests(t, "foo", "android_common")
345
346	// runtime_resource_overlay module depends on aconfig_declarations listed in flags_packages
347	android.AssertBoolEquals(t, "foo expected to depend on bar", true,
348		CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"))
349
350	android.AssertBoolEquals(t, "foo expected to depend on baz", true,
351		CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "baz"))
352
353	aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
354	linkInFlags := aapt2LinkRule.Args["inFlags"]
355	android.AssertStringDoesContain(t,
356		"aapt2 link command expected to pass feature flags arguments",
357		linkInFlags,
358		"--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
359	)
360}
361
362func TestCanBeDataOfTest(t *testing.T) {
363	android.GroupFixturePreparers(
364		prepareForJavaTest,
365	).RunTestWithBp(t, `
366		runtime_resource_overlay {
367			name: "foo",
368			sdk_version: "current",
369		}
370		android_test {
371			name: "bar",
372			data: [
373				":foo",
374			],
375		}
376	`)
377	// Just test that this doesn't get errors
378}
379