1// Copyright 2018 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 apex
16
17import (
18	"io/ioutil"
19	"os"
20	"path"
21	"reflect"
22	"regexp"
23	"sort"
24	"strings"
25	"testing"
26
27	"github.com/google/blueprint/proptools"
28
29	"android/soong/android"
30	"android/soong/cc"
31	"android/soong/dexpreopt"
32	prebuilt_etc "android/soong/etc"
33	"android/soong/java"
34	"android/soong/sh"
35)
36
37var buildDir string
38
39// names returns name list from white space separated string
40func names(s string) (ns []string) {
41	for _, n := range strings.Split(s, " ") {
42		if len(n) > 0 {
43			ns = append(ns, n)
44		}
45	}
46	return
47}
48
49func testApexError(t *testing.T, pattern, bp string, handlers ...testCustomizer) {
50	t.Helper()
51	ctx, config := testApexContext(t, bp, handlers...)
52	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
53	if len(errs) > 0 {
54		android.FailIfNoMatchingErrors(t, pattern, errs)
55		return
56	}
57	_, errs = ctx.PrepareBuildActions(config)
58	if len(errs) > 0 {
59		android.FailIfNoMatchingErrors(t, pattern, errs)
60		return
61	}
62
63	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
64}
65
66func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
67	t.Helper()
68	ctx, config := testApexContext(t, bp, handlers...)
69	_, errs := ctx.ParseBlueprintsFiles(".")
70	android.FailIfErrored(t, errs)
71	_, errs = ctx.PrepareBuildActions(config)
72	android.FailIfErrored(t, errs)
73	return ctx, config
74}
75
76type testCustomizer func(fs map[string][]byte, config android.Config)
77
78func withFiles(files map[string][]byte) testCustomizer {
79	return func(fs map[string][]byte, config android.Config) {
80		for k, v := range files {
81			fs[k] = v
82		}
83	}
84}
85
86func withTargets(targets map[android.OsType][]android.Target) testCustomizer {
87	return func(fs map[string][]byte, config android.Config) {
88		for k, v := range targets {
89			config.Targets[k] = v
90		}
91	}
92}
93
94// withNativeBridgeTargets sets configuration with targets including:
95// - X86_64 (primary)
96// - X86 (secondary)
97// - Arm64 on X86_64 (native bridge)
98// - Arm on X86 (native bridge)
99func withNativeBridgeEnabled(_ map[string][]byte, config android.Config) {
100	config.Targets[android.Android] = []android.Target{
101		{Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}},
102			NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
103		{Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}},
104			NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
105		{Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}},
106			NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86_64", NativeBridgeRelativePath: "arm64"},
107		{Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
108			NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86", NativeBridgeRelativePath: "arm"},
109	}
110}
111
112func withManifestPackageNameOverrides(specs []string) testCustomizer {
113	return func(fs map[string][]byte, config android.Config) {
114		config.TestProductVariables.ManifestPackageNameOverrides = specs
115	}
116}
117
118func withBinder32bit(_ map[string][]byte, config android.Config) {
119	config.TestProductVariables.Binder32bit = proptools.BoolPtr(true)
120}
121
122func withUnbundledBuild(_ map[string][]byte, config android.Config) {
123	config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
124}
125
126func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
127	android.ClearApexDependency()
128
129	bp = bp + `
130		filegroup {
131			name: "myapex-file_contexts",
132			srcs: [
133				"system/sepolicy/apex/myapex-file_contexts",
134			],
135		}
136	`
137
138	bp = bp + cc.GatherRequiredDepsForTest(android.Android)
139
140	bp = bp + java.GatherRequiredDepsForTest()
141
142	fs := map[string][]byte{
143		"a.java":                                              nil,
144		"PrebuiltAppFoo.apk":                                  nil,
145		"PrebuiltAppFooPriv.apk":                              nil,
146		"build/make/target/product/security":                  nil,
147		"apex_manifest.json":                                  nil,
148		"AndroidManifest.xml":                                 nil,
149		"system/sepolicy/apex/myapex-file_contexts":           nil,
150		"system/sepolicy/apex/myapex.updatable-file_contexts": nil,
151		"system/sepolicy/apex/myapex2-file_contexts":          nil,
152		"system/sepolicy/apex/otherapex-file_contexts":        nil,
153		"system/sepolicy/apex/commonapex-file_contexts":       nil,
154		"system/sepolicy/apex/com.android.vndk-file_contexts": nil,
155		"mylib.cpp":                                  nil,
156		"mylib_common.cpp":                           nil,
157		"mytest.cpp":                                 nil,
158		"mytest1.cpp":                                nil,
159		"mytest2.cpp":                                nil,
160		"mytest3.cpp":                                nil,
161		"myprebuilt":                                 nil,
162		"my_include":                                 nil,
163		"foo/bar/MyClass.java":                       nil,
164		"prebuilt.jar":                               nil,
165		"prebuilt.so":                                nil,
166		"vendor/foo/devkeys/test.x509.pem":           nil,
167		"vendor/foo/devkeys/test.pk8":                nil,
168		"testkey.x509.pem":                           nil,
169		"testkey.pk8":                                nil,
170		"testkey.override.x509.pem":                  nil,
171		"testkey.override.pk8":                       nil,
172		"vendor/foo/devkeys/testkey.avbpubkey":       nil,
173		"vendor/foo/devkeys/testkey.pem":             nil,
174		"NOTICE":                                     nil,
175		"custom_notice":                              nil,
176		"custom_notice_for_static_lib":               nil,
177		"testkey2.avbpubkey":                         nil,
178		"testkey2.pem":                               nil,
179		"myapex-arm64.apex":                          nil,
180		"myapex-arm.apex":                            nil,
181		"myapex.apks":                                nil,
182		"frameworks/base/api/current.txt":            nil,
183		"framework/aidl/a.aidl":                      nil,
184		"build/make/core/proguard.flags":             nil,
185		"build/make/core/proguard_basic_keeps.flags": nil,
186		"dummy.txt":                                  nil,
187		"baz":                                        nil,
188		"bar/baz":                                    nil,
189		"testdata/baz":                               nil,
190		"AppSet.apks":                                nil,
191	}
192
193	cc.GatherRequiredFilesForTest(fs)
194
195	for _, handler := range handlers {
196		// The fs now needs to be populated before creating the config, call handlers twice
197		// for now, once to get any fs changes, and later after the config was created to
198		// set product variables or targets.
199		tempConfig := android.TestArchConfig(buildDir, nil, bp, fs)
200		handler(fs, tempConfig)
201	}
202
203	config := android.TestArchConfig(buildDir, nil, bp, fs)
204	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
205	config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
206	config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
207	config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q")
208	config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false)
209	config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
210	config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
211
212	for _, handler := range handlers {
213		// The fs now needs to be populated before creating the config, call handlers twice
214		// for now, earlier to get any fs changes, and now after the config was created to
215		// set product variables or targets.
216		tempFS := map[string][]byte{}
217		handler(tempFS, config)
218	}
219
220	ctx := android.NewTestArchContext()
221
222	// from android package
223	android.RegisterPackageBuildComponents(ctx)
224	ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
225
226	ctx.RegisterModuleType("apex", BundleFactory)
227	ctx.RegisterModuleType("apex_test", testApexBundleFactory)
228	ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
229	ctx.RegisterModuleType("apex_key", ApexKeyFactory)
230	ctx.RegisterModuleType("apex_defaults", defaultsFactory)
231	ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
232	ctx.RegisterModuleType("override_apex", overrideApexFactory)
233	ctx.RegisterModuleType("apex_set", apexSetFactory)
234
235	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
236	ctx.PreArchMutators(android.RegisterComponentsMutator)
237	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
238
239	android.RegisterPrebuiltMutators(ctx)
240
241	// Register these after the prebuilt mutators have been registered to match what
242	// happens at runtime.
243	ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
244	ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
245
246	cc.RegisterRequiredBuildComponentsForTest(ctx)
247
248	ctx.RegisterModuleType("cc_test", cc.TestFactory)
249	ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
250	ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory)
251	ctx.RegisterModuleType("prebuilt_etc", prebuilt_etc.PrebuiltEtcFactory)
252	ctx.RegisterModuleType("platform_compat_config", java.PlatformCompatConfigFactory)
253	ctx.RegisterModuleType("sh_binary", sh.ShBinaryFactory)
254	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
255	java.RegisterJavaBuildComponents(ctx)
256	java.RegisterSystemModulesBuildComponents(ctx)
257	java.RegisterAppBuildComponents(ctx)
258	java.RegisterSdkLibraryBuildComponents(ctx)
259	ctx.RegisterSingletonType("apex_keys_text", apexKeysTextFactory)
260
261	ctx.PreDepsMutators(RegisterPreDepsMutators)
262	ctx.PostDepsMutators(RegisterPostDepsMutators)
263
264	ctx.Register(config)
265
266	return ctx, config
267}
268
269func setUp() {
270	var err error
271	buildDir, err = ioutil.TempDir("", "soong_apex_test")
272	if err != nil {
273		panic(err)
274	}
275}
276
277func tearDown() {
278	_ = os.RemoveAll(buildDir)
279}
280
281// ensure that 'result' equals 'expected'
282func ensureEquals(t *testing.T, result string, expected string) {
283	t.Helper()
284	if result != expected {
285		t.Errorf("%q != %q", expected, result)
286	}
287}
288
289// ensure that 'result' contains 'expected'
290func ensureContains(t *testing.T, result string, expected string) {
291	t.Helper()
292	if !strings.Contains(result, expected) {
293		t.Errorf("%q is not found in %q", expected, result)
294	}
295}
296
297// ensure that 'result' contains 'expected' exactly one time
298func ensureContainsOnce(t *testing.T, result string, expected string) {
299	t.Helper()
300	count := strings.Count(result, expected)
301	if count != 1 {
302		t.Errorf("%q is found %d times (expected 1 time) in %q", expected, count, result)
303	}
304}
305
306// ensures that 'result' does not contain 'notExpected'
307func ensureNotContains(t *testing.T, result string, notExpected string) {
308	t.Helper()
309	if strings.Contains(result, notExpected) {
310		t.Errorf("%q is found in %q", notExpected, result)
311	}
312}
313
314func ensureMatches(t *testing.T, result string, expectedRex string) {
315	ok, err := regexp.MatchString(expectedRex, result)
316	if err != nil {
317		t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err)
318		return
319	}
320	if !ok {
321		t.Errorf("%s does not match regular expession %s", result, expectedRex)
322	}
323}
324
325func ensureListContains(t *testing.T, result []string, expected string) {
326	t.Helper()
327	if !android.InList(expected, result) {
328		t.Errorf("%q is not found in %v", expected, result)
329	}
330}
331
332func ensureListNotContains(t *testing.T, result []string, notExpected string) {
333	t.Helper()
334	if android.InList(notExpected, result) {
335		t.Errorf("%q is found in %v", notExpected, result)
336	}
337}
338
339func ensureListEmpty(t *testing.T, result []string) {
340	t.Helper()
341	if len(result) > 0 {
342		t.Errorf("%q is expected to be empty", result)
343	}
344}
345
346// Minimal test
347func TestBasicApex(t *testing.T) {
348	ctx, config := testApex(t, `
349		apex_defaults {
350			name: "myapex-defaults",
351			manifest: ":myapex.manifest",
352			androidManifest: ":myapex.androidmanifest",
353			key: "myapex.key",
354			native_shared_libs: ["mylib"],
355			multilib: {
356				both: {
357					binaries: ["foo",],
358				}
359			},
360			java_libs: [
361				"myjar",
362				"myjar_dex",
363			],
364		}
365
366		apex {
367			name: "myapex",
368			defaults: ["myapex-defaults"],
369		}
370
371		apex_key {
372			name: "myapex.key",
373			public_key: "testkey.avbpubkey",
374			private_key: "testkey.pem",
375		}
376
377		filegroup {
378			name: "myapex.manifest",
379			srcs: ["apex_manifest.json"],
380		}
381
382		filegroup {
383			name: "myapex.androidmanifest",
384			srcs: ["AndroidManifest.xml"],
385		}
386
387		cc_library {
388			name: "mylib",
389			srcs: ["mylib.cpp"],
390			shared_libs: ["mylib2"],
391			system_shared_libs: [],
392			stl: "none",
393			// TODO: remove //apex_available:platform
394			apex_available: [
395				"//apex_available:platform",
396				"myapex",
397			],
398		}
399
400		cc_binary {
401			name: "foo",
402			srcs: ["mylib.cpp"],
403			compile_multilib: "both",
404			multilib: {
405					lib32: {
406							suffix: "32",
407					},
408					lib64: {
409							suffix: "64",
410					},
411			},
412			symlinks: ["foo_link_"],
413			symlink_preferred_arch: true,
414			system_shared_libs: [],
415			static_executable: true,
416			stl: "none",
417			apex_available: [ "myapex" ],
418		}
419
420		cc_library_shared {
421			name: "mylib2",
422			srcs: ["mylib.cpp"],
423			system_shared_libs: [],
424			stl: "none",
425			notice: "custom_notice",
426			static_libs: ["libstatic"],
427			// TODO: remove //apex_available:platform
428			apex_available: [
429				"//apex_available:platform",
430				"myapex",
431			],
432		}
433
434		cc_prebuilt_library_shared {
435			name: "mylib2",
436			srcs: ["prebuilt.so"],
437			// TODO: remove //apex_available:platform
438			apex_available: [
439				"//apex_available:platform",
440				"myapex",
441			],
442    }
443
444		cc_library_static {
445			name: "libstatic",
446			srcs: ["mylib.cpp"],
447			system_shared_libs: [],
448			stl: "none",
449			notice: "custom_notice_for_static_lib",
450			// TODO: remove //apex_available:platform
451			apex_available: [
452				"//apex_available:platform",
453				"myapex",
454			],
455		}
456
457		java_library {
458			name: "myjar",
459			srcs: ["foo/bar/MyClass.java"],
460			stem: "myjar_stem",
461			sdk_version: "none",
462			system_modules: "none",
463			static_libs: ["myotherjar"],
464			libs: ["mysharedjar"],
465			// TODO: remove //apex_available:platform
466			apex_available: [
467				"//apex_available:platform",
468				"myapex",
469			],
470		}
471
472		dex_import {
473			name: "myjar_dex",
474			jars: ["prebuilt.jar"],
475			apex_available: [
476				"//apex_available:platform",
477				"myapex",
478			],
479		}
480
481		java_library {
482			name: "myotherjar",
483			srcs: ["foo/bar/MyClass.java"],
484			sdk_version: "none",
485			system_modules: "none",
486			// TODO: remove //apex_available:platform
487			apex_available: [
488				"//apex_available:platform",
489				"myapex",
490			],
491		}
492
493		java_library {
494			name: "mysharedjar",
495			srcs: ["foo/bar/MyClass.java"],
496			sdk_version: "none",
497			system_modules: "none",
498		}
499	`)
500
501	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
502
503	// Make sure that Android.mk is created
504	ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
505	data := android.AndroidMkDataForTest(t, config, "", ab)
506	var builder strings.Builder
507	data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
508
509	androidMk := builder.String()
510	ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
511	ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
512
513	optFlags := apexRule.Args["opt_flags"]
514	ensureContains(t, optFlags, "--pubkey vendor/foo/devkeys/testkey.avbpubkey")
515	// Ensure that the NOTICE output is being packaged as an asset.
516	ensureContains(t, optFlags, "--assets_dir "+buildDir+"/.intermediates/myapex/android_common_myapex_image/NOTICE")
517
518	copyCmds := apexRule.Args["copy_commands"]
519
520	// Ensure that main rule creates an output
521	ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
522
523	// Ensure that apex variant is created for the direct dep
524	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
525	ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_myapex")
526	ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_myapex")
527
528	// Ensure that apex variant is created for the indirect dep
529	ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
530	ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_myapex")
531
532	// Ensure that both direct and indirect deps are copied into apex
533	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
534	ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
535	ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
536	ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar")
537	// .. but not for java libs
538	ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
539	ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
540
541	// Ensure that the platform variant ends with _shared or _common
542	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared")
543	ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared")
544	ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common")
545	ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common")
546	ensureListContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common")
547
548	// Ensure that dynamic dependency to java libs are not included
549	ensureListNotContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common_myapex")
550
551	// Ensure that all symlinks are present.
552	found_foo_link_64 := false
553	found_foo := false
554	for _, cmd := range strings.Split(copyCmds, " && ") {
555		if strings.HasPrefix(cmd, "ln -sfn foo64") {
556			if strings.HasSuffix(cmd, "bin/foo") {
557				found_foo = true
558			} else if strings.HasSuffix(cmd, "bin/foo_link_64") {
559				found_foo_link_64 = true
560			}
561		}
562	}
563	good := found_foo && found_foo_link_64
564	if !good {
565		t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds)
566	}
567
568	mergeNoticesRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("mergeNoticesRule")
569	noticeInputs := mergeNoticesRule.Inputs.Strings()
570	if len(noticeInputs) != 3 {
571		t.Errorf("number of input notice files: expected = 3, actual = %q", len(noticeInputs))
572	}
573	ensureListContains(t, noticeInputs, "NOTICE")
574	ensureListContains(t, noticeInputs, "custom_notice")
575	ensureListContains(t, noticeInputs, "custom_notice_for_static_lib")
576
577	fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
578	ensureListContains(t, fullDepsInfo, "myjar(minSdkVersion:(no version)) <- myapex")
579	ensureListContains(t, fullDepsInfo, "mylib(minSdkVersion:(no version)) <- myapex")
580	ensureListContains(t, fullDepsInfo, "mylib2(minSdkVersion:(no version)) <- mylib")
581	ensureListContains(t, fullDepsInfo, "myotherjar(minSdkVersion:(no version)) <- myjar")
582	ensureListContains(t, fullDepsInfo, "mysharedjar(minSdkVersion:(no version)) (external) <- myjar")
583
584	flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
585	ensureListContains(t, flatDepsInfo, "  myjar(minSdkVersion:(no version))")
586	ensureListContains(t, flatDepsInfo, "  mylib(minSdkVersion:(no version))")
587	ensureListContains(t, flatDepsInfo, "  mylib2(minSdkVersion:(no version))")
588	ensureListContains(t, flatDepsInfo, "  myotherjar(minSdkVersion:(no version))")
589	ensureListContains(t, flatDepsInfo, "  mysharedjar(minSdkVersion:(no version)) (external)")
590}
591
592func TestDefaults(t *testing.T) {
593	ctx, _ := testApex(t, `
594		apex_defaults {
595			name: "myapex-defaults",
596			key: "myapex.key",
597			prebuilts: ["myetc"],
598			native_shared_libs: ["mylib"],
599			java_libs: ["myjar"],
600			apps: ["AppFoo"],
601			rros: ["rro"],
602		}
603
604		prebuilt_etc {
605			name: "myetc",
606			src: "myprebuilt",
607		}
608
609		apex {
610			name: "myapex",
611			defaults: ["myapex-defaults"],
612		}
613
614		apex_key {
615			name: "myapex.key",
616			public_key: "testkey.avbpubkey",
617			private_key: "testkey.pem",
618		}
619
620		cc_library {
621			name: "mylib",
622			system_shared_libs: [],
623			stl: "none",
624			apex_available: [ "myapex" ],
625		}
626
627		java_library {
628			name: "myjar",
629			srcs: ["foo/bar/MyClass.java"],
630			sdk_version: "none",
631			system_modules: "none",
632			apex_available: [ "myapex" ],
633		}
634
635		android_app {
636			name: "AppFoo",
637			srcs: ["foo/bar/MyClass.java"],
638			sdk_version: "none",
639			system_modules: "none",
640			apex_available: [ "myapex" ],
641		}
642
643		runtime_resource_overlay {
644			name: "rro",
645			theme: "blue",
646		}
647
648	`)
649	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
650		"etc/myetc",
651		"javalib/myjar.jar",
652		"lib64/mylib.so",
653		"app/AppFoo/AppFoo.apk",
654		"overlay/blue/rro.apk",
655	})
656}
657
658func TestApexManifest(t *testing.T) {
659	ctx, _ := testApex(t, `
660		apex {
661			name: "myapex",
662			key: "myapex.key",
663		}
664
665		apex_key {
666			name: "myapex.key",
667			public_key: "testkey.avbpubkey",
668			private_key: "testkey.pem",
669		}
670	`)
671
672	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
673	args := module.Rule("apexRule").Args
674	if manifest := args["manifest"]; manifest != module.Output("apex_manifest.pb").Output.String() {
675		t.Error("manifest should be apex_manifest.pb, but " + manifest)
676	}
677}
678
679func TestBasicZipApex(t *testing.T) {
680	ctx, _ := testApex(t, `
681		apex {
682			name: "myapex",
683			key: "myapex.key",
684			payload_type: "zip",
685			native_shared_libs: ["mylib"],
686		}
687
688		apex_key {
689			name: "myapex.key",
690			public_key: "testkey.avbpubkey",
691			private_key: "testkey.pem",
692		}
693
694		cc_library {
695			name: "mylib",
696			srcs: ["mylib.cpp"],
697			shared_libs: ["mylib2"],
698			system_shared_libs: [],
699			stl: "none",
700			apex_available: [ "myapex" ],
701		}
702
703		cc_library {
704			name: "mylib2",
705			srcs: ["mylib.cpp"],
706			system_shared_libs: [],
707			stl: "none",
708			apex_available: [ "myapex" ],
709		}
710	`)
711
712	zipApexRule := ctx.ModuleForTests("myapex", "android_common_myapex_zip").Rule("zipApexRule")
713	copyCmds := zipApexRule.Args["copy_commands"]
714
715	// Ensure that main rule creates an output
716	ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
717
718	// Ensure that APEX variant is created for the direct dep
719	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
720
721	// Ensure that APEX variant is created for the indirect dep
722	ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
723
724	// Ensure that both direct and indirect deps are copied into apex
725	ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
726	ensureContains(t, copyCmds, "image.zipapex/lib64/mylib2.so")
727}
728
729func TestApexWithStubs(t *testing.T) {
730	ctx, _ := testApex(t, `
731		apex {
732			name: "myapex",
733			key: "myapex.key",
734			native_shared_libs: ["mylib", "mylib3"],
735		}
736
737		apex_key {
738			name: "myapex.key",
739			public_key: "testkey.avbpubkey",
740			private_key: "testkey.pem",
741		}
742
743		cc_library {
744			name: "mylib",
745			srcs: ["mylib.cpp"],
746			shared_libs: ["mylib2", "mylib3"],
747			system_shared_libs: [],
748			stl: "none",
749			apex_available: [ "myapex" ],
750		}
751
752		cc_library {
753			name: "mylib2",
754			srcs: ["mylib.cpp"],
755			cflags: ["-include mylib.h"],
756			system_shared_libs: [],
757			stl: "none",
758			stubs: {
759				versions: ["1", "2", "3"],
760			},
761		}
762
763		cc_library {
764			name: "mylib3",
765			srcs: ["mylib.cpp"],
766			shared_libs: ["mylib4"],
767			system_shared_libs: [],
768			stl: "none",
769			stubs: {
770				versions: ["10", "11", "12"],
771			},
772			apex_available: [ "myapex" ],
773		}
774
775		cc_library {
776			name: "mylib4",
777			srcs: ["mylib.cpp"],
778			system_shared_libs: [],
779			stl: "none",
780			apex_available: [ "myapex" ],
781		}
782	`)
783
784	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
785	copyCmds := apexRule.Args["copy_commands"]
786
787	// Ensure that direct non-stubs dep is always included
788	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
789
790	// Ensure that indirect stubs dep is not included
791	ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
792
793	// Ensure that direct stubs dep is included
794	ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
795
796	mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
797
798	// Ensure that mylib is linking with the latest version of stubs for mylib2
799	ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3/mylib2.so")
800	// ... and not linking to the non-stub (impl) variant of mylib2
801	ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
802
803	// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
804	ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_myapex/mylib3.so")
805	// .. and not linking to the stubs variant of mylib3
806	ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12_myapex/mylib3.so")
807
808	// Ensure that stubs libs are built without -include flags
809	mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
810	ensureNotContains(t, mylib2Cflags, "-include ")
811
812	// Ensure that genstub is invoked with --apex
813	ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_3").Rule("genStubSrc").Args["flags"])
814
815	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
816		"lib64/mylib.so",
817		"lib64/mylib3.so",
818		"lib64/mylib4.so",
819	})
820}
821
822func TestApexWithExplicitStubsDependency(t *testing.T) {
823	ctx, _ := testApex(t, `
824		apex {
825			name: "myapex2",
826			key: "myapex2.key",
827			native_shared_libs: ["mylib"],
828		}
829
830		apex_key {
831			name: "myapex2.key",
832			public_key: "testkey.avbpubkey",
833			private_key: "testkey.pem",
834		}
835
836		cc_library {
837			name: "mylib",
838			srcs: ["mylib.cpp"],
839			shared_libs: ["libfoo#10"],
840			static_libs: ["libbaz"],
841			system_shared_libs: [],
842			stl: "none",
843			apex_available: [ "myapex2" ],
844		}
845
846		cc_library {
847			name: "libfoo",
848			srcs: ["mylib.cpp"],
849			shared_libs: ["libbar"],
850			system_shared_libs: [],
851			stl: "none",
852			stubs: {
853				versions: ["10", "20", "30"],
854			},
855		}
856
857		cc_library {
858			name: "libbar",
859			srcs: ["mylib.cpp"],
860			system_shared_libs: [],
861			stl: "none",
862		}
863
864		cc_library_static {
865			name: "libbaz",
866			srcs: ["mylib.cpp"],
867			system_shared_libs: [],
868			stl: "none",
869			apex_available: [ "myapex2" ],
870		}
871
872	`)
873
874	apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule")
875	copyCmds := apexRule.Args["copy_commands"]
876
877	// Ensure that direct non-stubs dep is always included
878	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
879
880	// Ensure that indirect stubs dep is not included
881	ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
882
883	// Ensure that dependency of stubs is not included
884	ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
885
886	mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex2").Rule("ld").Args["libFlags"]
887
888	// Ensure that mylib is linking with version 10 of libfoo
889	ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
890	// ... and not linking to the non-stub (impl) variant of libfoo
891	ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared/libfoo.so")
892
893	libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"]
894
895	// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
896	ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
897
898	fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
899	ensureListContains(t, fullDepsInfo, "mylib(minSdkVersion:(no version)) <- myapex2")
900	ensureListContains(t, fullDepsInfo, "libbaz(minSdkVersion:(no version)) <- mylib")
901	ensureListContains(t, fullDepsInfo, "libfoo(minSdkVersion:(no version)) (external) <- mylib")
902
903	flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
904	ensureListContains(t, flatDepsInfo, "  mylib(minSdkVersion:(no version))")
905	ensureListContains(t, flatDepsInfo, "  libbaz(minSdkVersion:(no version))")
906	ensureListContains(t, flatDepsInfo, "  libfoo(minSdkVersion:(no version)) (external)")
907}
908
909func TestApexWithRuntimeLibsDependency(t *testing.T) {
910	/*
911		myapex
912		  |
913		  v   (runtime_libs)
914		mylib ------+------> libfoo [provides stub]
915			    |
916			    `------> libbar
917	*/
918	ctx, _ := testApex(t, `
919		apex {
920			name: "myapex",
921			key: "myapex.key",
922			native_shared_libs: ["mylib"],
923		}
924
925		apex_key {
926			name: "myapex.key",
927			public_key: "testkey.avbpubkey",
928			private_key: "testkey.pem",
929		}
930
931		cc_library {
932			name: "mylib",
933			srcs: ["mylib.cpp"],
934			runtime_libs: ["libfoo", "libbar"],
935			system_shared_libs: [],
936			stl: "none",
937			apex_available: [ "myapex" ],
938		}
939
940		cc_library {
941			name: "libfoo",
942			srcs: ["mylib.cpp"],
943			system_shared_libs: [],
944			stl: "none",
945			stubs: {
946				versions: ["10", "20", "30"],
947			},
948		}
949
950		cc_library {
951			name: "libbar",
952			srcs: ["mylib.cpp"],
953			system_shared_libs: [],
954			stl: "none",
955			apex_available: [ "myapex" ],
956		}
957
958	`)
959
960	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
961	copyCmds := apexRule.Args["copy_commands"]
962
963	// Ensure that direct non-stubs dep is always included
964	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
965
966	// Ensure that indirect stubs dep is not included
967	ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
968
969	// Ensure that runtime_libs dep in included
970	ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
971
972	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
973	ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
974	ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so")
975
976}
977
978func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
979	ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
980		bp := `
981		apex {
982			name: "com.android.runtime",
983			key: "com.android.runtime.key",
984			native_shared_libs: ["libc"],
985		}
986
987		apex_key {
988			name: "com.android.runtime.key",
989			public_key: "testkey.avbpubkey",
990			private_key: "testkey.pem",
991		}
992
993		cc_library {
994			name: "libc",
995			no_libcrt: true,
996			nocrt: true,
997			stl: "none",
998			system_shared_libs: [],
999			stubs: { versions: ["1"] },
1000			apex_available: ["com.android.runtime"],
1001
1002			sanitize: {
1003				hwaddress: true,
1004			}
1005		}
1006
1007		cc_prebuilt_library_shared {
1008			name: "libclang_rt.hwasan-aarch64-android",
1009			no_libcrt: true,
1010			nocrt: true,
1011			stl: "none",
1012			system_shared_libs: [],
1013			srcs: [""],
1014			stubs: { versions: ["1"] },
1015
1016			sanitize: {
1017				never: true,
1018			},
1019		}
1020		`
1021		// override bp to use hard-coded names: com.android.runtime and libc
1022		fs["Android.bp"] = []byte(bp)
1023		fs["system/sepolicy/apex/com.android.runtime-file_contexts"] = nil
1024	})
1025
1026	ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{
1027		"lib64/bionic/libc.so",
1028		"lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
1029	})
1030
1031	hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared")
1032
1033	installed := hwasan.Description("install libclang_rt.hwasan")
1034	ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
1035
1036	symlink := hwasan.Description("install symlink libclang_rt.hwasan")
1037	ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so")
1038	ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so")
1039}
1040
1041func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
1042	ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
1043		bp := `
1044		apex {
1045			name: "com.android.runtime",
1046			key: "com.android.runtime.key",
1047			native_shared_libs: ["libc"],
1048		}
1049
1050		apex_key {
1051			name: "com.android.runtime.key",
1052			public_key: "testkey.avbpubkey",
1053			private_key: "testkey.pem",
1054		}
1055
1056		cc_library {
1057			name: "libc",
1058			no_libcrt: true,
1059			nocrt: true,
1060			stl: "none",
1061			system_shared_libs: [],
1062			stubs: { versions: ["1"] },
1063			apex_available: ["com.android.runtime"],
1064		}
1065
1066		cc_prebuilt_library_shared {
1067			name: "libclang_rt.hwasan-aarch64-android",
1068			no_libcrt: true,
1069			nocrt: true,
1070			stl: "none",
1071			system_shared_libs: [],
1072			srcs: [""],
1073			stubs: { versions: ["1"] },
1074
1075			sanitize: {
1076				never: true,
1077			},
1078		}
1079		`
1080		// override bp to use hard-coded names: com.android.runtime and libc
1081		fs["Android.bp"] = []byte(bp)
1082		fs["system/sepolicy/apex/com.android.runtime-file_contexts"] = nil
1083
1084		config.TestProductVariables.SanitizeDevice = []string{"hwaddress"}
1085	})
1086
1087	ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{
1088		"lib64/bionic/libc.so",
1089		"lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
1090	})
1091
1092	hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared")
1093
1094	installed := hwasan.Description("install libclang_rt.hwasan")
1095	ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
1096
1097	symlink := hwasan.Description("install symlink libclang_rt.hwasan")
1098	ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so")
1099	ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so")
1100}
1101
1102func TestApexDependsOnLLNDKTransitively(t *testing.T) {
1103	testcases := []struct {
1104		name          string
1105		minSdkVersion string
1106		shouldLink    string
1107		shouldNotLink []string
1108	}{
1109		{
1110			name:          "should link to the latest",
1111			minSdkVersion: "",
1112			shouldLink:    "30",
1113			shouldNotLink: []string{"29"},
1114		},
1115		{
1116			name:          "should link to llndk#29",
1117			minSdkVersion: "min_sdk_version: \"29\",",
1118			shouldLink:    "29",
1119			shouldNotLink: []string{"30"},
1120		},
1121	}
1122	for _, tc := range testcases {
1123		t.Run(tc.name, func(t *testing.T) {
1124			ctx, _ := testApex(t, `
1125			apex {
1126				name: "myapex",
1127				key: "myapex.key",
1128				use_vendor: true,
1129				native_shared_libs: ["mylib"],
1130				`+tc.minSdkVersion+`
1131			}
1132
1133			apex_key {
1134				name: "myapex.key",
1135				public_key: "testkey.avbpubkey",
1136				private_key: "testkey.pem",
1137			}
1138
1139			cc_library {
1140				name: "mylib",
1141				srcs: ["mylib.cpp"],
1142				vendor_available: true,
1143				shared_libs: ["libbar"],
1144				system_shared_libs: [],
1145				stl: "none",
1146				apex_available: [ "myapex" ],
1147				min_sdk_version: "29",
1148			}
1149
1150			cc_library {
1151				name: "libbar",
1152				srcs: ["mylib.cpp"],
1153				system_shared_libs: [],
1154				stl: "none",
1155				stubs: { versions: ["29","30"] },
1156			}
1157
1158			llndk_library {
1159				name: "libbar",
1160				symbol_file: "",
1161			}
1162			`, func(fs map[string][]byte, config android.Config) {
1163				setUseVendorAllowListForTest(config, []string{"myapex"})
1164			}, withUnbundledBuild)
1165
1166			// Ensure that LLNDK dep is not included
1167			ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
1168				"lib64/mylib.so",
1169			})
1170
1171			// Ensure that LLNDK dep is required
1172			apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
1173			ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
1174			ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
1175
1176			mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
1177			ensureContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
1178			for _, ver := range tc.shouldNotLink {
1179				ensureNotContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+ver+"/libbar.so")
1180			}
1181
1182			mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
1183			ensureContains(t, mylibCFlags, "__LIBBAR_API__="+tc.shouldLink)
1184		})
1185	}
1186}
1187
1188func TestApexWithSystemLibsStubs(t *testing.T) {
1189	ctx, _ := testApex(t, `
1190		apex {
1191			name: "myapex",
1192			key: "myapex.key",
1193			native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
1194		}
1195
1196		apex_key {
1197			name: "myapex.key",
1198			public_key: "testkey.avbpubkey",
1199			private_key: "testkey.pem",
1200		}
1201
1202		cc_library {
1203			name: "mylib",
1204			srcs: ["mylib.cpp"],
1205			shared_libs: ["libdl#27"],
1206			stl: "none",
1207			apex_available: [ "myapex" ],
1208		}
1209
1210		cc_library_shared {
1211			name: "mylib_shared",
1212			srcs: ["mylib.cpp"],
1213			shared_libs: ["libdl#27"],
1214			stl: "none",
1215			apex_available: [ "myapex" ],
1216		}
1217
1218		cc_library {
1219			name: "libBootstrap",
1220			srcs: ["mylib.cpp"],
1221			stl: "none",
1222			bootstrap: true,
1223		}
1224	`)
1225
1226	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
1227	copyCmds := apexRule.Args["copy_commands"]
1228
1229	// Ensure that mylib, libm, libdl are included.
1230	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
1231	ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so")
1232	ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so")
1233
1234	// Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
1235	ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so")
1236
1237	mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
1238	mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
1239	mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_myapex").Rule("cc").Args["cFlags"]
1240
1241	// For dependency to libc
1242	// Ensure that mylib is linking with the latest version of stubs
1243	ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_29/libc.so")
1244	// ... and not linking to the non-stub (impl) variant
1245	ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared/libc.so")
1246	// ... Cflags from stub is correctly exported to mylib
1247	ensureContains(t, mylibCFlags, "__LIBC_API__=29")
1248	ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29")
1249
1250	// For dependency to libm
1251	// Ensure that mylib is linking with the non-stub (impl) variant
1252	ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_myapex/libm.so")
1253	// ... and not linking to the stub variant
1254	ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29/libm.so")
1255	// ... and is not compiling with the stub
1256	ensureNotContains(t, mylibCFlags, "__LIBM_API__=29")
1257	ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29")
1258
1259	// For dependency to libdl
1260	// Ensure that mylib is linking with the specified version of stubs
1261	ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27/libdl.so")
1262	// ... and not linking to the other versions of stubs
1263	ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28/libdl.so")
1264	ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29/libdl.so")
1265	// ... and not linking to the non-stub (impl) variant
1266	ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_myapex/libdl.so")
1267	// ... Cflags from stub is correctly exported to mylib
1268	ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
1269	ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
1270
1271	// Ensure that libBootstrap is depending on the platform variant of bionic libs
1272	libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
1273	ensureContains(t, libFlags, "libc/android_arm64_armv8-a_shared/libc.so")
1274	ensureContains(t, libFlags, "libm/android_arm64_armv8-a_shared/libm.so")
1275	ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_shared/libdl.so")
1276}
1277
1278func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) {
1279	// there are three links between liba --> libz
1280	// 1) myapex -> libx -> liba -> libz    : this should be #29 link, but fallback to #28
1281	// 2) otherapex -> liby -> liba -> libz : this should be #30 link
1282	// 3) (platform) -> liba -> libz        : this should be non-stub link
1283	ctx, _ := testApex(t, `
1284		apex {
1285			name: "myapex",
1286			key: "myapex.key",
1287			native_shared_libs: ["libx"],
1288			min_sdk_version: "29",
1289		}
1290
1291		apex {
1292			name: "otherapex",
1293			key: "myapex.key",
1294			native_shared_libs: ["liby"],
1295			min_sdk_version: "30",
1296		}
1297
1298		apex_key {
1299			name: "myapex.key",
1300			public_key: "testkey.avbpubkey",
1301			private_key: "testkey.pem",
1302		}
1303
1304		cc_library {
1305			name: "libx",
1306			shared_libs: ["liba"],
1307			system_shared_libs: [],
1308			stl: "none",
1309			apex_available: [ "myapex" ],
1310			min_sdk_version: "29",
1311		}
1312
1313		cc_library {
1314			name: "liby",
1315			shared_libs: ["liba"],
1316			system_shared_libs: [],
1317			stl: "none",
1318			apex_available: [ "otherapex" ],
1319			min_sdk_version: "29",
1320		}
1321
1322		cc_library {
1323			name: "liba",
1324			shared_libs: ["libz"],
1325			system_shared_libs: [],
1326			stl: "none",
1327			apex_available: [
1328				"//apex_available:anyapex",
1329				"//apex_available:platform",
1330			],
1331			min_sdk_version: "29",
1332		}
1333
1334		cc_library {
1335			name: "libz",
1336			system_shared_libs: [],
1337			stl: "none",
1338			stubs: {
1339				versions: ["28", "30"],
1340			},
1341		}
1342	`)
1343
1344	expectLink := func(from, from_variant, to, to_variant string) {
1345		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1346		ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1347	}
1348	expectNoLink := func(from, from_variant, to, to_variant string) {
1349		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1350		ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1351	}
1352	// platform liba is linked to non-stub version
1353	expectLink("liba", "shared", "libz", "shared")
1354	// liba in myapex is linked to #28
1355	expectLink("liba", "shared_myapex", "libz", "shared_28")
1356	expectNoLink("liba", "shared_myapex", "libz", "shared_30")
1357	expectNoLink("liba", "shared_myapex", "libz", "shared")
1358	// liba in otherapex is linked to #30
1359	expectLink("liba", "shared_otherapex", "libz", "shared_30")
1360	expectNoLink("liba", "shared_otherapex", "libz", "shared_28")
1361	expectNoLink("liba", "shared_otherapex", "libz", "shared")
1362}
1363
1364func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
1365	ctx, _ := testApex(t, `
1366		apex {
1367			name: "myapex",
1368			key: "myapex.key",
1369			native_shared_libs: ["libx"],
1370			min_sdk_version: "R",
1371		}
1372
1373		apex_key {
1374			name: "myapex.key",
1375			public_key: "testkey.avbpubkey",
1376			private_key: "testkey.pem",
1377		}
1378
1379		cc_library {
1380			name: "libx",
1381			shared_libs: ["libz"],
1382			system_shared_libs: [],
1383			stl: "none",
1384			apex_available: [ "myapex" ],
1385			min_sdk_version: "R",
1386		}
1387
1388		cc_library {
1389			name: "libz",
1390			system_shared_libs: [],
1391			stl: "none",
1392			stubs: {
1393				versions: ["29", "R"],
1394			},
1395		}
1396	`, func(fs map[string][]byte, config android.Config) {
1397		config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
1398	})
1399
1400	expectLink := func(from, from_variant, to, to_variant string) {
1401		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1402		ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1403	}
1404	expectNoLink := func(from, from_variant, to, to_variant string) {
1405		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1406		ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1407	}
1408	// 9000 is quite a magic number.
1409	// Finalized SDK codenames are mapped as P(28), Q(29), ...
1410	// And, codenames which are not finalized yet(active_codenames + future_codenames) are numbered from 9000, 9001, ...
1411	// to distinguish them from finalized and future_api(10000)
1412	// In this test, "R" is assumed not finalized yet( listed in Platform_version_active_codenames) and translated into 9000
1413	// (refer android/api_levels.go)
1414	expectLink("libx", "shared_myapex", "libz", "shared_9000")
1415	expectNoLink("libx", "shared_myapex", "libz", "shared_29")
1416	expectNoLink("libx", "shared_myapex", "libz", "shared")
1417}
1418
1419func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
1420	ctx, _ := testApex(t, `
1421		apex {
1422			name: "myapex",
1423			key: "myapex.key",
1424			native_shared_libs: ["libx"],
1425		}
1426
1427		apex_key {
1428			name: "myapex.key",
1429			public_key: "testkey.avbpubkey",
1430			private_key: "testkey.pem",
1431		}
1432
1433		cc_library {
1434			name: "libx",
1435			shared_libs: ["libz"],
1436			system_shared_libs: [],
1437			stl: "none",
1438			apex_available: [ "myapex" ],
1439		}
1440
1441		cc_library {
1442			name: "libz",
1443			system_shared_libs: [],
1444			stl: "none",
1445			stubs: {
1446				versions: ["1", "2"],
1447			},
1448		}
1449	`)
1450
1451	expectLink := func(from, from_variant, to, to_variant string) {
1452		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1453		ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1454	}
1455	expectNoLink := func(from, from_variant, to, to_variant string) {
1456		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1457		ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1458	}
1459	expectLink("libx", "shared_myapex", "libz", "shared_2")
1460	expectNoLink("libx", "shared_myapex", "libz", "shared_1")
1461	expectNoLink("libx", "shared_myapex", "libz", "shared")
1462}
1463
1464func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
1465	ctx, _ := testApex(t, `
1466		apex {
1467			name: "myapex",
1468			key: "myapex.key",
1469			native_shared_libs: ["libx"],
1470		}
1471
1472		apex_key {
1473			name: "myapex.key",
1474			public_key: "testkey.avbpubkey",
1475			private_key: "testkey.pem",
1476		}
1477
1478		cc_library {
1479			name: "libx",
1480			system_shared_libs: [],
1481			stl: "none",
1482			apex_available: [ "myapex" ],
1483			stubs: {
1484				versions: ["1", "2"],
1485			},
1486		}
1487
1488		cc_library {
1489			name: "libz",
1490			shared_libs: ["libx"],
1491			system_shared_libs: [],
1492			stl: "none",
1493		}
1494	`)
1495
1496	expectLink := func(from, from_variant, to, to_variant string) {
1497		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1498		ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1499	}
1500	expectNoLink := func(from, from_variant, to, to_variant string) {
1501		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
1502		ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1503	}
1504	expectLink("libz", "shared", "libx", "shared_2")
1505	expectNoLink("libz", "shared", "libz", "shared_1")
1506	expectNoLink("libz", "shared", "libz", "shared")
1507}
1508
1509func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
1510	ctx, _ := testApex(t, `
1511		apex {
1512			name: "myapex",
1513			key: "myapex.key",
1514			native_shared_libs: ["libx"],
1515			min_sdk_version: "29",
1516		}
1517
1518		apex_key {
1519			name: "myapex.key",
1520			public_key: "testkey.avbpubkey",
1521			private_key: "testkey.pem",
1522		}
1523
1524		cc_library {
1525			name: "libx",
1526			shared_libs: ["libbar"],
1527			apex_available: [ "myapex" ],
1528			min_sdk_version: "29",
1529		}
1530
1531		cc_library {
1532			name: "libbar",
1533			stubs: {
1534				versions: ["29", "30"],
1535			},
1536		}
1537	`, func(fs map[string][]byte, config android.Config) {
1538		config.TestProductVariables.SanitizeDevice = []string{"hwaddress"}
1539	})
1540	expectLink := func(from, from_variant, to, to_variant string) {
1541		ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
1542		libFlags := ld.Args["libFlags"]
1543		ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1544	}
1545	expectLink("libx", "shared_hwasan_myapex", "libbar", "shared_30")
1546}
1547
1548func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
1549	ctx, _ := testApex(t, `
1550		apex {
1551			name: "myapex",
1552			key: "myapex.key",
1553			native_shared_libs: ["libx"],
1554			min_sdk_version: "29",
1555		}
1556
1557		apex_key {
1558			name: "myapex.key",
1559			public_key: "testkey.avbpubkey",
1560			private_key: "testkey.pem",
1561		}
1562
1563		cc_library {
1564			name: "libx",
1565			apex_available: [ "myapex" ],
1566			min_sdk_version: "29",
1567		}
1568	`)
1569
1570	// ensure apex variant of c++ is linked with static unwinder
1571	cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module)
1572	ensureListContains(t, cm.Properties.AndroidMkStaticLibs, "libgcc_stripped")
1573	// note that platform variant is not.
1574	cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
1575	ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libgcc_stripped")
1576}
1577
1578func TestApexMinSdkVersion_ErrorIfIncompatibleStubs(t *testing.T) {
1579	testApexError(t, `"libz" .*: not found a version\(<=29\)`, `
1580		apex {
1581			name: "myapex",
1582			key: "myapex.key",
1583			native_shared_libs: ["libx"],
1584			min_sdk_version: "29",
1585		}
1586
1587		apex_key {
1588			name: "myapex.key",
1589			public_key: "testkey.avbpubkey",
1590			private_key: "testkey.pem",
1591		}
1592
1593		cc_library {
1594			name: "libx",
1595			shared_libs: ["libz"],
1596			system_shared_libs: [],
1597			stl: "none",
1598			apex_available: [ "myapex" ],
1599			min_sdk_version: "29",
1600		}
1601
1602		cc_library {
1603			name: "libz",
1604			system_shared_libs: [],
1605			stl: "none",
1606			stubs: {
1607				versions: ["30"],
1608			},
1609		}
1610	`)
1611}
1612
1613func TestApexMinSdkVersion_ErrorIfIncompatibleVersion(t *testing.T) {
1614	testApexError(t, `module "mylib".*: should support min_sdk_version\(29\)`, `
1615		apex {
1616			name: "myapex",
1617			key: "myapex.key",
1618			native_shared_libs: ["mylib"],
1619			min_sdk_version: "29",
1620		}
1621
1622		apex_key {
1623			name: "myapex.key",
1624			public_key: "testkey.avbpubkey",
1625			private_key: "testkey.pem",
1626		}
1627
1628		cc_library {
1629			name: "mylib",
1630			srcs: ["mylib.cpp"],
1631			system_shared_libs: [],
1632			stl: "none",
1633			apex_available: [
1634				"myapex",
1635			],
1636			min_sdk_version: "30",
1637		}
1638	`)
1639}
1640
1641func TestApexMinSdkVersion_Okay(t *testing.T) {
1642	testApex(t, `
1643		apex {
1644			name: "myapex",
1645			key: "myapex.key",
1646			native_shared_libs: ["libfoo"],
1647			java_libs: ["libbar"],
1648			min_sdk_version: "29",
1649		}
1650
1651		apex_key {
1652			name: "myapex.key",
1653			public_key: "testkey.avbpubkey",
1654			private_key: "testkey.pem",
1655		}
1656
1657		cc_library {
1658			name: "libfoo",
1659			srcs: ["mylib.cpp"],
1660			shared_libs: ["libfoo_dep"],
1661			apex_available: ["myapex"],
1662			min_sdk_version: "29",
1663		}
1664
1665		cc_library {
1666			name: "libfoo_dep",
1667			srcs: ["mylib.cpp"],
1668			apex_available: ["myapex"],
1669			min_sdk_version: "29",
1670		}
1671
1672		java_library {
1673			name: "libbar",
1674			sdk_version: "current",
1675			srcs: ["a.java"],
1676			static_libs: ["libbar_dep"],
1677			apex_available: ["myapex"],
1678			min_sdk_version: "29",
1679		}
1680
1681		java_library {
1682			name: "libbar_dep",
1683			sdk_version: "current",
1684			srcs: ["a.java"],
1685			apex_available: ["myapex"],
1686			min_sdk_version: "29",
1687		}
1688	`)
1689}
1690
1691func TestJavaStableSdkVersion(t *testing.T) {
1692	testCases := []struct {
1693		name          string
1694		expectedError string
1695		bp            string
1696	}{
1697		{
1698			name: "Non-updatable apex with non-stable dep",
1699			bp: `
1700				apex {
1701					name: "myapex",
1702					java_libs: ["myjar"],
1703					key: "myapex.key",
1704				}
1705				apex_key {
1706					name: "myapex.key",
1707					public_key: "testkey.avbpubkey",
1708					private_key: "testkey.pem",
1709				}
1710				java_library {
1711					name: "myjar",
1712					srcs: ["foo/bar/MyClass.java"],
1713					sdk_version: "core_platform",
1714					apex_available: ["myapex"],
1715				}
1716			`,
1717		},
1718		{
1719			name: "Updatable apex with stable dep",
1720			bp: `
1721				apex {
1722					name: "myapex",
1723					java_libs: ["myjar"],
1724					key: "myapex.key",
1725					updatable: true,
1726					min_sdk_version: "29",
1727				}
1728				apex_key {
1729					name: "myapex.key",
1730					public_key: "testkey.avbpubkey",
1731					private_key: "testkey.pem",
1732				}
1733				java_library {
1734					name: "myjar",
1735					srcs: ["foo/bar/MyClass.java"],
1736					sdk_version: "current",
1737					apex_available: ["myapex"],
1738					min_sdk_version: "29",
1739				}
1740			`,
1741		},
1742		{
1743			name:          "Updatable apex with non-stable dep",
1744			expectedError: "cannot depend on \"myjar\"",
1745			bp: `
1746				apex {
1747					name: "myapex",
1748					java_libs: ["myjar"],
1749					key: "myapex.key",
1750					updatable: true,
1751				}
1752				apex_key {
1753					name: "myapex.key",
1754					public_key: "testkey.avbpubkey",
1755					private_key: "testkey.pem",
1756				}
1757				java_library {
1758					name: "myjar",
1759					srcs: ["foo/bar/MyClass.java"],
1760					sdk_version: "core_platform",
1761					apex_available: ["myapex"],
1762				}
1763			`,
1764		},
1765		{
1766			name:          "Updatable apex with non-stable transitive dep",
1767			expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against non-public Android API.",
1768			bp: `
1769				apex {
1770					name: "myapex",
1771					java_libs: ["myjar"],
1772					key: "myapex.key",
1773					updatable: true,
1774				}
1775				apex_key {
1776					name: "myapex.key",
1777					public_key: "testkey.avbpubkey",
1778					private_key: "testkey.pem",
1779				}
1780				java_library {
1781					name: "myjar",
1782					srcs: ["foo/bar/MyClass.java"],
1783					sdk_version: "current",
1784					apex_available: ["myapex"],
1785					static_libs: ["transitive-jar"],
1786				}
1787				java_library {
1788					name: "transitive-jar",
1789					srcs: ["foo/bar/MyClass.java"],
1790					sdk_version: "core_platform",
1791					apex_available: ["myapex"],
1792				}
1793			`,
1794		},
1795	}
1796
1797	for _, test := range testCases {
1798		t.Run(test.name, func(t *testing.T) {
1799			if test.expectedError == "" {
1800				testApex(t, test.bp)
1801			} else {
1802				testApexError(t, test.expectedError, test.bp)
1803			}
1804		})
1805	}
1806}
1807
1808func TestApexMinSdkVersion_ErrorIfDepIsNewer(t *testing.T) {
1809	testApexError(t, `module "mylib2".*: should support min_sdk_version\(29\) for "myapex"`, `
1810		apex {
1811			name: "myapex",
1812			key: "myapex.key",
1813			native_shared_libs: ["mylib"],
1814			min_sdk_version: "29",
1815		}
1816
1817		apex_key {
1818			name: "myapex.key",
1819			public_key: "testkey.avbpubkey",
1820			private_key: "testkey.pem",
1821		}
1822
1823		cc_library {
1824			name: "mylib",
1825			srcs: ["mylib.cpp"],
1826			shared_libs: ["mylib2"],
1827			system_shared_libs: [],
1828			stl: "none",
1829			apex_available: [
1830				"myapex",
1831			],
1832			min_sdk_version: "29",
1833		}
1834
1835		// indirect part of the apex
1836		cc_library {
1837			name: "mylib2",
1838			srcs: ["mylib.cpp"],
1839			system_shared_libs: [],
1840			stl: "none",
1841			apex_available: [
1842				"myapex",
1843			],
1844			min_sdk_version: "30",
1845		}
1846	`)
1847}
1848
1849func TestApexMinSdkVersion_ErrorIfDepIsNewer_Java(t *testing.T) {
1850	testApexError(t, `module "bar".*: should support min_sdk_version\(29\) for "myapex"`, `
1851		apex {
1852			name: "myapex",
1853			key: "myapex.key",
1854			apps: ["AppFoo"],
1855			min_sdk_version: "29",
1856		}
1857
1858		apex_key {
1859			name: "myapex.key",
1860			public_key: "testkey.avbpubkey",
1861			private_key: "testkey.pem",
1862		}
1863
1864		android_app {
1865			name: "AppFoo",
1866			srcs: ["foo/bar/MyClass.java"],
1867			sdk_version: "current",
1868			min_sdk_version: "29",
1869			system_modules: "none",
1870			stl: "none",
1871			static_libs: ["bar"],
1872			apex_available: [ "myapex" ],
1873		}
1874
1875		java_library {
1876			name: "bar",
1877			sdk_version: "current",
1878			srcs: ["a.java"],
1879			apex_available: [ "myapex" ],
1880		}
1881	`)
1882}
1883
1884func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) {
1885	ctx, _ := testApex(t, `
1886		apex {
1887			name: "myapex",
1888			key: "myapex.key",
1889			native_shared_libs: ["mylib"],
1890			min_sdk_version: "29",
1891		}
1892
1893		apex_key {
1894			name: "myapex.key",
1895			public_key: "testkey.avbpubkey",
1896			private_key: "testkey.pem",
1897		}
1898
1899		// mylib in myapex will link to mylib2#29
1900		// mylib in otherapex will link to mylib2(non-stub) in otherapex as well
1901		cc_library {
1902			name: "mylib",
1903			srcs: ["mylib.cpp"],
1904			shared_libs: ["mylib2"],
1905			system_shared_libs: [],
1906			stl: "none",
1907			apex_available: ["myapex", "otherapex"],
1908			min_sdk_version: "29",
1909		}
1910
1911		cc_library {
1912			name: "mylib2",
1913			srcs: ["mylib.cpp"],
1914			system_shared_libs: [],
1915			stl: "none",
1916			apex_available: ["otherapex"],
1917			stubs: { versions: ["29", "30"] },
1918			min_sdk_version: "30",
1919		}
1920
1921		apex {
1922			name: "otherapex",
1923			key: "myapex.key",
1924			native_shared_libs: ["mylib", "mylib2"],
1925			min_sdk_version: "30",
1926		}
1927	`)
1928	expectLink := func(from, from_variant, to, to_variant string) {
1929		ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
1930		libFlags := ld.Args["libFlags"]
1931		ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
1932	}
1933	expectLink("mylib", "shared_myapex", "mylib2", "shared_29")
1934	expectLink("mylib", "shared_otherapex", "mylib2", "shared_otherapex")
1935}
1936
1937func TestFilesInSubDir(t *testing.T) {
1938	ctx, _ := testApex(t, `
1939		apex {
1940			name: "myapex",
1941			key: "myapex.key",
1942			native_shared_libs: ["mylib"],
1943			binaries: ["mybin"],
1944			prebuilts: ["myetc"],
1945			compile_multilib: "both",
1946		}
1947
1948		apex_key {
1949			name: "myapex.key",
1950			public_key: "testkey.avbpubkey",
1951			private_key: "testkey.pem",
1952		}
1953
1954		prebuilt_etc {
1955			name: "myetc",
1956			src: "myprebuilt",
1957			sub_dir: "foo/bar",
1958		}
1959
1960		cc_library {
1961			name: "mylib",
1962			srcs: ["mylib.cpp"],
1963			relative_install_path: "foo/bar",
1964			system_shared_libs: [],
1965			stl: "none",
1966			apex_available: [ "myapex" ],
1967		}
1968
1969		cc_binary {
1970			name: "mybin",
1971			srcs: ["mylib.cpp"],
1972			relative_install_path: "foo/bar",
1973			system_shared_libs: [],
1974			static_executable: true,
1975			stl: "none",
1976			apex_available: [ "myapex" ],
1977		}
1978	`)
1979
1980	generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("generateFsConfig")
1981	dirs := strings.Split(generateFsRule.Args["exec_paths"], " ")
1982
1983	// Ensure that the subdirectories are all listed
1984	ensureListContains(t, dirs, "etc")
1985	ensureListContains(t, dirs, "etc/foo")
1986	ensureListContains(t, dirs, "etc/foo/bar")
1987	ensureListContains(t, dirs, "lib64")
1988	ensureListContains(t, dirs, "lib64/foo")
1989	ensureListContains(t, dirs, "lib64/foo/bar")
1990	ensureListContains(t, dirs, "lib")
1991	ensureListContains(t, dirs, "lib/foo")
1992	ensureListContains(t, dirs, "lib/foo/bar")
1993
1994	ensureListContains(t, dirs, "bin")
1995	ensureListContains(t, dirs, "bin/foo")
1996	ensureListContains(t, dirs, "bin/foo/bar")
1997}
1998
1999func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
2000	ctx, _ := testApex(t, `
2001		apex {
2002			name: "myapex",
2003			key: "myapex.key",
2004			multilib: {
2005				both: {
2006					native_shared_libs: ["mylib"],
2007					binaries: ["mybin"],
2008				},
2009			},
2010			compile_multilib: "both",
2011			native_bridge_supported: true,
2012		}
2013
2014		apex_key {
2015			name: "myapex.key",
2016			public_key: "testkey.avbpubkey",
2017			private_key: "testkey.pem",
2018		}
2019
2020		cc_library {
2021			name: "mylib",
2022			relative_install_path: "foo/bar",
2023			system_shared_libs: [],
2024			stl: "none",
2025			apex_available: [ "myapex" ],
2026			native_bridge_supported: true,
2027		}
2028
2029		cc_binary {
2030			name: "mybin",
2031			relative_install_path: "foo/bar",
2032			system_shared_libs: [],
2033			static_executable: true,
2034			stl: "none",
2035			apex_available: [ "myapex" ],
2036			native_bridge_supported: true,
2037			compile_multilib: "both", // default is "first" for binary
2038			multilib: {
2039				lib64: {
2040					suffix: "64",
2041				},
2042			},
2043		}
2044	`, withNativeBridgeEnabled)
2045	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
2046		"bin/foo/bar/mybin",
2047		"bin/foo/bar/mybin64",
2048		"bin/arm/foo/bar/mybin",
2049		"bin/arm64/foo/bar/mybin64",
2050		"lib/foo/bar/mylib.so",
2051		"lib/arm/foo/bar/mylib.so",
2052		"lib64/foo/bar/mylib.so",
2053		"lib64/arm64/foo/bar/mylib.so",
2054	})
2055}
2056
2057func TestUseVendor(t *testing.T) {
2058	ctx, _ := testApex(t, `
2059		apex {
2060			name: "myapex",
2061			key: "myapex.key",
2062			native_shared_libs: ["mylib"],
2063			use_vendor: true,
2064		}
2065
2066		apex_key {
2067			name: "myapex.key",
2068			public_key: "testkey.avbpubkey",
2069			private_key: "testkey.pem",
2070		}
2071
2072		cc_library {
2073			name: "mylib",
2074			srcs: ["mylib.cpp"],
2075			shared_libs: ["mylib2"],
2076			system_shared_libs: [],
2077			vendor_available: true,
2078			stl: "none",
2079			apex_available: [ "myapex" ],
2080		}
2081
2082		cc_library {
2083			name: "mylib2",
2084			srcs: ["mylib.cpp"],
2085			system_shared_libs: [],
2086			vendor_available: true,
2087			stl: "none",
2088			apex_available: [ "myapex" ],
2089		}
2090	`, func(fs map[string][]byte, config android.Config) {
2091		setUseVendorAllowListForTest(config, []string{"myapex"})
2092	})
2093
2094	inputsList := []string{}
2095	for _, i := range ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().BuildParamsForTests() {
2096		for _, implicit := range i.Implicits {
2097			inputsList = append(inputsList, implicit.String())
2098		}
2099	}
2100	inputsString := strings.Join(inputsList, " ")
2101
2102	// ensure that the apex includes vendor variants of the direct and indirect deps
2103	ensureContains(t, inputsString, "android_vendor.VER_arm64_armv8-a_shared_myapex/mylib.so")
2104	ensureContains(t, inputsString, "android_vendor.VER_arm64_armv8-a_shared_myapex/mylib2.so")
2105
2106	// ensure that the apex does not include core variants
2107	ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_myapex/mylib.so")
2108	ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_myapex/mylib2.so")
2109}
2110
2111func TestUseVendorNotAllowedForSystemApexes(t *testing.T) {
2112	testApexError(t, `module "myapex" .*: use_vendor: not allowed`, `
2113		apex {
2114			name: "myapex",
2115			key: "myapex.key",
2116			use_vendor: true,
2117		}
2118		apex_key {
2119			name: "myapex.key",
2120			public_key: "testkey.avbpubkey",
2121			private_key: "testkey.pem",
2122		}
2123	`, func(fs map[string][]byte, config android.Config) {
2124		setUseVendorAllowListForTest(config, []string{""})
2125	})
2126	// no error with allow list
2127	testApex(t, `
2128		apex {
2129			name: "myapex",
2130			key: "myapex.key",
2131			use_vendor: true,
2132		}
2133		apex_key {
2134			name: "myapex.key",
2135			public_key: "testkey.avbpubkey",
2136			private_key: "testkey.pem",
2137		}
2138	`, func(fs map[string][]byte, config android.Config) {
2139		setUseVendorAllowListForTest(config, []string{"myapex"})
2140	})
2141}
2142
2143func TestUseVendorFailsIfNotVendorAvailable(t *testing.T) {
2144	testApexError(t, `dependency "mylib" of "myapex" missing variant:\n.*image:vendor`, `
2145		apex {
2146			name: "myapex",
2147			key: "myapex.key",
2148			native_shared_libs: ["mylib"],
2149			use_vendor: true,
2150		}
2151
2152		apex_key {
2153			name: "myapex.key",
2154			public_key: "testkey.avbpubkey",
2155			private_key: "testkey.pem",
2156		}
2157
2158		cc_library {
2159			name: "mylib",
2160			srcs: ["mylib.cpp"],
2161			system_shared_libs: [],
2162			stl: "none",
2163		}
2164	`)
2165}
2166
2167func TestVendorApex(t *testing.T) {
2168	ctx, config := testApex(t, `
2169		apex {
2170			name: "myapex",
2171			key: "myapex.key",
2172			binaries: ["mybin"],
2173			vendor: true,
2174		}
2175		apex_key {
2176			name: "myapex.key",
2177			public_key: "testkey.avbpubkey",
2178			private_key: "testkey.pem",
2179		}
2180		cc_binary {
2181			name: "mybin",
2182			vendor: true,
2183			shared_libs: ["libfoo"],
2184		}
2185		cc_library {
2186			name: "libfoo",
2187			proprietary: true,
2188		}
2189	`)
2190
2191	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
2192		"bin/mybin",
2193		"lib64/libfoo.so",
2194		// TODO(b/159195575): Add an option to use VNDK libs from VNDK APEX
2195		"lib64/libc++.so",
2196	})
2197
2198	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
2199	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
2200	name := apexBundle.BaseModuleName()
2201	prefix := "TARGET_"
2202	var builder strings.Builder
2203	data.Custom(&builder, name, prefix, "", data)
2204	androidMk := builder.String()
2205	ensureContains(t, androidMk, `LOCAL_MODULE_PATH := /tmp/target/product/test_device/vendor/apex`)
2206
2207	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
2208	requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
2209	ensureListNotContains(t, requireNativeLibs, ":vndk")
2210}
2211
2212func TestVendorApex_use_vndk_as_stable(t *testing.T) {
2213	ctx, _ := testApex(t, `
2214		apex {
2215			name: "myapex",
2216			key: "myapex.key",
2217			binaries: ["mybin"],
2218			vendor: true,
2219			use_vndk_as_stable: true,
2220		}
2221		apex_key {
2222			name: "myapex.key",
2223			public_key: "testkey.avbpubkey",
2224			private_key: "testkey.pem",
2225		}
2226		cc_binary {
2227			name: "mybin",
2228			vendor: true,
2229			shared_libs: ["libvndk", "libvendor"],
2230		}
2231		cc_library {
2232			name: "libvndk",
2233			vndk: {
2234				enabled: true,
2235			},
2236			vendor_available: true,
2237		}
2238		cc_library {
2239			name: "libvendor",
2240			vendor: true,
2241		}
2242	`)
2243
2244	vendorVariant := "android_vendor.VER_arm64_armv8-a"
2245
2246	ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_myapex").Rule("ld")
2247	libs := names(ldRule.Args["libFlags"])
2248	// VNDK libs(libvndk/libc++) as they are
2249	ensureListContains(t, libs, buildDir+"/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
2250	ensureListContains(t, libs, buildDir+"/.intermediates/libc++/"+vendorVariant+"_shared/libc++.so")
2251	// non-stable Vendor libs as APEX variants
2252	ensureListContains(t, libs, buildDir+"/.intermediates/libvendor/"+vendorVariant+"_shared_myapex/libvendor.so")
2253
2254	// VNDK libs are not included when use_vndk_as_stable: true
2255	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
2256		"bin/mybin",
2257		"lib64/libvendor.so",
2258	})
2259
2260	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
2261	requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
2262	ensureListContains(t, requireNativeLibs, ":vndk")
2263}
2264
2265func TestAndroidMk_UseVendorRequired(t *testing.T) {
2266	ctx, config := testApex(t, `
2267		apex {
2268			name: "myapex",
2269			key: "myapex.key",
2270			use_vendor: true,
2271			native_shared_libs: ["mylib"],
2272		}
2273
2274		apex_key {
2275			name: "myapex.key",
2276			public_key: "testkey.avbpubkey",
2277			private_key: "testkey.pem",
2278		}
2279
2280		cc_library {
2281			name: "mylib",
2282			vendor_available: true,
2283			apex_available: ["myapex"],
2284		}
2285	`, func(fs map[string][]byte, config android.Config) {
2286		setUseVendorAllowListForTest(config, []string{"myapex"})
2287	})
2288
2289	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
2290	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
2291	name := apexBundle.BaseModuleName()
2292	prefix := "TARGET_"
2293	var builder strings.Builder
2294	data.Custom(&builder, name, prefix, "", data)
2295	androidMk := builder.String()
2296	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc libm libdl\n")
2297}
2298
2299func TestAndroidMk_VendorApexRequired(t *testing.T) {
2300	ctx, config := testApex(t, `
2301		apex {
2302			name: "myapex",
2303			key: "myapex.key",
2304			vendor: true,
2305			native_shared_libs: ["mylib"],
2306		}
2307
2308		apex_key {
2309			name: "myapex.key",
2310			public_key: "testkey.avbpubkey",
2311			private_key: "testkey.pem",
2312		}
2313
2314		cc_library {
2315			name: "mylib",
2316			vendor_available: true,
2317		}
2318	`)
2319
2320	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
2321	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
2322	name := apexBundle.BaseModuleName()
2323	prefix := "TARGET_"
2324	var builder strings.Builder
2325	data.Custom(&builder, name, prefix, "", data)
2326	androidMk := builder.String()
2327	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc.vendor libm.vendor libdl.vendor\n")
2328}
2329
2330func TestAndroidMkWritesCommonProperties(t *testing.T) {
2331	ctx, config := testApex(t, `
2332		apex {
2333			name: "myapex",
2334			key: "myapex.key",
2335			vintf_fragments: ["fragment.xml"],
2336			init_rc: ["init.rc"],
2337		}
2338		apex_key {
2339			name: "myapex.key",
2340			public_key: "testkey.avbpubkey",
2341			private_key: "testkey.pem",
2342		}
2343		cc_binary {
2344			name: "mybin",
2345		}
2346	`)
2347
2348	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
2349	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
2350	name := apexBundle.BaseModuleName()
2351	prefix := "TARGET_"
2352	var builder strings.Builder
2353	data.Custom(&builder, name, prefix, "", data)
2354	androidMk := builder.String()
2355	ensureContains(t, androidMk, "LOCAL_VINTF_FRAGMENTS := fragment.xml\n")
2356	ensureContains(t, androidMk, "LOCAL_INIT_RC := init.rc\n")
2357}
2358
2359func TestStaticLinking(t *testing.T) {
2360	ctx, _ := testApex(t, `
2361		apex {
2362			name: "myapex",
2363			key: "myapex.key",
2364			native_shared_libs: ["mylib"],
2365		}
2366
2367		apex_key {
2368			name: "myapex.key",
2369			public_key: "testkey.avbpubkey",
2370			private_key: "testkey.pem",
2371		}
2372
2373		cc_library {
2374			name: "mylib",
2375			srcs: ["mylib.cpp"],
2376			system_shared_libs: [],
2377			stl: "none",
2378			stubs: {
2379				versions: ["1", "2", "3"],
2380			},
2381			apex_available: [
2382				"//apex_available:platform",
2383				"myapex",
2384			],
2385		}
2386
2387		cc_binary {
2388			name: "not_in_apex",
2389			srcs: ["mylib.cpp"],
2390			static_libs: ["mylib"],
2391			static_executable: true,
2392			system_shared_libs: [],
2393			stl: "none",
2394		}
2395	`)
2396
2397	ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
2398
2399	// Ensure that not_in_apex is linking with the static variant of mylib
2400	ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_static/mylib.a")
2401}
2402
2403func TestKeys(t *testing.T) {
2404	ctx, _ := testApex(t, `
2405		apex {
2406			name: "myapex_keytest",
2407			key: "myapex.key",
2408			certificate: ":myapex.certificate",
2409			native_shared_libs: ["mylib"],
2410			file_contexts: ":myapex-file_contexts",
2411		}
2412
2413		cc_library {
2414			name: "mylib",
2415			srcs: ["mylib.cpp"],
2416			system_shared_libs: [],
2417			stl: "none",
2418			apex_available: [ "myapex_keytest" ],
2419		}
2420
2421		apex_key {
2422			name: "myapex.key",
2423			public_key: "testkey.avbpubkey",
2424			private_key: "testkey.pem",
2425		}
2426
2427		android_app_certificate {
2428			name: "myapex.certificate",
2429			certificate: "testkey",
2430		}
2431
2432		android_app_certificate {
2433			name: "myapex.certificate.override",
2434			certificate: "testkey.override",
2435		}
2436
2437	`)
2438
2439	// check the APEX keys
2440	keys := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey)
2441
2442	if keys.public_key_file.String() != "vendor/foo/devkeys/testkey.avbpubkey" {
2443		t.Errorf("public key %q is not %q", keys.public_key_file.String(),
2444			"vendor/foo/devkeys/testkey.avbpubkey")
2445	}
2446	if keys.private_key_file.String() != "vendor/foo/devkeys/testkey.pem" {
2447		t.Errorf("private key %q is not %q", keys.private_key_file.String(),
2448			"vendor/foo/devkeys/testkey.pem")
2449	}
2450
2451	// check the APK certs. It should be overridden to myapex.certificate.override
2452	certs := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk").Args["certificates"]
2453	if certs != "testkey.override.x509.pem testkey.override.pk8" {
2454		t.Errorf("cert and private key %q are not %q", certs,
2455			"testkey.override.509.pem testkey.override.pk8")
2456	}
2457}
2458
2459func TestCertificate(t *testing.T) {
2460	t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) {
2461		ctx, _ := testApex(t, `
2462			apex {
2463				name: "myapex",
2464				key: "myapex.key",
2465			}
2466			apex_key {
2467				name: "myapex.key",
2468				public_key: "testkey.avbpubkey",
2469				private_key: "testkey.pem",
2470			}`)
2471		rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk")
2472		expected := "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8"
2473		if actual := rule.Args["certificates"]; actual != expected {
2474			t.Errorf("certificates should be %q, not %q", expected, actual)
2475		}
2476	})
2477	t.Run("override when unspecified", func(t *testing.T) {
2478		ctx, _ := testApex(t, `
2479			apex {
2480				name: "myapex_keytest",
2481				key: "myapex.key",
2482				file_contexts: ":myapex-file_contexts",
2483			}
2484			apex_key {
2485				name: "myapex.key",
2486				public_key: "testkey.avbpubkey",
2487				private_key: "testkey.pem",
2488			}
2489			android_app_certificate {
2490				name: "myapex.certificate.override",
2491				certificate: "testkey.override",
2492			}`)
2493		rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk")
2494		expected := "testkey.override.x509.pem testkey.override.pk8"
2495		if actual := rule.Args["certificates"]; actual != expected {
2496			t.Errorf("certificates should be %q, not %q", expected, actual)
2497		}
2498	})
2499	t.Run("if specified as :module, it respects the prop", func(t *testing.T) {
2500		ctx, _ := testApex(t, `
2501			apex {
2502				name: "myapex",
2503				key: "myapex.key",
2504				certificate: ":myapex.certificate",
2505			}
2506			apex_key {
2507				name: "myapex.key",
2508				public_key: "testkey.avbpubkey",
2509				private_key: "testkey.pem",
2510			}
2511			android_app_certificate {
2512				name: "myapex.certificate",
2513				certificate: "testkey",
2514			}`)
2515		rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk")
2516		expected := "testkey.x509.pem testkey.pk8"
2517		if actual := rule.Args["certificates"]; actual != expected {
2518			t.Errorf("certificates should be %q, not %q", expected, actual)
2519		}
2520	})
2521	t.Run("override when specifiec as <:module>", func(t *testing.T) {
2522		ctx, _ := testApex(t, `
2523			apex {
2524				name: "myapex_keytest",
2525				key: "myapex.key",
2526				file_contexts: ":myapex-file_contexts",
2527				certificate: ":myapex.certificate",
2528			}
2529			apex_key {
2530				name: "myapex.key",
2531				public_key: "testkey.avbpubkey",
2532				private_key: "testkey.pem",
2533			}
2534			android_app_certificate {
2535				name: "myapex.certificate.override",
2536				certificate: "testkey.override",
2537			}`)
2538		rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk")
2539		expected := "testkey.override.x509.pem testkey.override.pk8"
2540		if actual := rule.Args["certificates"]; actual != expected {
2541			t.Errorf("certificates should be %q, not %q", expected, actual)
2542		}
2543	})
2544	t.Run("if specified as name, finds it from DefaultDevKeyDir", func(t *testing.T) {
2545		ctx, _ := testApex(t, `
2546			apex {
2547				name: "myapex",
2548				key: "myapex.key",
2549				certificate: "testkey",
2550			}
2551			apex_key {
2552				name: "myapex.key",
2553				public_key: "testkey.avbpubkey",
2554				private_key: "testkey.pem",
2555			}`)
2556		rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk")
2557		expected := "vendor/foo/devkeys/testkey.x509.pem vendor/foo/devkeys/testkey.pk8"
2558		if actual := rule.Args["certificates"]; actual != expected {
2559			t.Errorf("certificates should be %q, not %q", expected, actual)
2560		}
2561	})
2562	t.Run("override when specified as <name>", func(t *testing.T) {
2563		ctx, _ := testApex(t, `
2564			apex {
2565				name: "myapex_keytest",
2566				key: "myapex.key",
2567				file_contexts: ":myapex-file_contexts",
2568				certificate: "testkey",
2569			}
2570			apex_key {
2571				name: "myapex.key",
2572				public_key: "testkey.avbpubkey",
2573				private_key: "testkey.pem",
2574			}
2575			android_app_certificate {
2576				name: "myapex.certificate.override",
2577				certificate: "testkey.override",
2578			}`)
2579		rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk")
2580		expected := "testkey.override.x509.pem testkey.override.pk8"
2581		if actual := rule.Args["certificates"]; actual != expected {
2582			t.Errorf("certificates should be %q, not %q", expected, actual)
2583		}
2584	})
2585}
2586
2587func TestMacro(t *testing.T) {
2588	ctx, _ := testApex(t, `
2589		apex {
2590			name: "myapex",
2591			key: "myapex.key",
2592			native_shared_libs: ["mylib", "mylib2"],
2593		}
2594
2595		apex {
2596			name: "otherapex",
2597			key: "myapex.key",
2598			native_shared_libs: ["mylib", "mylib2"],
2599			min_sdk_version: "29",
2600		}
2601
2602		apex_key {
2603			name: "myapex.key",
2604			public_key: "testkey.avbpubkey",
2605			private_key: "testkey.pem",
2606		}
2607
2608		cc_library {
2609			name: "mylib",
2610			srcs: ["mylib.cpp"],
2611			system_shared_libs: [],
2612			stl: "none",
2613			apex_available: [
2614				"myapex",
2615				"otherapex",
2616			],
2617			recovery_available: true,
2618			min_sdk_version: "29",
2619		}
2620		cc_library {
2621			name: "mylib2",
2622			srcs: ["mylib.cpp"],
2623			system_shared_libs: [],
2624			stl: "none",
2625			apex_available: [
2626				"myapex",
2627				"otherapex",
2628			],
2629			use_apex_name_macro: true,
2630			min_sdk_version: "29",
2631		}
2632	`)
2633
2634	// non-APEX variant does not have __ANDROID_APEX__ defined
2635	mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
2636	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
2637	ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
2638
2639	// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
2640	mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
2641	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
2642	ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=10000")
2643	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
2644
2645	// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
2646	mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
2647	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
2648	ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=29")
2649	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
2650
2651	// When cc_library sets use_apex_name_macro: true
2652	// apex variants define additional macro to distinguish which apex variant it is built for
2653
2654	// non-APEX variant does not have __ANDROID_APEX__ defined
2655	mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
2656	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
2657
2658	// APEX variant has __ANDROID_APEX__ defined
2659	mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
2660	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
2661	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
2662	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
2663
2664	// APEX variant has __ANDROID_APEX__ defined
2665	mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
2666	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
2667	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
2668	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
2669
2670	// recovery variant does not set __ANDROID_SDK_VERSION__
2671	mylibCFlags = ctx.ModuleForTests("mylib", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
2672	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
2673	ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
2674}
2675
2676func TestHeaderLibsDependency(t *testing.T) {
2677	ctx, _ := testApex(t, `
2678		apex {
2679			name: "myapex",
2680			key: "myapex.key",
2681			native_shared_libs: ["mylib"],
2682		}
2683
2684		apex_key {
2685			name: "myapex.key",
2686			public_key: "testkey.avbpubkey",
2687			private_key: "testkey.pem",
2688		}
2689
2690		cc_library_headers {
2691			name: "mylib_headers",
2692			export_include_dirs: ["my_include"],
2693			system_shared_libs: [],
2694			stl: "none",
2695			apex_available: [ "myapex" ],
2696		}
2697
2698		cc_library {
2699			name: "mylib",
2700			srcs: ["mylib.cpp"],
2701			system_shared_libs: [],
2702			stl: "none",
2703			header_libs: ["mylib_headers"],
2704			export_header_lib_headers: ["mylib_headers"],
2705			stubs: {
2706				versions: ["1", "2", "3"],
2707			},
2708			apex_available: [ "myapex" ],
2709		}
2710
2711		cc_library {
2712			name: "otherlib",
2713			srcs: ["mylib.cpp"],
2714			system_shared_libs: [],
2715			stl: "none",
2716			shared_libs: ["mylib"],
2717		}
2718	`)
2719
2720	cFlags := ctx.ModuleForTests("otherlib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
2721
2722	// Ensure that the include path of the header lib is exported to 'otherlib'
2723	ensureContains(t, cFlags, "-Imy_include")
2724}
2725
2726type fileInApex struct {
2727	path   string // path in apex
2728	src    string // src path
2729	isLink bool
2730}
2731
2732func getFiles(t *testing.T, ctx *android.TestContext, moduleName, variant string) []fileInApex {
2733	t.Helper()
2734	apexRule := ctx.ModuleForTests(moduleName, variant).Rule("apexRule")
2735	copyCmds := apexRule.Args["copy_commands"]
2736	imageApexDir := "/image.apex/"
2737	var ret []fileInApex
2738	for _, cmd := range strings.Split(copyCmds, "&&") {
2739		cmd = strings.TrimSpace(cmd)
2740		if cmd == "" {
2741			continue
2742		}
2743		terms := strings.Split(cmd, " ")
2744		var dst, src string
2745		var isLink bool
2746		switch terms[0] {
2747		case "mkdir":
2748		case "cp":
2749			if len(terms) != 3 && len(terms) != 4 {
2750				t.Fatal("copyCmds contains invalid cp command", cmd)
2751			}
2752			dst = terms[len(terms)-1]
2753			src = terms[len(terms)-2]
2754			isLink = false
2755		case "ln":
2756			if len(terms) != 3 && len(terms) != 4 {
2757				// ln LINK TARGET or ln -s LINK TARGET
2758				t.Fatal("copyCmds contains invalid ln command", cmd)
2759			}
2760			dst = terms[len(terms)-1]
2761			src = terms[len(terms)-2]
2762			isLink = true
2763		default:
2764			t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd)
2765		}
2766		if dst != "" {
2767			index := strings.Index(dst, imageApexDir)
2768			if index == -1 {
2769				t.Fatal("copyCmds should copy a file to image.apex/", cmd)
2770			}
2771			dstFile := dst[index+len(imageApexDir):]
2772			ret = append(ret, fileInApex{path: dstFile, src: src, isLink: isLink})
2773		}
2774	}
2775	return ret
2776}
2777
2778func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, variant string, files []string) {
2779	t.Helper()
2780	var failed bool
2781	var surplus []string
2782	filesMatched := make(map[string]bool)
2783	for _, file := range getFiles(t, ctx, moduleName, variant) {
2784		mactchFound := false
2785		for _, expected := range files {
2786			if matched, _ := path.Match(expected, file.path); matched {
2787				filesMatched[expected] = true
2788				mactchFound = true
2789				break
2790			}
2791		}
2792		if !mactchFound {
2793			surplus = append(surplus, file.path)
2794		}
2795	}
2796
2797	if len(surplus) > 0 {
2798		sort.Strings(surplus)
2799		t.Log("surplus files", surplus)
2800		failed = true
2801	}
2802
2803	if len(files) > len(filesMatched) {
2804		var missing []string
2805		for _, expected := range files {
2806			if !filesMatched[expected] {
2807				missing = append(missing, expected)
2808			}
2809		}
2810		sort.Strings(missing)
2811		t.Log("missing files", missing)
2812		failed = true
2813	}
2814	if failed {
2815		t.Fail()
2816	}
2817}
2818
2819func TestVndkApexCurrent(t *testing.T) {
2820	ctx, _ := testApex(t, `
2821		apex_vndk {
2822			name: "myapex",
2823			key: "myapex.key",
2824		}
2825
2826		apex_key {
2827			name: "myapex.key",
2828			public_key: "testkey.avbpubkey",
2829			private_key: "testkey.pem",
2830		}
2831
2832		cc_library {
2833			name: "libvndk",
2834			srcs: ["mylib.cpp"],
2835			vendor_available: true,
2836			vndk: {
2837				enabled: true,
2838			},
2839			system_shared_libs: [],
2840			stl: "none",
2841			apex_available: [ "myapex" ],
2842		}
2843
2844		cc_library {
2845			name: "libvndksp",
2846			srcs: ["mylib.cpp"],
2847			vendor_available: true,
2848			vndk: {
2849				enabled: true,
2850				support_system_process: true,
2851			},
2852			system_shared_libs: [],
2853			stl: "none",
2854			apex_available: [ "myapex" ],
2855		}
2856	`+vndkLibrariesTxtFiles("current"))
2857
2858	ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
2859		"lib/libvndk.so",
2860		"lib/libvndksp.so",
2861		"lib/libc++.so",
2862		"lib64/libvndk.so",
2863		"lib64/libvndksp.so",
2864		"lib64/libc++.so",
2865		"etc/llndk.libraries.VER.txt",
2866		"etc/vndkcore.libraries.VER.txt",
2867		"etc/vndksp.libraries.VER.txt",
2868		"etc/vndkprivate.libraries.VER.txt",
2869	})
2870}
2871
2872func TestVndkApexWithPrebuilt(t *testing.T) {
2873	ctx, _ := testApex(t, `
2874		apex_vndk {
2875			name: "myapex",
2876			key: "myapex.key",
2877		}
2878
2879		apex_key {
2880			name: "myapex.key",
2881			public_key: "testkey.avbpubkey",
2882			private_key: "testkey.pem",
2883		}
2884
2885		cc_prebuilt_library_shared {
2886			name: "libvndk",
2887			srcs: ["libvndk.so"],
2888			vendor_available: true,
2889			vndk: {
2890				enabled: true,
2891			},
2892			system_shared_libs: [],
2893			stl: "none",
2894			apex_available: [ "myapex" ],
2895		}
2896
2897		cc_prebuilt_library_shared {
2898			name: "libvndk.arm",
2899			srcs: ["libvndk.arm.so"],
2900			vendor_available: true,
2901			vndk: {
2902				enabled: true,
2903			},
2904			enabled: false,
2905			arch: {
2906				arm: {
2907					enabled: true,
2908				},
2909			},
2910			system_shared_libs: [],
2911			stl: "none",
2912			apex_available: [ "myapex" ],
2913		}
2914		`+vndkLibrariesTxtFiles("current"),
2915		withFiles(map[string][]byte{
2916			"libvndk.so":     nil,
2917			"libvndk.arm.so": nil,
2918		}))
2919
2920	ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
2921		"lib/libvndk.so",
2922		"lib/libvndk.arm.so",
2923		"lib64/libvndk.so",
2924		"lib/libc++.so",
2925		"lib64/libc++.so",
2926		"etc/*",
2927	})
2928}
2929
2930func vndkLibrariesTxtFiles(vers ...string) (result string) {
2931	for _, v := range vers {
2932		if v == "current" {
2933			for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate"} {
2934				result += `
2935					vndk_libraries_txt {
2936						name: "` + txt + `.libraries.txt",
2937					}
2938				`
2939			}
2940		} else {
2941			for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate"} {
2942				result += `
2943					prebuilt_etc {
2944						name: "` + txt + `.libraries.` + v + `.txt",
2945						src: "dummy.txt",
2946					}
2947				`
2948			}
2949		}
2950	}
2951	return
2952}
2953
2954func TestVndkApexVersion(t *testing.T) {
2955	ctx, _ := testApex(t, `
2956		apex_vndk {
2957			name: "myapex_v27",
2958			key: "myapex.key",
2959			file_contexts: ":myapex-file_contexts",
2960			vndk_version: "27",
2961		}
2962
2963		apex_key {
2964			name: "myapex.key",
2965			public_key: "testkey.avbpubkey",
2966			private_key: "testkey.pem",
2967		}
2968
2969		vndk_prebuilt_shared {
2970			name: "libvndk27",
2971			version: "27",
2972			vendor_available: true,
2973			vndk: {
2974				enabled: true,
2975			},
2976			target_arch: "arm64",
2977			arch: {
2978				arm: {
2979					srcs: ["libvndk27_arm.so"],
2980				},
2981				arm64: {
2982					srcs: ["libvndk27_arm64.so"],
2983				},
2984			},
2985			apex_available: [ "myapex_v27" ],
2986		}
2987
2988		vndk_prebuilt_shared {
2989			name: "libvndk27",
2990			version: "27",
2991			vendor_available: true,
2992			vndk: {
2993				enabled: true,
2994			},
2995			target_arch: "x86_64",
2996			arch: {
2997				x86: {
2998					srcs: ["libvndk27_x86.so"],
2999				},
3000				x86_64: {
3001					srcs: ["libvndk27_x86_64.so"],
3002				},
3003			},
3004		}
3005		`+vndkLibrariesTxtFiles("27"),
3006		withFiles(map[string][]byte{
3007			"libvndk27_arm.so":    nil,
3008			"libvndk27_arm64.so":  nil,
3009			"libvndk27_x86.so":    nil,
3010			"libvndk27_x86_64.so": nil,
3011		}))
3012
3013	ensureExactContents(t, ctx, "myapex_v27", "android_common_image", []string{
3014		"lib/libvndk27_arm.so",
3015		"lib64/libvndk27_arm64.so",
3016		"etc/*",
3017	})
3018}
3019
3020func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
3021	testApexError(t, `module "myapex_v27.*" .*: vndk_version: 27 is already defined in "myapex_v27.*"`, `
3022		apex_vndk {
3023			name: "myapex_v27",
3024			key: "myapex.key",
3025			file_contexts: ":myapex-file_contexts",
3026			vndk_version: "27",
3027		}
3028		apex_vndk {
3029			name: "myapex_v27_other",
3030			key: "myapex.key",
3031			file_contexts: ":myapex-file_contexts",
3032			vndk_version: "27",
3033		}
3034
3035		apex_key {
3036			name: "myapex.key",
3037			public_key: "testkey.avbpubkey",
3038			private_key: "testkey.pem",
3039		}
3040
3041		cc_library {
3042			name: "libvndk",
3043			srcs: ["mylib.cpp"],
3044			vendor_available: true,
3045			vndk: {
3046				enabled: true,
3047			},
3048			system_shared_libs: [],
3049			stl: "none",
3050		}
3051
3052		vndk_prebuilt_shared {
3053			name: "libvndk",
3054			version: "27",
3055			vendor_available: true,
3056			vndk: {
3057				enabled: true,
3058			},
3059			srcs: ["libvndk.so"],
3060		}
3061	`, withFiles(map[string][]byte{
3062		"libvndk.so": nil,
3063	}))
3064}
3065
3066func TestVndkApexNameRule(t *testing.T) {
3067	ctx, _ := testApex(t, `
3068		apex_vndk {
3069			name: "myapex",
3070			key: "myapex.key",
3071			file_contexts: ":myapex-file_contexts",
3072		}
3073		apex_vndk {
3074			name: "myapex_v28",
3075			key: "myapex.key",
3076			file_contexts: ":myapex-file_contexts",
3077			vndk_version: "28",
3078		}
3079		apex_key {
3080			name: "myapex.key",
3081			public_key: "testkey.avbpubkey",
3082			private_key: "testkey.pem",
3083		}`+vndkLibrariesTxtFiles("28", "current"))
3084
3085	assertApexName := func(expected, moduleName string) {
3086		bundle := ctx.ModuleForTests(moduleName, "android_common_image").Module().(*apexBundle)
3087		actual := proptools.String(bundle.properties.Apex_name)
3088		if !reflect.DeepEqual(actual, expected) {
3089			t.Errorf("Got '%v', expected '%v'", actual, expected)
3090		}
3091	}
3092
3093	assertApexName("com.android.vndk.vVER", "myapex")
3094	assertApexName("com.android.vndk.v28", "myapex_v28")
3095}
3096
3097func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
3098	ctx, _ := testApex(t, `
3099		apex_vndk {
3100			name: "myapex",
3101			key: "myapex.key",
3102			file_contexts: ":myapex-file_contexts",
3103		}
3104
3105		apex_key {
3106			name: "myapex.key",
3107			public_key: "testkey.avbpubkey",
3108			private_key: "testkey.pem",
3109		}
3110
3111		cc_library {
3112			name: "libvndk",
3113			srcs: ["mylib.cpp"],
3114			vendor_available: true,
3115			native_bridge_supported: true,
3116			host_supported: true,
3117			vndk: {
3118				enabled: true,
3119			},
3120			system_shared_libs: [],
3121			stl: "none",
3122			apex_available: [ "myapex" ],
3123		}
3124		`+vndkLibrariesTxtFiles("current"), withNativeBridgeEnabled)
3125
3126	ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
3127		"lib/libvndk.so",
3128		"lib64/libvndk.so",
3129		"lib/libc++.so",
3130		"lib64/libc++.so",
3131		"etc/*",
3132	})
3133}
3134
3135func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
3136	testApexError(t, `module "myapex" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
3137		apex_vndk {
3138			name: "myapex",
3139			key: "myapex.key",
3140			file_contexts: ":myapex-file_contexts",
3141			native_bridge_supported: true,
3142		}
3143
3144		apex_key {
3145			name: "myapex.key",
3146			public_key: "testkey.avbpubkey",
3147			private_key: "testkey.pem",
3148		}
3149
3150		cc_library {
3151			name: "libvndk",
3152			srcs: ["mylib.cpp"],
3153			vendor_available: true,
3154			native_bridge_supported: true,
3155			host_supported: true,
3156			vndk: {
3157				enabled: true,
3158			},
3159			system_shared_libs: [],
3160			stl: "none",
3161		}
3162	`)
3163}
3164
3165func TestVndkApexWithBinder32(t *testing.T) {
3166	ctx, _ := testApex(t, `
3167		apex_vndk {
3168			name: "myapex_v27",
3169			key: "myapex.key",
3170			file_contexts: ":myapex-file_contexts",
3171			vndk_version: "27",
3172		}
3173
3174		apex_key {
3175			name: "myapex.key",
3176			public_key: "testkey.avbpubkey",
3177			private_key: "testkey.pem",
3178		}
3179
3180		vndk_prebuilt_shared {
3181			name: "libvndk27",
3182			version: "27",
3183			target_arch: "arm",
3184			vendor_available: true,
3185			vndk: {
3186				enabled: true,
3187			},
3188			arch: {
3189				arm: {
3190					srcs: ["libvndk27.so"],
3191				}
3192			},
3193		}
3194
3195		vndk_prebuilt_shared {
3196			name: "libvndk27",
3197			version: "27",
3198			target_arch: "arm",
3199			binder32bit: true,
3200			vendor_available: true,
3201			vndk: {
3202				enabled: true,
3203			},
3204			arch: {
3205				arm: {
3206					srcs: ["libvndk27binder32.so"],
3207				}
3208			},
3209			apex_available: [ "myapex_v27" ],
3210		}
3211		`+vndkLibrariesTxtFiles("27"),
3212		withFiles(map[string][]byte{
3213			"libvndk27.so":         nil,
3214			"libvndk27binder32.so": nil,
3215		}),
3216		withBinder32bit,
3217		withTargets(map[android.OsType][]android.Target{
3218			android.Android: []android.Target{
3219				{Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
3220					NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
3221			},
3222		}),
3223	)
3224
3225	ensureExactContents(t, ctx, "myapex_v27", "android_common_image", []string{
3226		"lib/libvndk27binder32.so",
3227		"etc/*",
3228	})
3229}
3230
3231func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
3232	ctx, _ := testApex(t, `
3233		apex_vndk {
3234			name: "myapex",
3235			key: "myapex.key",
3236			file_contexts: ":myapex-file_contexts",
3237		}
3238
3239		apex_key {
3240			name: "myapex.key",
3241			public_key: "testkey.avbpubkey",
3242			private_key: "testkey.pem",
3243		}
3244
3245		cc_library {
3246			name: "libz",
3247			vendor_available: true,
3248			vndk: {
3249				enabled: true,
3250			},
3251			stubs: {
3252				symbol_file: "libz.map.txt",
3253				versions: ["30"],
3254			}
3255		}
3256	`+vndkLibrariesTxtFiles("current"), withFiles(map[string][]byte{
3257		"libz.map.txt": nil,
3258	}))
3259
3260	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_image").Rule("apexManifestRule")
3261	provideNativeLibs := names(apexManifestRule.Args["provideNativeLibs"])
3262	ensureListEmpty(t, provideNativeLibs)
3263}
3264
3265func TestDependenciesInApexManifest(t *testing.T) {
3266	ctx, _ := testApex(t, `
3267		apex {
3268			name: "myapex_nodep",
3269			key: "myapex.key",
3270			native_shared_libs: ["lib_nodep"],
3271			compile_multilib: "both",
3272			file_contexts: ":myapex-file_contexts",
3273		}
3274
3275		apex {
3276			name: "myapex_dep",
3277			key: "myapex.key",
3278			native_shared_libs: ["lib_dep"],
3279			compile_multilib: "both",
3280			file_contexts: ":myapex-file_contexts",
3281		}
3282
3283		apex {
3284			name: "myapex_provider",
3285			key: "myapex.key",
3286			native_shared_libs: ["libfoo"],
3287			compile_multilib: "both",
3288			file_contexts: ":myapex-file_contexts",
3289		}
3290
3291		apex {
3292			name: "myapex_selfcontained",
3293			key: "myapex.key",
3294			native_shared_libs: ["lib_dep", "libfoo"],
3295			compile_multilib: "both",
3296			file_contexts: ":myapex-file_contexts",
3297		}
3298
3299		apex_key {
3300			name: "myapex.key",
3301			public_key: "testkey.avbpubkey",
3302			private_key: "testkey.pem",
3303		}
3304
3305		cc_library {
3306			name: "lib_nodep",
3307			srcs: ["mylib.cpp"],
3308			system_shared_libs: [],
3309			stl: "none",
3310			apex_available: [ "myapex_nodep" ],
3311		}
3312
3313		cc_library {
3314			name: "lib_dep",
3315			srcs: ["mylib.cpp"],
3316			shared_libs: ["libfoo"],
3317			system_shared_libs: [],
3318			stl: "none",
3319			apex_available: [
3320				"myapex_dep",
3321				"myapex_provider",
3322				"myapex_selfcontained",
3323			],
3324		}
3325
3326		cc_library {
3327			name: "libfoo",
3328			srcs: ["mytest.cpp"],
3329			stubs: {
3330				versions: ["1"],
3331			},
3332			system_shared_libs: [],
3333			stl: "none",
3334			apex_available: [
3335				"myapex_provider",
3336				"myapex_selfcontained",
3337			],
3338		}
3339	`)
3340
3341	var apexManifestRule android.TestingBuildParams
3342	var provideNativeLibs, requireNativeLibs []string
3343
3344	apexManifestRule = ctx.ModuleForTests("myapex_nodep", "android_common_myapex_nodep_image").Rule("apexManifestRule")
3345	provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
3346	requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
3347	ensureListEmpty(t, provideNativeLibs)
3348	ensureListEmpty(t, requireNativeLibs)
3349
3350	apexManifestRule = ctx.ModuleForTests("myapex_dep", "android_common_myapex_dep_image").Rule("apexManifestRule")
3351	provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
3352	requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
3353	ensureListEmpty(t, provideNativeLibs)
3354	ensureListContains(t, requireNativeLibs, "libfoo.so")
3355
3356	apexManifestRule = ctx.ModuleForTests("myapex_provider", "android_common_myapex_provider_image").Rule("apexManifestRule")
3357	provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
3358	requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
3359	ensureListContains(t, provideNativeLibs, "libfoo.so")
3360	ensureListEmpty(t, requireNativeLibs)
3361
3362	apexManifestRule = ctx.ModuleForTests("myapex_selfcontained", "android_common_myapex_selfcontained_image").Rule("apexManifestRule")
3363	provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
3364	requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
3365	ensureListContains(t, provideNativeLibs, "libfoo.so")
3366	ensureListEmpty(t, requireNativeLibs)
3367}
3368
3369func TestApexName(t *testing.T) {
3370	ctx, config := testApex(t, `
3371		apex {
3372			name: "myapex",
3373			key: "myapex.key",
3374			apex_name: "com.android.myapex",
3375			native_shared_libs: ["mylib"],
3376		}
3377
3378		apex_key {
3379			name: "myapex.key",
3380			public_key: "testkey.avbpubkey",
3381			private_key: "testkey.pem",
3382		}
3383
3384		cc_library {
3385			name: "mylib",
3386			srcs: ["mylib.cpp"],
3387			system_shared_libs: [],
3388			stl: "none",
3389			apex_available: [
3390				"//apex_available:platform",
3391				"myapex",
3392			],
3393		}
3394	`)
3395
3396	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
3397	apexManifestRule := module.Rule("apexManifestRule")
3398	ensureContains(t, apexManifestRule.Args["opt"], "-v name com.android.myapex")
3399	apexRule := module.Rule("apexRule")
3400	ensureContains(t, apexRule.Args["opt_flags"], "--do_not_check_keyname")
3401
3402	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
3403	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
3404	name := apexBundle.BaseModuleName()
3405	prefix := "TARGET_"
3406	var builder strings.Builder
3407	data.Custom(&builder, name, prefix, "", data)
3408	androidMk := builder.String()
3409	ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
3410	ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
3411}
3412
3413func TestNonTestApex(t *testing.T) {
3414	ctx, _ := testApex(t, `
3415		apex {
3416			name: "myapex",
3417			key: "myapex.key",
3418			native_shared_libs: ["mylib_common"],
3419		}
3420
3421		apex_key {
3422			name: "myapex.key",
3423			public_key: "testkey.avbpubkey",
3424			private_key: "testkey.pem",
3425		}
3426
3427		cc_library {
3428			name: "mylib_common",
3429			srcs: ["mylib.cpp"],
3430			system_shared_libs: [],
3431			stl: "none",
3432			apex_available: [
3433					"//apex_available:platform",
3434				  "myapex",
3435		  ],
3436		}
3437	`)
3438
3439	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
3440	apexRule := module.Rule("apexRule")
3441	copyCmds := apexRule.Args["copy_commands"]
3442
3443	if apex, ok := module.Module().(*apexBundle); !ok || apex.testApex {
3444		t.Log("Apex was a test apex!")
3445		t.Fail()
3446	}
3447	// Ensure that main rule creates an output
3448	ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
3449
3450	// Ensure that apex variant is created for the direct dep
3451	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_myapex")
3452
3453	// Ensure that both direct and indirect deps are copied into apex
3454	ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
3455
3456	// Ensure that the platform variant ends with _shared
3457	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared")
3458
3459	if !android.InAnyApex("mylib_common") {
3460		t.Log("Found mylib_common not in any apex!")
3461		t.Fail()
3462	}
3463}
3464
3465func TestTestApex(t *testing.T) {
3466	if android.InAnyApex("mylib_common_test") {
3467		t.Fatal("mylib_common_test must not be used in any other tests since this checks that global state is not updated in an illegal way!")
3468	}
3469	ctx, _ := testApex(t, `
3470		apex_test {
3471			name: "myapex",
3472			key: "myapex.key",
3473			native_shared_libs: ["mylib_common_test"],
3474		}
3475
3476		apex_key {
3477			name: "myapex.key",
3478			public_key: "testkey.avbpubkey",
3479			private_key: "testkey.pem",
3480		}
3481
3482		cc_library {
3483			name: "mylib_common_test",
3484			srcs: ["mylib.cpp"],
3485			system_shared_libs: [],
3486			stl: "none",
3487			// TODO: remove //apex_available:platform
3488			apex_available: [
3489				"//apex_available:platform",
3490				"myapex",
3491			],
3492		}
3493	`)
3494
3495	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
3496	apexRule := module.Rule("apexRule")
3497	copyCmds := apexRule.Args["copy_commands"]
3498
3499	if apex, ok := module.Module().(*apexBundle); !ok || !apex.testApex {
3500		t.Log("Apex was not a test apex!")
3501		t.Fail()
3502	}
3503	// Ensure that main rule creates an output
3504	ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
3505
3506	// Ensure that apex variant is created for the direct dep
3507	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared_myapex")
3508
3509	// Ensure that both direct and indirect deps are copied into apex
3510	ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so")
3511
3512	// Ensure that the platform variant ends with _shared
3513	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared")
3514}
3515
3516func TestApexWithTarget(t *testing.T) {
3517	ctx, _ := testApex(t, `
3518		apex {
3519			name: "myapex",
3520			key: "myapex.key",
3521			multilib: {
3522				first: {
3523					native_shared_libs: ["mylib_common"],
3524				}
3525			},
3526			target: {
3527				android: {
3528					multilib: {
3529						first: {
3530							native_shared_libs: ["mylib"],
3531						}
3532					}
3533				},
3534				host: {
3535					multilib: {
3536						first: {
3537							native_shared_libs: ["mylib2"],
3538						}
3539					}
3540				}
3541			}
3542		}
3543
3544		apex_key {
3545			name: "myapex.key",
3546			public_key: "testkey.avbpubkey",
3547			private_key: "testkey.pem",
3548		}
3549
3550		cc_library {
3551			name: "mylib",
3552			srcs: ["mylib.cpp"],
3553			system_shared_libs: [],
3554			stl: "none",
3555			// TODO: remove //apex_available:platform
3556			apex_available: [
3557				"//apex_available:platform",
3558				"myapex",
3559			],
3560		}
3561
3562		cc_library {
3563			name: "mylib_common",
3564			srcs: ["mylib.cpp"],
3565			system_shared_libs: [],
3566			stl: "none",
3567			compile_multilib: "first",
3568			// TODO: remove //apex_available:platform
3569			apex_available: [
3570				"//apex_available:platform",
3571				"myapex",
3572			],
3573		}
3574
3575		cc_library {
3576			name: "mylib2",
3577			srcs: ["mylib.cpp"],
3578			system_shared_libs: [],
3579			stl: "none",
3580			compile_multilib: "first",
3581		}
3582	`)
3583
3584	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
3585	copyCmds := apexRule.Args["copy_commands"]
3586
3587	// Ensure that main rule creates an output
3588	ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
3589
3590	// Ensure that apex variant is created for the direct dep
3591	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
3592	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_myapex")
3593	ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
3594
3595	// Ensure that both direct and indirect deps are copied into apex
3596	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
3597	ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
3598	ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
3599
3600	// Ensure that the platform variant ends with _shared
3601	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared")
3602	ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared")
3603	ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared")
3604}
3605
3606func TestApexWithShBinary(t *testing.T) {
3607	ctx, _ := testApex(t, `
3608		apex {
3609			name: "myapex",
3610			key: "myapex.key",
3611			binaries: ["myscript"],
3612		}
3613
3614		apex_key {
3615			name: "myapex.key",
3616			public_key: "testkey.avbpubkey",
3617			private_key: "testkey.pem",
3618		}
3619
3620		sh_binary {
3621			name: "myscript",
3622			src: "mylib.cpp",
3623			filename: "myscript.sh",
3624			sub_dir: "script",
3625		}
3626	`)
3627
3628	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
3629	copyCmds := apexRule.Args["copy_commands"]
3630
3631	ensureContains(t, copyCmds, "image.apex/bin/script/myscript.sh")
3632}
3633
3634func TestApexInVariousPartition(t *testing.T) {
3635	testcases := []struct {
3636		propName, parition, flattenedPartition string
3637	}{
3638		{"", "system", "system_ext"},
3639		{"product_specific: true", "product", "product"},
3640		{"soc_specific: true", "vendor", "vendor"},
3641		{"proprietary: true", "vendor", "vendor"},
3642		{"vendor: true", "vendor", "vendor"},
3643		{"system_ext_specific: true", "system_ext", "system_ext"},
3644	}
3645	for _, tc := range testcases {
3646		t.Run(tc.propName+":"+tc.parition, func(t *testing.T) {
3647			ctx, _ := testApex(t, `
3648				apex {
3649					name: "myapex",
3650					key: "myapex.key",
3651					`+tc.propName+`
3652				}
3653
3654				apex_key {
3655					name: "myapex.key",
3656					public_key: "testkey.avbpubkey",
3657					private_key: "testkey.pem",
3658				}
3659			`)
3660
3661			apex := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
3662			expected := buildDir + "/target/product/test_device/" + tc.parition + "/apex"
3663			actual := apex.installDir.String()
3664			if actual != expected {
3665				t.Errorf("wrong install path. expected %q. actual %q", expected, actual)
3666			}
3667
3668			flattened := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
3669			expected = buildDir + "/target/product/test_device/" + tc.flattenedPartition + "/apex"
3670			actual = flattened.installDir.String()
3671			if actual != expected {
3672				t.Errorf("wrong install path. expected %q. actual %q", expected, actual)
3673			}
3674		})
3675	}
3676}
3677
3678func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) {
3679	ctx, _ := testApex(t, `
3680		apex {
3681			name: "myapex",
3682			key: "myapex.key",
3683		}
3684
3685		apex_key {
3686			name: "myapex.key",
3687			public_key: "testkey.avbpubkey",
3688			private_key: "testkey.pem",
3689		}
3690	`)
3691	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
3692	rule := module.Output("file_contexts")
3693	ensureContains(t, rule.RuleParams.Command, "cat system/sepolicy/apex/myapex-file_contexts")
3694}
3695
3696func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes(t *testing.T) {
3697	testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, `
3698		apex {
3699			name: "myapex",
3700			key: "myapex.key",
3701			file_contexts: "my_own_file_contexts",
3702		}
3703
3704		apex_key {
3705			name: "myapex.key",
3706			public_key: "testkey.avbpubkey",
3707			private_key: "testkey.pem",
3708		}
3709	`, withFiles(map[string][]byte{
3710		"my_own_file_contexts": nil,
3711	}))
3712}
3713
3714func TestFileContexts_ProductSpecificApexes(t *testing.T) {
3715	testApexError(t, `"myapex" .*: file_contexts: cannot find`, `
3716		apex {
3717			name: "myapex",
3718			key: "myapex.key",
3719			product_specific: true,
3720			file_contexts: "product_specific_file_contexts",
3721		}
3722
3723		apex_key {
3724			name: "myapex.key",
3725			public_key: "testkey.avbpubkey",
3726			private_key: "testkey.pem",
3727		}
3728	`)
3729
3730	ctx, _ := testApex(t, `
3731		apex {
3732			name: "myapex",
3733			key: "myapex.key",
3734			product_specific: true,
3735			file_contexts: "product_specific_file_contexts",
3736		}
3737
3738		apex_key {
3739			name: "myapex.key",
3740			public_key: "testkey.avbpubkey",
3741			private_key: "testkey.pem",
3742		}
3743	`, withFiles(map[string][]byte{
3744		"product_specific_file_contexts": nil,
3745	}))
3746	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
3747	rule := module.Output("file_contexts")
3748	ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
3749}
3750
3751func TestFileContexts_SetViaFileGroup(t *testing.T) {
3752	ctx, _ := testApex(t, `
3753		apex {
3754			name: "myapex",
3755			key: "myapex.key",
3756			product_specific: true,
3757			file_contexts: ":my-file-contexts",
3758		}
3759
3760		apex_key {
3761			name: "myapex.key",
3762			public_key: "testkey.avbpubkey",
3763			private_key: "testkey.pem",
3764		}
3765
3766		filegroup {
3767			name: "my-file-contexts",
3768			srcs: ["product_specific_file_contexts"],
3769		}
3770	`, withFiles(map[string][]byte{
3771		"product_specific_file_contexts": nil,
3772	}))
3773	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
3774	rule := module.Output("file_contexts")
3775	ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
3776}
3777
3778func TestApexKeyFromOtherModule(t *testing.T) {
3779	ctx, _ := testApex(t, `
3780		apex_key {
3781			name: "myapex.key",
3782			public_key: ":my.avbpubkey",
3783			private_key: ":my.pem",
3784			product_specific: true,
3785		}
3786
3787		filegroup {
3788			name: "my.avbpubkey",
3789			srcs: ["testkey2.avbpubkey"],
3790		}
3791
3792		filegroup {
3793			name: "my.pem",
3794			srcs: ["testkey2.pem"],
3795		}
3796	`)
3797
3798	apex_key := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey)
3799	expected_pubkey := "testkey2.avbpubkey"
3800	actual_pubkey := apex_key.public_key_file.String()
3801	if actual_pubkey != expected_pubkey {
3802		t.Errorf("wrong public key path. expected %q. actual %q", expected_pubkey, actual_pubkey)
3803	}
3804	expected_privkey := "testkey2.pem"
3805	actual_privkey := apex_key.private_key_file.String()
3806	if actual_privkey != expected_privkey {
3807		t.Errorf("wrong private key path. expected %q. actual %q", expected_privkey, actual_privkey)
3808	}
3809}
3810
3811func TestPrebuilt(t *testing.T) {
3812	ctx, _ := testApex(t, `
3813		prebuilt_apex {
3814			name: "myapex",
3815			arch: {
3816				arm64: {
3817					src: "myapex-arm64.apex",
3818				},
3819				arm: {
3820					src: "myapex-arm.apex",
3821				},
3822			},
3823		}
3824	`)
3825
3826	prebuilt := ctx.ModuleForTests("myapex", "android_common").Module().(*Prebuilt)
3827
3828	expectedInput := "myapex-arm64.apex"
3829	if prebuilt.inputApex.String() != expectedInput {
3830		t.Errorf("inputApex invalid. expected: %q, actual: %q", expectedInput, prebuilt.inputApex.String())
3831	}
3832}
3833
3834func TestPrebuiltFilenameOverride(t *testing.T) {
3835	ctx, _ := testApex(t, `
3836		prebuilt_apex {
3837			name: "myapex",
3838			src: "myapex-arm.apex",
3839			filename: "notmyapex.apex",
3840		}
3841	`)
3842
3843	p := ctx.ModuleForTests("myapex", "android_common").Module().(*Prebuilt)
3844
3845	expected := "notmyapex.apex"
3846	if p.installFilename != expected {
3847		t.Errorf("installFilename invalid. expected: %q, actual: %q", expected, p.installFilename)
3848	}
3849}
3850
3851func TestPrebuiltOverrides(t *testing.T) {
3852	ctx, config := testApex(t, `
3853		prebuilt_apex {
3854			name: "myapex.prebuilt",
3855			src: "myapex-arm.apex",
3856			overrides: [
3857				"myapex",
3858			],
3859		}
3860	`)
3861
3862	p := ctx.ModuleForTests("myapex.prebuilt", "android_common").Module().(*Prebuilt)
3863
3864	expected := []string{"myapex"}
3865	actual := android.AndroidMkEntriesForTest(t, config, "", p)[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
3866	if !reflect.DeepEqual(actual, expected) {
3867		t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES value '%s', expected '%s'", actual, expected)
3868	}
3869}
3870
3871func TestApexWithTests(t *testing.T) {
3872	ctx, config := testApex(t, `
3873		apex_test {
3874			name: "myapex",
3875			key: "myapex.key",
3876			tests: [
3877				"mytest",
3878				"mytests",
3879			],
3880		}
3881
3882		apex_key {
3883			name: "myapex.key",
3884			public_key: "testkey.avbpubkey",
3885			private_key: "testkey.pem",
3886		}
3887
3888		filegroup {
3889			name: "fg",
3890			srcs: [
3891				"baz",
3892				"bar/baz"
3893			],
3894		}
3895
3896		cc_test {
3897			name: "mytest",
3898			gtest: false,
3899			srcs: ["mytest.cpp"],
3900			relative_install_path: "test",
3901			shared_libs: ["mylib"],
3902			system_shared_libs: [],
3903			static_executable: true,
3904			stl: "none",
3905			data: [":fg"],
3906		}
3907
3908		cc_library {
3909			name: "mylib",
3910			srcs: ["mylib.cpp"],
3911			system_shared_libs: [],
3912			stl: "none",
3913		}
3914
3915		filegroup {
3916			name: "fg2",
3917			srcs: [
3918				"testdata/baz"
3919			],
3920		}
3921
3922		cc_test {
3923			name: "mytests",
3924			gtest: false,
3925			srcs: [
3926				"mytest1.cpp",
3927				"mytest2.cpp",
3928				"mytest3.cpp",
3929			],
3930			test_per_src: true,
3931			relative_install_path: "test",
3932			system_shared_libs: [],
3933			static_executable: true,
3934			stl: "none",
3935			data: [
3936				":fg",
3937				":fg2",
3938			],
3939		}
3940	`)
3941
3942	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
3943	copyCmds := apexRule.Args["copy_commands"]
3944
3945	// Ensure that test dep (and their transitive dependencies) are copied into apex.
3946	ensureContains(t, copyCmds, "image.apex/bin/test/mytest")
3947	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
3948
3949	//Ensure that test data are copied into apex.
3950	ensureContains(t, copyCmds, "image.apex/bin/test/baz")
3951	ensureContains(t, copyCmds, "image.apex/bin/test/bar/baz")
3952
3953	// Ensure that test deps built with `test_per_src` are copied into apex.
3954	ensureContains(t, copyCmds, "image.apex/bin/test/mytest1")
3955	ensureContains(t, copyCmds, "image.apex/bin/test/mytest2")
3956	ensureContains(t, copyCmds, "image.apex/bin/test/mytest3")
3957
3958	// Ensure the module is correctly translated.
3959	bundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
3960	data := android.AndroidMkDataForTest(t, config, "", bundle)
3961	name := bundle.BaseModuleName()
3962	prefix := "TARGET_"
3963	var builder strings.Builder
3964	data.Custom(&builder, name, prefix, "", data)
3965	androidMk := builder.String()
3966	ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n")
3967	ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n")
3968	ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n")
3969	ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n")
3970	ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex\n")
3971	ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n")
3972	ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")
3973
3974	flatBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
3975	data = android.AndroidMkDataForTest(t, config, "", flatBundle)
3976	data.Custom(&builder, name, prefix, "", data)
3977	flatAndroidMk := builder.String()
3978	ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :baz :bar/baz\n")
3979	ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :testdata/baz\n")
3980}
3981
3982func TestInstallExtraFlattenedApexes(t *testing.T) {
3983	ctx, config := testApex(t, `
3984		apex {
3985			name: "myapex",
3986			key: "myapex.key",
3987		}
3988		apex_key {
3989			name: "myapex.key",
3990			public_key: "testkey.avbpubkey",
3991			private_key: "testkey.pem",
3992		}
3993	`, func(fs map[string][]byte, config android.Config) {
3994		config.TestProductVariables.InstallExtraFlattenedApexes = proptools.BoolPtr(true)
3995	})
3996	ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
3997	ensureListContains(t, ab.requiredDeps, "myapex.flattened")
3998	mk := android.AndroidMkDataForTest(t, config, "", ab)
3999	var builder strings.Builder
4000	mk.Custom(&builder, ab.Name(), "TARGET_", "", mk)
4001	androidMk := builder.String()
4002	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += myapex.flattened")
4003}
4004
4005func TestApexUsesOtherApex(t *testing.T) {
4006	ctx, _ := testApex(t, `
4007		apex {
4008			name: "myapex",
4009			key: "myapex.key",
4010			native_shared_libs: ["mylib"],
4011			uses: ["commonapex"],
4012		}
4013
4014		apex {
4015			name: "commonapex",
4016			key: "myapex.key",
4017			native_shared_libs: ["libcommon"],
4018			provide_cpp_shared_libs: true,
4019		}
4020
4021		apex_key {
4022			name: "myapex.key",
4023			public_key: "testkey.avbpubkey",
4024			private_key: "testkey.pem",
4025		}
4026
4027		cc_library {
4028			name: "mylib",
4029			srcs: ["mylib.cpp"],
4030			shared_libs: ["libcommon"],
4031			system_shared_libs: [],
4032			stl: "none",
4033			apex_available: [ "myapex" ],
4034		}
4035
4036		cc_library {
4037			name: "libcommon",
4038			srcs: ["mylib_common.cpp"],
4039			system_shared_libs: [],
4040			stl: "none",
4041			// TODO: remove //apex_available:platform
4042			apex_available: [
4043				"//apex_available:platform",
4044				"commonapex",
4045				"myapex",
4046			],
4047		}
4048	`)
4049
4050	module1 := ctx.ModuleForTests("myapex", "android_common_myapex_image")
4051	apexRule1 := module1.Rule("apexRule")
4052	copyCmds1 := apexRule1.Args["copy_commands"]
4053
4054	module2 := ctx.ModuleForTests("commonapex", "android_common_commonapex_image")
4055	apexRule2 := module2.Rule("apexRule")
4056	copyCmds2 := apexRule2.Args["copy_commands"]
4057
4058	ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
4059	ensureListContains(t, ctx.ModuleVariantsForTests("libcommon"), "android_arm64_armv8-a_shared_commonapex")
4060	ensureContains(t, copyCmds1, "image.apex/lib64/mylib.so")
4061	ensureContains(t, copyCmds2, "image.apex/lib64/libcommon.so")
4062	ensureNotContains(t, copyCmds1, "image.apex/lib64/libcommon.so")
4063}
4064
4065func TestApexUsesFailsIfNotProvided(t *testing.T) {
4066	testApexError(t, `uses: "commonapex" does not provide native_shared_libs`, `
4067		apex {
4068			name: "myapex",
4069			key: "myapex.key",
4070			uses: ["commonapex"],
4071		}
4072
4073		apex {
4074			name: "commonapex",
4075			key: "myapex.key",
4076		}
4077
4078		apex_key {
4079			name: "myapex.key",
4080			public_key: "testkey.avbpubkey",
4081			private_key: "testkey.pem",
4082		}
4083	`)
4084	testApexError(t, `uses: "commonapex" is not a provider`, `
4085		apex {
4086			name: "myapex",
4087			key: "myapex.key",
4088			uses: ["commonapex"],
4089		}
4090
4091		cc_library {
4092			name: "commonapex",
4093			system_shared_libs: [],
4094			stl: "none",
4095		}
4096
4097		apex_key {
4098			name: "myapex.key",
4099			public_key: "testkey.avbpubkey",
4100			private_key: "testkey.pem",
4101		}
4102	`)
4103}
4104
4105func TestApexUsesFailsIfUseVenderMismatch(t *testing.T) {
4106	testApexError(t, `use_vendor: "commonapex" has different value of use_vendor`, `
4107		apex {
4108			name: "myapex",
4109			key: "myapex.key",
4110			use_vendor: true,
4111			uses: ["commonapex"],
4112		}
4113
4114		apex {
4115			name: "commonapex",
4116			key: "myapex.key",
4117			provide_cpp_shared_libs: true,
4118		}
4119
4120		apex_key {
4121			name: "myapex.key",
4122			public_key: "testkey.avbpubkey",
4123			private_key: "testkey.pem",
4124		}
4125	`, func(fs map[string][]byte, config android.Config) {
4126		setUseVendorAllowListForTest(config, []string{"myapex"})
4127	})
4128}
4129
4130func TestErrorsIfDepsAreNotEnabled(t *testing.T) {
4131	testApexError(t, `module "myapex" .* depends on disabled module "libfoo"`, `
4132		apex {
4133			name: "myapex",
4134			key: "myapex.key",
4135			native_shared_libs: ["libfoo"],
4136		}
4137
4138		apex_key {
4139			name: "myapex.key",
4140			public_key: "testkey.avbpubkey",
4141			private_key: "testkey.pem",
4142		}
4143
4144		cc_library {
4145			name: "libfoo",
4146			stl: "none",
4147			system_shared_libs: [],
4148			enabled: false,
4149			apex_available: ["myapex"],
4150		}
4151	`)
4152	testApexError(t, `module "myapex" .* depends on disabled module "myjar"`, `
4153		apex {
4154			name: "myapex",
4155			key: "myapex.key",
4156			java_libs: ["myjar"],
4157		}
4158
4159		apex_key {
4160			name: "myapex.key",
4161			public_key: "testkey.avbpubkey",
4162			private_key: "testkey.pem",
4163		}
4164
4165		java_library {
4166			name: "myjar",
4167			srcs: ["foo/bar/MyClass.java"],
4168			sdk_version: "none",
4169			system_modules: "none",
4170			enabled: false,
4171			apex_available: ["myapex"],
4172		}
4173	`)
4174}
4175
4176func TestApexWithApps(t *testing.T) {
4177	ctx, _ := testApex(t, `
4178		apex {
4179			name: "myapex",
4180			key: "myapex.key",
4181			apps: [
4182				"AppFoo",
4183				"AppFooPriv",
4184			],
4185		}
4186
4187		apex_key {
4188			name: "myapex.key",
4189			public_key: "testkey.avbpubkey",
4190			private_key: "testkey.pem",
4191		}
4192
4193		android_app {
4194			name: "AppFoo",
4195			srcs: ["foo/bar/MyClass.java"],
4196			sdk_version: "current",
4197			system_modules: "none",
4198			jni_libs: ["libjni"],
4199			stl: "none",
4200			apex_available: [ "myapex" ],
4201		}
4202
4203		android_app {
4204			name: "AppFooPriv",
4205			srcs: ["foo/bar/MyClass.java"],
4206			sdk_version: "current",
4207			system_modules: "none",
4208			privileged: true,
4209			stl: "none",
4210			apex_available: [ "myapex" ],
4211		}
4212
4213		cc_library_shared {
4214			name: "libjni",
4215			srcs: ["mylib.cpp"],
4216			shared_libs: ["libfoo"],
4217			stl: "none",
4218			system_shared_libs: [],
4219			apex_available: [ "myapex" ],
4220			sdk_version: "current",
4221		}
4222
4223		cc_library_shared {
4224			name: "libfoo",
4225			stl: "none",
4226			system_shared_libs: [],
4227			apex_available: [ "myapex" ],
4228			sdk_version: "current",
4229		}
4230	`)
4231
4232	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
4233	apexRule := module.Rule("apexRule")
4234	copyCmds := apexRule.Args["copy_commands"]
4235
4236	ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
4237	ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk")
4238
4239	appZipRule := ctx.ModuleForTests("AppFoo", "android_common_myapex").Description("zip jni libs")
4240	// JNI libraries are uncompressed
4241	if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") {
4242		t.Errorf("jni libs are not uncompressed for AppFoo")
4243	}
4244	// JNI libraries including transitive deps are
4245	for _, jni := range []string{"libjni", "libfoo"} {
4246		jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_myapex").Module().(*cc.Module).OutputFile()
4247		// ... embedded inside APK (jnilibs.zip)
4248		ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
4249		// ... and not directly inside the APEX
4250		ensureNotContains(t, copyCmds, "image.apex/lib64/"+jni+".so")
4251	}
4252}
4253
4254func TestApexWithAppImports(t *testing.T) {
4255	ctx, _ := testApex(t, `
4256		apex {
4257			name: "myapex",
4258			key: "myapex.key",
4259			apps: [
4260				"AppFooPrebuilt",
4261				"AppFooPrivPrebuilt",
4262			],
4263		}
4264
4265		apex_key {
4266			name: "myapex.key",
4267			public_key: "testkey.avbpubkey",
4268			private_key: "testkey.pem",
4269		}
4270
4271		android_app_import {
4272			name: "AppFooPrebuilt",
4273			apk: "PrebuiltAppFoo.apk",
4274			presigned: true,
4275			dex_preopt: {
4276				enabled: false,
4277			},
4278			apex_available: ["myapex"],
4279		}
4280
4281		android_app_import {
4282			name: "AppFooPrivPrebuilt",
4283			apk: "PrebuiltAppFooPriv.apk",
4284			privileged: true,
4285			presigned: true,
4286			dex_preopt: {
4287				enabled: false,
4288			},
4289			filename: "AwesomePrebuiltAppFooPriv.apk",
4290			apex_available: ["myapex"],
4291		}
4292	`)
4293
4294	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
4295	apexRule := module.Rule("apexRule")
4296	copyCmds := apexRule.Args["copy_commands"]
4297
4298	ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt/AppFooPrebuilt.apk")
4299	ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AwesomePrebuiltAppFooPriv.apk")
4300}
4301
4302func TestApexWithAppImportsPrefer(t *testing.T) {
4303	ctx, _ := testApex(t, `
4304		apex {
4305			name: "myapex",
4306			key: "myapex.key",
4307			apps: [
4308				"AppFoo",
4309			],
4310		}
4311
4312		apex_key {
4313			name: "myapex.key",
4314			public_key: "testkey.avbpubkey",
4315			private_key: "testkey.pem",
4316		}
4317
4318		android_app {
4319			name: "AppFoo",
4320			srcs: ["foo/bar/MyClass.java"],
4321			sdk_version: "none",
4322			system_modules: "none",
4323			apex_available: [ "myapex" ],
4324		}
4325
4326		android_app_import {
4327			name: "AppFoo",
4328			apk: "AppFooPrebuilt.apk",
4329			filename: "AppFooPrebuilt.apk",
4330			presigned: true,
4331			prefer: true,
4332			apex_available: ["myapex"],
4333		}
4334	`, withFiles(map[string][]byte{
4335		"AppFooPrebuilt.apk": nil,
4336	}))
4337
4338	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
4339		"app/AppFoo/AppFooPrebuilt.apk",
4340	})
4341}
4342
4343func TestApexWithTestHelperApp(t *testing.T) {
4344	ctx, _ := testApex(t, `
4345		apex {
4346			name: "myapex",
4347			key: "myapex.key",
4348			apps: [
4349				"TesterHelpAppFoo",
4350			],
4351		}
4352
4353		apex_key {
4354			name: "myapex.key",
4355			public_key: "testkey.avbpubkey",
4356			private_key: "testkey.pem",
4357		}
4358
4359		android_test_helper_app {
4360			name: "TesterHelpAppFoo",
4361			srcs: ["foo/bar/MyClass.java"],
4362			apex_available: [ "myapex" ],
4363		}
4364
4365	`)
4366
4367	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
4368	apexRule := module.Rule("apexRule")
4369	copyCmds := apexRule.Args["copy_commands"]
4370
4371	ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo/TesterHelpAppFoo.apk")
4372}
4373
4374func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
4375	// libfoo's apex_available comes from cc_defaults
4376	testApexError(t, `requires "libfoo" that is not available for the APEX`, `
4377	apex {
4378		name: "myapex",
4379		key: "myapex.key",
4380		native_shared_libs: ["libfoo"],
4381	}
4382
4383	apex_key {
4384		name: "myapex.key",
4385		public_key: "testkey.avbpubkey",
4386		private_key: "testkey.pem",
4387	}
4388
4389	apex {
4390		name: "otherapex",
4391		key: "myapex.key",
4392		native_shared_libs: ["libfoo"],
4393	}
4394
4395	cc_defaults {
4396		name: "libfoo-defaults",
4397		apex_available: ["otherapex"],
4398	}
4399
4400	cc_library {
4401		name: "libfoo",
4402		defaults: ["libfoo-defaults"],
4403		stl: "none",
4404		system_shared_libs: [],
4405	}`)
4406}
4407
4408func TestApexAvailable_DirectDep(t *testing.T) {
4409	// libfoo is not available to myapex, but only to otherapex
4410	testApexError(t, "requires \"libfoo\" that is not available for the APEX", `
4411	apex {
4412		name: "myapex",
4413		key: "myapex.key",
4414		native_shared_libs: ["libfoo"],
4415	}
4416
4417	apex_key {
4418		name: "myapex.key",
4419		public_key: "testkey.avbpubkey",
4420		private_key: "testkey.pem",
4421	}
4422
4423	apex {
4424		name: "otherapex",
4425		key: "otherapex.key",
4426		native_shared_libs: ["libfoo"],
4427	}
4428
4429	apex_key {
4430		name: "otherapex.key",
4431		public_key: "testkey.avbpubkey",
4432		private_key: "testkey.pem",
4433	}
4434
4435	cc_library {
4436		name: "libfoo",
4437		stl: "none",
4438		system_shared_libs: [],
4439		apex_available: ["otherapex"],
4440	}`)
4441}
4442
4443func TestApexAvailable_IndirectDep(t *testing.T) {
4444	// libbbaz is an indirect dep
4445	testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path:
4446.*via tag apex\.dependencyTag.*"sharedLib".*
4447.*-> libfoo.*link:shared.*
4448.*via tag cc\.DependencyTag.*"shared".*
4449.*-> libbar.*link:shared.*
4450.*via tag cc\.DependencyTag.*"shared".*
4451.*-> libbaz.*link:shared.*`, `
4452	apex {
4453		name: "myapex",
4454		key: "myapex.key",
4455		native_shared_libs: ["libfoo"],
4456	}
4457
4458	apex_key {
4459		name: "myapex.key",
4460		public_key: "testkey.avbpubkey",
4461		private_key: "testkey.pem",
4462	}
4463
4464	cc_library {
4465		name: "libfoo",
4466		stl: "none",
4467		shared_libs: ["libbar"],
4468		system_shared_libs: [],
4469		apex_available: ["myapex"],
4470	}
4471
4472	cc_library {
4473		name: "libbar",
4474		stl: "none",
4475		shared_libs: ["libbaz"],
4476		system_shared_libs: [],
4477		apex_available: ["myapex"],
4478	}
4479
4480	cc_library {
4481		name: "libbaz",
4482		stl: "none",
4483		system_shared_libs: [],
4484	}`)
4485}
4486
4487func TestApexAvailable_InvalidApexName(t *testing.T) {
4488	testApexError(t, "\"otherapex\" is not a valid module name", `
4489	apex {
4490		name: "myapex",
4491		key: "myapex.key",
4492		native_shared_libs: ["libfoo"],
4493	}
4494
4495	apex_key {
4496		name: "myapex.key",
4497		public_key: "testkey.avbpubkey",
4498		private_key: "testkey.pem",
4499	}
4500
4501	cc_library {
4502		name: "libfoo",
4503		stl: "none",
4504		system_shared_libs: [],
4505		apex_available: ["otherapex"],
4506	}`)
4507
4508	testApex(t, `
4509	apex {
4510		name: "myapex",
4511		key: "myapex.key",
4512		native_shared_libs: ["libfoo", "libbar"],
4513	}
4514
4515	apex_key {
4516		name: "myapex.key",
4517		public_key: "testkey.avbpubkey",
4518		private_key: "testkey.pem",
4519	}
4520
4521	cc_library {
4522		name: "libfoo",
4523		stl: "none",
4524		system_shared_libs: [],
4525		runtime_libs: ["libbaz"],
4526		apex_available: ["myapex"],
4527	}
4528
4529	cc_library {
4530		name: "libbar",
4531		stl: "none",
4532		system_shared_libs: [],
4533		apex_available: ["//apex_available:anyapex"],
4534	}
4535
4536	cc_library {
4537		name: "libbaz",
4538		stl: "none",
4539		system_shared_libs: [],
4540		stubs: {
4541			versions: ["10", "20", "30"],
4542		},
4543	}`)
4544}
4545
4546func TestApexAvailable_CheckForPlatform(t *testing.T) {
4547	ctx, _ := testApex(t, `
4548	apex {
4549		name: "myapex",
4550		key: "myapex.key",
4551		native_shared_libs: ["libbar", "libbaz"],
4552	}
4553
4554	apex_key {
4555		name: "myapex.key",
4556		public_key: "testkey.avbpubkey",
4557		private_key: "testkey.pem",
4558	}
4559
4560	cc_library {
4561		name: "libfoo",
4562		stl: "none",
4563		system_shared_libs: [],
4564		shared_libs: ["libbar"],
4565		apex_available: ["//apex_available:platform"],
4566	}
4567
4568	cc_library {
4569		name: "libfoo2",
4570		stl: "none",
4571		system_shared_libs: [],
4572		shared_libs: ["libbaz"],
4573		apex_available: ["//apex_available:platform"],
4574	}
4575
4576	cc_library {
4577		name: "libbar",
4578		stl: "none",
4579		system_shared_libs: [],
4580		apex_available: ["myapex"],
4581	}
4582
4583	cc_library {
4584		name: "libbaz",
4585		stl: "none",
4586		system_shared_libs: [],
4587		apex_available: ["myapex"],
4588		stubs: {
4589			versions: ["1"],
4590		},
4591	}`)
4592
4593	// libfoo shouldn't be available to platform even though it has "//apex_available:platform",
4594	// because it depends on libbar which isn't available to platform
4595	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
4596	if libfoo.NotAvailableForPlatform() != true {
4597		t.Errorf("%q shouldn't be available to platform", libfoo.String())
4598	}
4599
4600	// libfoo2 however can be available to platform because it depends on libbaz which provides
4601	// stubs
4602	libfoo2 := ctx.ModuleForTests("libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module)
4603	if libfoo2.NotAvailableForPlatform() == true {
4604		t.Errorf("%q should be available to platform", libfoo2.String())
4605	}
4606}
4607
4608func TestApexAvailable_CreatedForApex(t *testing.T) {
4609	ctx, _ := testApex(t, `
4610	apex {
4611		name: "myapex",
4612		key: "myapex.key",
4613		native_shared_libs: ["libfoo"],
4614	}
4615
4616	apex_key {
4617		name: "myapex.key",
4618		public_key: "testkey.avbpubkey",
4619		private_key: "testkey.pem",
4620	}
4621
4622	cc_library {
4623		name: "libfoo",
4624		stl: "none",
4625		system_shared_libs: [],
4626		apex_available: ["myapex"],
4627		static: {
4628			apex_available: ["//apex_available:platform"],
4629		},
4630	}`)
4631
4632	libfooShared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
4633	if libfooShared.NotAvailableForPlatform() != true {
4634		t.Errorf("%q shouldn't be available to platform", libfooShared.String())
4635	}
4636	libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module)
4637	if libfooStatic.NotAvailableForPlatform() != false {
4638		t.Errorf("%q should be available to platform", libfooStatic.String())
4639	}
4640}
4641
4642func TestOverrideApex(t *testing.T) {
4643	ctx, config := testApex(t, `
4644		apex {
4645			name: "myapex",
4646			key: "myapex.key",
4647			apps: ["app"],
4648			overrides: ["oldapex"],
4649		}
4650
4651		override_apex {
4652			name: "override_myapex",
4653			base: "myapex",
4654			apps: ["override_app"],
4655			overrides: ["unknownapex"],
4656			logging_parent: "com.foo.bar",
4657			package_name: "test.overridden.package",
4658		}
4659
4660		apex_key {
4661			name: "myapex.key",
4662			public_key: "testkey.avbpubkey",
4663			private_key: "testkey.pem",
4664		}
4665
4666		android_app {
4667			name: "app",
4668			srcs: ["foo/bar/MyClass.java"],
4669			package_name: "foo",
4670			sdk_version: "none",
4671			system_modules: "none",
4672			apex_available: [ "myapex" ],
4673		}
4674
4675		override_android_app {
4676			name: "override_app",
4677			base: "app",
4678			package_name: "bar",
4679		}
4680	`, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"}))
4681
4682	originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(android.OverridableModule)
4683	overriddenVariant := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image").Module().(android.OverridableModule)
4684	if originalVariant.GetOverriddenBy() != "" {
4685		t.Errorf("GetOverriddenBy should be empty, but was %q", originalVariant.GetOverriddenBy())
4686	}
4687	if overriddenVariant.GetOverriddenBy() != "override_myapex" {
4688		t.Errorf("GetOverriddenBy should be \"override_myapex\", but was %q", overriddenVariant.GetOverriddenBy())
4689	}
4690
4691	module := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image")
4692	apexRule := module.Rule("apexRule")
4693	copyCmds := apexRule.Args["copy_commands"]
4694
4695	ensureNotContains(t, copyCmds, "image.apex/app/app/app.apk")
4696	ensureContains(t, copyCmds, "image.apex/app/override_app/override_app.apk")
4697
4698	apexBundle := module.Module().(*apexBundle)
4699	name := apexBundle.Name()
4700	if name != "override_myapex" {
4701		t.Errorf("name should be \"override_myapex\", but was %q", name)
4702	}
4703
4704	if apexBundle.overridableProperties.Logging_parent != "com.foo.bar" {
4705		t.Errorf("override_myapex should have logging parent (com.foo.bar), but was %q.", apexBundle.overridableProperties.Logging_parent)
4706	}
4707
4708	optFlags := apexRule.Args["opt_flags"]
4709	ensureContains(t, optFlags, "--override_apk_package_name test.overridden.package")
4710
4711	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
4712	var builder strings.Builder
4713	data.Custom(&builder, name, "TARGET_", "", data)
4714	androidMk := builder.String()
4715	ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex")
4716	ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex")
4717	ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex")
4718	ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex")
4719	ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex")
4720	ensureNotContains(t, androidMk, "LOCAL_MODULE := override_app.myapex")
4721	ensureNotContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex")
4722	ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex")
4723}
4724
4725func TestLegacyAndroid10Support(t *testing.T) {
4726	ctx, _ := testApex(t, `
4727		apex {
4728			name: "myapex",
4729			key: "myapex.key",
4730			native_shared_libs: ["mylib"],
4731			min_sdk_version: "29",
4732		}
4733
4734		apex_key {
4735			name: "myapex.key",
4736			public_key: "testkey.avbpubkey",
4737			private_key: "testkey.pem",
4738		}
4739
4740		cc_library {
4741			name: "mylib",
4742			srcs: ["mylib.cpp"],
4743			stl: "libc++",
4744			system_shared_libs: [],
4745			apex_available: [ "myapex" ],
4746			min_sdk_version: "29",
4747		}
4748	`, withUnbundledBuild)
4749
4750	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
4751	args := module.Rule("apexRule").Args
4752	ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
4753	ensureNotContains(t, args["opt_flags"], "--no_hashtree")
4754
4755	// The copies of the libraries in the apex should have one more dependency than
4756	// the ones outside the apex, namely the unwinder. Ideally we should check
4757	// the dependency names directly here but for some reason the names are blank in
4758	// this test.
4759	for _, lib := range []string{"libc++", "mylib"} {
4760		apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_myapex").Rule("ld").Implicits
4761		nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
4762		if len(apexImplicits) != len(nonApexImplicits)+1 {
4763			t.Errorf("%q missing unwinder dep", lib)
4764		}
4765	}
4766}
4767
4768var filesForSdkLibrary = map[string][]byte{
4769	"api/current.txt":        nil,
4770	"api/removed.txt":        nil,
4771	"api/system-current.txt": nil,
4772	"api/system-removed.txt": nil,
4773	"api/test-current.txt":   nil,
4774	"api/test-removed.txt":   nil,
4775
4776	// For java_sdk_library_import
4777	"a.jar": nil,
4778}
4779
4780func TestJavaSDKLibrary(t *testing.T) {
4781	ctx, _ := testApex(t, `
4782		apex {
4783			name: "myapex",
4784			key: "myapex.key",
4785			java_libs: ["foo"],
4786		}
4787
4788		apex_key {
4789			name: "myapex.key",
4790			public_key: "testkey.avbpubkey",
4791			private_key: "testkey.pem",
4792		}
4793
4794		java_sdk_library {
4795			name: "foo",
4796			srcs: ["a.java"],
4797			api_packages: ["foo"],
4798			apex_available: [ "myapex" ],
4799		}
4800	`, withFiles(filesForSdkLibrary))
4801
4802	// java_sdk_library installs both impl jar and permission XML
4803	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
4804		"javalib/foo.jar",
4805		"etc/permissions/foo.xml",
4806	})
4807	// Permission XML should point to the activated path of impl jar of java_sdk_library
4808	sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Rule("java_sdk_xml")
4809	ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`)
4810}
4811
4812func TestJavaSDKLibrary_WithinApex(t *testing.T) {
4813	ctx, _ := testApex(t, `
4814		apex {
4815			name: "myapex",
4816			key: "myapex.key",
4817			java_libs: ["foo", "bar"],
4818		}
4819
4820		apex_key {
4821			name: "myapex.key",
4822			public_key: "testkey.avbpubkey",
4823			private_key: "testkey.pem",
4824		}
4825
4826		java_sdk_library {
4827			name: "foo",
4828			srcs: ["a.java"],
4829			api_packages: ["foo"],
4830			apex_available: ["myapex"],
4831			sdk_version: "none",
4832			system_modules: "none",
4833		}
4834
4835		java_library {
4836			name: "bar",
4837			srcs: ["a.java"],
4838			libs: ["foo"],
4839			apex_available: ["myapex"],
4840			sdk_version: "none",
4841			system_modules: "none",
4842		}
4843	`, withFiles(filesForSdkLibrary))
4844
4845	// java_sdk_library installs both impl jar and permission XML
4846	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
4847		"javalib/bar.jar",
4848		"javalib/foo.jar",
4849		"etc/permissions/foo.xml",
4850	})
4851
4852	// The bar library should depend on the implementation jar.
4853	barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
4854	if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
4855		t.Errorf("expected %q, found %#q", expected, actual)
4856	}
4857}
4858
4859func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
4860	ctx, _ := testApex(t, `
4861		apex {
4862			name: "myapex",
4863			key: "myapex.key",
4864			java_libs: ["foo"],
4865		}
4866
4867		apex_key {
4868			name: "myapex.key",
4869			public_key: "testkey.avbpubkey",
4870			private_key: "testkey.pem",
4871		}
4872
4873		java_sdk_library {
4874			name: "foo",
4875			srcs: ["a.java"],
4876			api_packages: ["foo"],
4877			apex_available: ["myapex"],
4878			sdk_version: "none",
4879			system_modules: "none",
4880		}
4881
4882		java_library {
4883			name: "bar",
4884			srcs: ["a.java"],
4885			libs: ["foo"],
4886			sdk_version: "none",
4887			system_modules: "none",
4888		}
4889	`, withFiles(filesForSdkLibrary))
4890
4891	// java_sdk_library installs both impl jar and permission XML
4892	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
4893		"javalib/foo.jar",
4894		"etc/permissions/foo.xml",
4895	})
4896
4897	// The bar library should depend on the stubs jar.
4898	barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac")
4899	if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
4900		t.Errorf("expected %q, found %#q", expected, actual)
4901	}
4902}
4903
4904func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
4905	ctx, _ := testApex(t, ``,
4906		withFiles(map[string][]byte{
4907			"apex/a.java":             nil,
4908			"apex/apex_manifest.json": nil,
4909			"apex/Android.bp": []byte(`
4910		package {
4911			default_visibility: ["//visibility:private"],
4912		}
4913
4914		apex {
4915			name: "myapex",
4916			key: "myapex.key",
4917			java_libs: ["foo", "bar"],
4918		}
4919
4920		apex_key {
4921			name: "myapex.key",
4922			public_key: "testkey.avbpubkey",
4923			private_key: "testkey.pem",
4924		}
4925
4926		java_library {
4927			name: "bar",
4928			srcs: ["a.java"],
4929			libs: ["foo"],
4930			apex_available: ["myapex"],
4931			sdk_version: "none",
4932			system_modules: "none",
4933		}
4934`),
4935			"source/a.java":          nil,
4936			"source/api/current.txt": nil,
4937			"source/api/removed.txt": nil,
4938			"source/Android.bp": []byte(`
4939		package {
4940			default_visibility: ["//visibility:private"],
4941		}
4942
4943		java_sdk_library {
4944			name: "foo",
4945			visibility: ["//apex"],
4946			srcs: ["a.java"],
4947			api_packages: ["foo"],
4948			apex_available: ["myapex"],
4949			sdk_version: "none",
4950			system_modules: "none",
4951			public: {
4952				enabled: true,
4953			},
4954		}
4955`),
4956			"prebuilt/a.jar": nil,
4957			"prebuilt/Android.bp": []byte(`
4958		package {
4959			default_visibility: ["//visibility:private"],
4960		}
4961
4962		java_sdk_library_import {
4963			name: "foo",
4964			visibility: ["//apex", "//source"],
4965			apex_available: ["myapex"],
4966			prefer: true,
4967			public: {
4968				jars: ["a.jar"],
4969			},
4970		}
4971`),
4972		}),
4973	)
4974
4975	// java_sdk_library installs both impl jar and permission XML
4976	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
4977		"javalib/bar.jar",
4978		"javalib/foo.jar",
4979		"etc/permissions/foo.xml",
4980	})
4981
4982	// The bar library should depend on the implementation jar.
4983	barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
4984	if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.impl\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
4985		t.Errorf("expected %q, found %#q", expected, actual)
4986	}
4987}
4988
4989func TestJavaSDKLibrary_ImportOnly(t *testing.T) {
4990	testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, `
4991		apex {
4992			name: "myapex",
4993			key: "myapex.key",
4994			java_libs: ["foo"],
4995		}
4996
4997		apex_key {
4998			name: "myapex.key",
4999			public_key: "testkey.avbpubkey",
5000			private_key: "testkey.pem",
5001		}
5002
5003		java_sdk_library_import {
5004			name: "foo",
5005			apex_available: ["myapex"],
5006			prefer: true,
5007			public: {
5008				jars: ["a.jar"],
5009			},
5010		}
5011
5012	`, withFiles(filesForSdkLibrary))
5013}
5014
5015func TestCompatConfig(t *testing.T) {
5016	ctx, _ := testApex(t, `
5017		apex {
5018			name: "myapex",
5019			key: "myapex.key",
5020			prebuilts: ["myjar-platform-compat-config"],
5021			java_libs: ["myjar"],
5022		}
5023
5024		apex_key {
5025			name: "myapex.key",
5026			public_key: "testkey.avbpubkey",
5027			private_key: "testkey.pem",
5028		}
5029
5030		platform_compat_config {
5031		    name: "myjar-platform-compat-config",
5032		    src: ":myjar",
5033		}
5034
5035		java_library {
5036			name: "myjar",
5037			srcs: ["foo/bar/MyClass.java"],
5038			sdk_version: "none",
5039			system_modules: "none",
5040			apex_available: [ "myapex" ],
5041		}
5042	`)
5043	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
5044		"etc/compatconfig/myjar-platform-compat-config.xml",
5045		"javalib/myjar.jar",
5046	})
5047}
5048
5049func TestRejectNonInstallableJavaLibrary(t *testing.T) {
5050	testApexError(t, `"myjar" is not configured to be compiled into dex`, `
5051		apex {
5052			name: "myapex",
5053			key: "myapex.key",
5054			java_libs: ["myjar"],
5055		}
5056
5057		apex_key {
5058			name: "myapex.key",
5059			public_key: "testkey.avbpubkey",
5060			private_key: "testkey.pem",
5061		}
5062
5063		java_library {
5064			name: "myjar",
5065			srcs: ["foo/bar/MyClass.java"],
5066			sdk_version: "none",
5067			system_modules: "none",
5068			compile_dex: false,
5069			apex_available: ["myapex"],
5070		}
5071	`)
5072}
5073
5074func TestCarryRequiredModuleNames(t *testing.T) {
5075	ctx, config := testApex(t, `
5076		apex {
5077			name: "myapex",
5078			key: "myapex.key",
5079			native_shared_libs: ["mylib"],
5080		}
5081
5082		apex_key {
5083			name: "myapex.key",
5084			public_key: "testkey.avbpubkey",
5085			private_key: "testkey.pem",
5086		}
5087
5088		cc_library {
5089			name: "mylib",
5090			srcs: ["mylib.cpp"],
5091			system_shared_libs: [],
5092			stl: "none",
5093			required: ["a", "b"],
5094			host_required: ["c", "d"],
5095			target_required: ["e", "f"],
5096			apex_available: [ "myapex" ],
5097		}
5098	`)
5099
5100	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
5101	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
5102	name := apexBundle.BaseModuleName()
5103	prefix := "TARGET_"
5104	var builder strings.Builder
5105	data.Custom(&builder, name, prefix, "", data)
5106	androidMk := builder.String()
5107	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += a b\n")
5108	ensureContains(t, androidMk, "LOCAL_HOST_REQUIRED_MODULES += c d\n")
5109	ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES += e f\n")
5110}
5111
5112func TestSymlinksFromApexToSystem(t *testing.T) {
5113	bp := `
5114		apex {
5115			name: "myapex",
5116			key: "myapex.key",
5117			native_shared_libs: ["mylib"],
5118			java_libs: ["myjar"],
5119		}
5120
5121		apex {
5122			name: "myapex.updatable",
5123			key: "myapex.key",
5124			native_shared_libs: ["mylib"],
5125			java_libs: ["myjar"],
5126			updatable: true,
5127			min_sdk_version: "current",
5128		}
5129
5130		apex_key {
5131			name: "myapex.key",
5132			public_key: "testkey.avbpubkey",
5133			private_key: "testkey.pem",
5134		}
5135
5136		cc_library {
5137			name: "mylib",
5138			srcs: ["mylib.cpp"],
5139			shared_libs: ["myotherlib"],
5140			system_shared_libs: [],
5141			stl: "none",
5142			apex_available: [
5143				"myapex",
5144				"myapex.updatable",
5145				"//apex_available:platform",
5146			],
5147			min_sdk_version: "current",
5148		}
5149
5150		cc_library {
5151			name: "myotherlib",
5152			srcs: ["mylib.cpp"],
5153			system_shared_libs: [],
5154			stl: "none",
5155			apex_available: [
5156				"myapex",
5157				"myapex.updatable",
5158				"//apex_available:platform",
5159			],
5160			min_sdk_version: "current",
5161		}
5162
5163		java_library {
5164			name: "myjar",
5165			srcs: ["foo/bar/MyClass.java"],
5166			sdk_version: "none",
5167			system_modules: "none",
5168			libs: ["myotherjar"],
5169			apex_available: [
5170				"myapex",
5171				"myapex.updatable",
5172				"//apex_available:platform",
5173			],
5174			min_sdk_version: "current",
5175		}
5176
5177		java_library {
5178			name: "myotherjar",
5179			srcs: ["foo/bar/MyClass.java"],
5180			sdk_version: "none",
5181			system_modules: "none",
5182			apex_available: [
5183				"myapex",
5184				"myapex.updatable",
5185				"//apex_available:platform",
5186			],
5187			min_sdk_version: "current",
5188		}
5189	`
5190
5191	ensureRealfileExists := func(t *testing.T, files []fileInApex, file string) {
5192		for _, f := range files {
5193			if f.path == file {
5194				if f.isLink {
5195					t.Errorf("%q is not a real file", file)
5196				}
5197				return
5198			}
5199		}
5200		t.Errorf("%q is not found", file)
5201	}
5202
5203	ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string) {
5204		for _, f := range files {
5205			if f.path == file {
5206				if !f.isLink {
5207					t.Errorf("%q is not a symlink", file)
5208				}
5209				return
5210			}
5211		}
5212		t.Errorf("%q is not found", file)
5213	}
5214
5215	// For unbundled build, symlink shouldn't exist regardless of whether an APEX
5216	// is updatable or not
5217	ctx, _ := testApex(t, bp, withUnbundledBuild)
5218	files := getFiles(t, ctx, "myapex", "android_common_myapex_image")
5219	ensureRealfileExists(t, files, "javalib/myjar.jar")
5220	ensureRealfileExists(t, files, "lib64/mylib.so")
5221	ensureRealfileExists(t, files, "lib64/myotherlib.so")
5222
5223	files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
5224	ensureRealfileExists(t, files, "javalib/myjar.jar")
5225	ensureRealfileExists(t, files, "lib64/mylib.so")
5226	ensureRealfileExists(t, files, "lib64/myotherlib.so")
5227
5228	// For bundled build, symlink to the system for the non-updatable APEXes only
5229	ctx, _ = testApex(t, bp)
5230	files = getFiles(t, ctx, "myapex", "android_common_myapex_image")
5231	ensureRealfileExists(t, files, "javalib/myjar.jar")
5232	ensureRealfileExists(t, files, "lib64/mylib.so")
5233	ensureSymlinkExists(t, files, "lib64/myotherlib.so") // this is symlink
5234
5235	files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
5236	ensureRealfileExists(t, files, "javalib/myjar.jar")
5237	ensureRealfileExists(t, files, "lib64/mylib.so")
5238	ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
5239}
5240
5241func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
5242	ctx, config := testApex(t, `
5243		apex {
5244			name: "myapex",
5245			key: "myapex.key",
5246			native_shared_libs: ["mylib"],
5247		}
5248
5249		apex_key {
5250			name: "myapex.key",
5251			public_key: "testkey.avbpubkey",
5252			private_key: "testkey.pem",
5253		}
5254
5255		cc_library_shared {
5256			name: "mylib",
5257			srcs: ["mylib.cpp"],
5258			shared_libs: ["myotherlib"],
5259			system_shared_libs: [],
5260			stl: "none",
5261			apex_available: [
5262				"myapex",
5263				"//apex_available:platform",
5264			],
5265		}
5266
5267		cc_prebuilt_library_shared {
5268			name: "myotherlib",
5269			srcs: ["prebuilt.so"],
5270			system_shared_libs: [],
5271			stl: "none",
5272			apex_available: [
5273				"myapex",
5274				"//apex_available:platform",
5275			],
5276		}
5277	`)
5278
5279	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
5280	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
5281	var builder strings.Builder
5282	data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
5283	androidMk := builder.String()
5284	// `myotherlib` is added to `myapex` as symlink
5285	ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
5286	ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n")
5287	ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n")
5288	// `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib`
5289	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += mylib.myapex myotherlib apex_manifest.pb.myapex apex_pubkey.myapex\n")
5290}
5291
5292func TestApexWithJniLibs(t *testing.T) {
5293	ctx, _ := testApex(t, `
5294		apex {
5295			name: "myapex",
5296			key: "myapex.key",
5297			jni_libs: ["mylib"],
5298		}
5299
5300		apex_key {
5301			name: "myapex.key",
5302			public_key: "testkey.avbpubkey",
5303			private_key: "testkey.pem",
5304		}
5305
5306		cc_library {
5307			name: "mylib",
5308			srcs: ["mylib.cpp"],
5309			shared_libs: ["mylib2"],
5310			system_shared_libs: [],
5311			stl: "none",
5312			apex_available: [ "myapex" ],
5313		}
5314
5315		cc_library {
5316			name: "mylib2",
5317			srcs: ["mylib.cpp"],
5318			system_shared_libs: [],
5319			stl: "none",
5320			apex_available: [ "myapex" ],
5321		}
5322	`)
5323
5324	rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
5325	// Notice mylib2.so (transitive dep) is not added as a jni_lib
5326	ensureEquals(t, rule.Args["opt"], "-a jniLibs mylib.so")
5327	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
5328		"lib64/mylib.so",
5329		"lib64/mylib2.so",
5330	})
5331}
5332
5333func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
5334	ctx, _ := testApex(t, `
5335		apex {
5336			name: "myapex",
5337			key: "myapex.key",
5338		}
5339		apex_key {
5340			name: "myapex.key",
5341			public_key: "testkey.avbpubkey",
5342			private_key: "testkey.pem",
5343		}
5344	`, func(fs map[string][]byte, config android.Config) {
5345		delete(config.Targets, android.Android)
5346		config.AndroidCommonTarget = android.Target{}
5347	})
5348
5349	if expected, got := []string{""}, ctx.ModuleVariantsForTests("myapex"); !reflect.DeepEqual(expected, got) {
5350		t.Errorf("Expected variants: %v, but got: %v", expected, got)
5351	}
5352}
5353
5354func TestApexWithJniLibs_Errors(t *testing.T) {
5355	testApexError(t, `jni_libs: "xxx" is not a cc_library`, `
5356		apex {
5357			name: "myapex",
5358			key: "myapex.key",
5359			jni_libs: ["xxx"],
5360		}
5361
5362		apex_key {
5363			name: "myapex.key",
5364			public_key: "testkey.avbpubkey",
5365			private_key: "testkey.pem",
5366		}
5367
5368		prebuilt_etc {
5369			name: "xxx",
5370			src: "xxx",
5371		}
5372	`, withFiles(map[string][]byte{
5373		"xxx": nil,
5374	}))
5375}
5376
5377func TestAppBundle(t *testing.T) {
5378	ctx, _ := testApex(t, `
5379		apex {
5380			name: "myapex",
5381			key: "myapex.key",
5382			apps: ["AppFoo"],
5383		}
5384
5385		apex_key {
5386			name: "myapex.key",
5387			public_key: "testkey.avbpubkey",
5388			private_key: "testkey.pem",
5389		}
5390
5391		android_app {
5392			name: "AppFoo",
5393			srcs: ["foo/bar/MyClass.java"],
5394			sdk_version: "none",
5395			system_modules: "none",
5396			apex_available: [ "myapex" ],
5397		}
5398		`, withManifestPackageNameOverrides([]string{"AppFoo:com.android.foo"}))
5399
5400	bundleConfigRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Description("Bundle Config")
5401	content := bundleConfigRule.Args["content"]
5402
5403	ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
5404	ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`)
5405}
5406
5407func TestAppSetBundle(t *testing.T) {
5408	ctx, _ := testApex(t, `
5409		apex {
5410			name: "myapex",
5411			key: "myapex.key",
5412			apps: ["AppSet"],
5413		}
5414
5415		apex_key {
5416			name: "myapex.key",
5417			public_key: "testkey.avbpubkey",
5418			private_key: "testkey.pem",
5419		}
5420
5421		android_app_set {
5422			name: "AppSet",
5423			set: "AppSet.apks",
5424		}`)
5425	mod := ctx.ModuleForTests("myapex", "android_common_myapex_image")
5426	bundleConfigRule := mod.Description("Bundle Config")
5427	content := bundleConfigRule.Args["content"]
5428	ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
5429	s := mod.Rule("apexRule").Args["copy_commands"]
5430	copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
5431	if len(copyCmds) != 3 {
5432		t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
5433	}
5434	ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet$")
5435	ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet$")
5436	ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$")
5437}
5438
5439func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
5440	t.Helper()
5441
5442	bp := `
5443		java_library {
5444			name: "some-updatable-apex-lib",
5445			srcs: ["a.java"],
5446			sdk_version: "current",
5447			apex_available: [
5448				"some-updatable-apex",
5449			],
5450		}
5451
5452		java_library {
5453			name: "some-non-updatable-apex-lib",
5454			srcs: ["a.java"],
5455			apex_available: [
5456				"some-non-updatable-apex",
5457			],
5458		}
5459
5460		java_library {
5461			name: "some-platform-lib",
5462			srcs: ["a.java"],
5463			sdk_version: "current",
5464			installable: true,
5465		}
5466
5467		java_library {
5468			name: "some-art-lib",
5469			srcs: ["a.java"],
5470			sdk_version: "current",
5471			apex_available: [
5472				"com.android.art.something",
5473			],
5474			hostdex: true,
5475		}
5476
5477		apex {
5478			name: "some-updatable-apex",
5479			key: "some-updatable-apex.key",
5480			java_libs: ["some-updatable-apex-lib"],
5481			updatable: true,
5482			min_sdk_version: "current",
5483		}
5484
5485		apex {
5486			name: "some-non-updatable-apex",
5487			key: "some-non-updatable-apex.key",
5488			java_libs: ["some-non-updatable-apex-lib"],
5489		}
5490
5491		apex_key {
5492			name: "some-updatable-apex.key",
5493		}
5494
5495		apex_key {
5496			name: "some-non-updatable-apex.key",
5497		}
5498
5499		apex {
5500			name: "com.android.art.something",
5501			key: "com.android.art.something.key",
5502			java_libs: ["some-art-lib"],
5503			updatable: true,
5504			min_sdk_version: "current",
5505		}
5506
5507		apex_key {
5508			name: "com.android.art.something.key",
5509		}
5510
5511		filegroup {
5512			name: "some-updatable-apex-file_contexts",
5513			srcs: [
5514				"system/sepolicy/apex/some-updatable-apex-file_contexts",
5515			],
5516		}
5517
5518		filegroup {
5519			name: "some-non-updatable-apex-file_contexts",
5520			srcs: [
5521				"system/sepolicy/apex/some-non-updatable-apex-file_contexts",
5522			],
5523		}
5524	`
5525	bp += cc.GatherRequiredDepsForTest(android.Android)
5526	bp += java.GatherRequiredDepsForTest()
5527	bp += dexpreopt.BpToolModulesForTest()
5528
5529	fs := map[string][]byte{
5530		"a.java":                             nil,
5531		"a.jar":                              nil,
5532		"build/make/target/product/security": nil,
5533		"apex_manifest.json":                 nil,
5534		"AndroidManifest.xml":                nil,
5535		"system/sepolicy/apex/some-updatable-apex-file_contexts":       nil,
5536		"system/sepolicy/apex/some-non-updatable-apex-file_contexts":   nil,
5537		"system/sepolicy/apex/com.android.art.something-file_contexts": nil,
5538		"framework/aidl/a.aidl": nil,
5539	}
5540	cc.GatherRequiredFilesForTest(fs)
5541
5542	ctx := android.NewTestArchContext()
5543	ctx.RegisterModuleType("apex", BundleFactory)
5544	ctx.RegisterModuleType("apex_key", ApexKeyFactory)
5545	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
5546	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
5547	android.RegisterPrebuiltMutators(ctx)
5548	cc.RegisterRequiredBuildComponentsForTest(ctx)
5549	java.RegisterJavaBuildComponents(ctx)
5550	java.RegisterSystemModulesBuildComponents(ctx)
5551	java.RegisterAppBuildComponents(ctx)
5552	java.RegisterDexpreoptBootJarsComponents(ctx)
5553	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
5554	ctx.PreDepsMutators(RegisterPreDepsMutators)
5555	ctx.PostDepsMutators(RegisterPostDepsMutators)
5556
5557	config := android.TestArchConfig(buildDir, nil, bp, fs)
5558	ctx.Register(config)
5559
5560	_ = dexpreopt.GlobalSoongConfigForTests(config)
5561	dexpreopt.RegisterToolModulesForTest(ctx)
5562	pathCtx := android.PathContextForTesting(config)
5563	dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
5564	transformDexpreoptConfig(dexpreoptConfig)
5565	dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
5566
5567	_, errs := ctx.ParseBlueprintsFiles("Android.bp")
5568	android.FailIfErrored(t, errs)
5569
5570	_, errs = ctx.PrepareBuildActions(config)
5571	if errmsg == "" {
5572		android.FailIfErrored(t, errs)
5573	} else if len(errs) > 0 {
5574		android.FailIfNoMatchingErrors(t, errmsg, errs)
5575		return
5576	} else {
5577		t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
5578	}
5579}
5580
5581func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
5582	testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
5583		apex {
5584			name: "myapex",
5585			key: "myapex.key",
5586			updatable: true,
5587		}
5588
5589		apex_key {
5590			name: "myapex.key",
5591			public_key: "testkey.avbpubkey",
5592			private_key: "testkey.pem",
5593		}
5594	`)
5595}
5596
5597func TestNoUpdatableJarsInBootImage(t *testing.T) {
5598
5599	var err string
5600	var transform func(*dexpreopt.GlobalConfig)
5601
5602	t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) {
5603		transform = func(config *dexpreopt.GlobalConfig) {
5604			config.ArtApexJars = []string{"com.android.art.something:some-art-lib"}
5605		}
5606		testNoUpdatableJarsInBootImage(t, "", transform)
5607	})
5608
5609	t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
5610		err = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image"
5611		transform = func(config *dexpreopt.GlobalConfig) {
5612			config.BootJars = []string{"com.android.art.something:some-art-lib"}
5613		}
5614		testNoUpdatableJarsInBootImage(t, err, transform)
5615	})
5616
5617	t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
5618		err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image"
5619		transform = func(config *dexpreopt.GlobalConfig) {
5620			config.ArtApexJars = []string{"some-updatable-apex:some-updatable-apex-lib"}
5621		}
5622		testNoUpdatableJarsInBootImage(t, err, transform)
5623	})
5624
5625	t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
5626		err = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
5627		transform = func(config *dexpreopt.GlobalConfig) {
5628			config.ArtApexJars = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"}
5629		}
5630		testNoUpdatableJarsInBootImage(t, err, transform)
5631	})
5632
5633	t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
5634		err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
5635		transform = func(config *dexpreopt.GlobalConfig) {
5636			config.BootJars = []string{"some-updatable-apex:some-updatable-apex-lib"}
5637		}
5638		testNoUpdatableJarsInBootImage(t, err, transform)
5639	})
5640
5641	t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) {
5642		transform = func(config *dexpreopt.GlobalConfig) {
5643			config.BootJars = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"}
5644		}
5645		testNoUpdatableJarsInBootImage(t, "", transform)
5646	})
5647
5648	t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) {
5649		err = "failed to find a dex jar path for module 'nonexistent'"
5650		transform = func(config *dexpreopt.GlobalConfig) {
5651			config.ArtApexJars = []string{"platform:nonexistent"}
5652		}
5653		testNoUpdatableJarsInBootImage(t, err, transform)
5654	})
5655
5656	t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) {
5657		err = "failed to find a dex jar path for module 'nonexistent'"
5658		transform = func(config *dexpreopt.GlobalConfig) {
5659			config.BootJars = []string{"platform:nonexistent"}
5660		}
5661		testNoUpdatableJarsInBootImage(t, err, transform)
5662	})
5663
5664	t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
5665		err = "module 'some-platform-lib' is not allowed in the ART boot image"
5666		transform = func(config *dexpreopt.GlobalConfig) {
5667			config.ArtApexJars = []string{"platform:some-platform-lib"}
5668		}
5669		testNoUpdatableJarsInBootImage(t, err, transform)
5670	})
5671
5672	t.Run("platform jar in the framework boot image => ok", func(t *testing.T) {
5673		transform = func(config *dexpreopt.GlobalConfig) {
5674			config.BootJars = []string{"platform:some-platform-lib"}
5675		}
5676		testNoUpdatableJarsInBootImage(t, "", transform)
5677	})
5678}
5679
5680func TestTestFor(t *testing.T) {
5681	ctx, _ := testApex(t, `
5682		apex {
5683			name: "myapex",
5684			key: "myapex.key",
5685			native_shared_libs: ["mylib", "myprivlib"],
5686		}
5687
5688		apex_key {
5689			name: "myapex.key",
5690			public_key: "testkey.avbpubkey",
5691			private_key: "testkey.pem",
5692		}
5693
5694		cc_library {
5695			name: "mylib",
5696			srcs: ["mylib.cpp"],
5697			system_shared_libs: [],
5698			stl: "none",
5699			stubs: {
5700				versions: ["1"],
5701			},
5702			apex_available: ["myapex"],
5703		}
5704
5705		cc_library {
5706			name: "myprivlib",
5707			srcs: ["mylib.cpp"],
5708			system_shared_libs: [],
5709			stl: "none",
5710			apex_available: ["myapex"],
5711		}
5712
5713
5714		cc_test {
5715			name: "mytest",
5716			gtest: false,
5717			srcs: ["mylib.cpp"],
5718			system_shared_libs: [],
5719			stl: "none",
5720			shared_libs: ["mylib", "myprivlib"],
5721			test_for: ["myapex"]
5722		}
5723	`)
5724
5725	// the test 'mytest' is a test for the apex, therefore is linked to the
5726	// actual implementation of mylib instead of its stub.
5727	ldFlags := ctx.ModuleForTests("mytest", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
5728	ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared/mylib.so")
5729	ensureNotContains(t, ldFlags, "mylib/android_arm64_armv8-a_shared_1/mylib.so")
5730}
5731
5732// TODO(jungjw): Move this to proptools
5733func intPtr(i int) *int {
5734	return &i
5735}
5736
5737func TestApexSet(t *testing.T) {
5738	ctx, config := testApex(t, `
5739		apex_set {
5740			name: "myapex",
5741			set: "myapex.apks",
5742			filename: "foo_v2.apex",
5743			overrides: ["foo"],
5744		}
5745	`, func(fs map[string][]byte, config android.Config) {
5746		config.TestProductVariables.Platform_sdk_version = intPtr(30)
5747		config.TestProductVariables.DeviceArch = proptools.StringPtr("arm")
5748		config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm64")
5749	})
5750
5751	m := ctx.ModuleForTests("myapex", "android_common")
5752
5753	// Check extract_apks tool parameters.
5754	extractedApex := m.Output(buildDir + "/.intermediates/myapex/android_common/foo_v2.apex")
5755	actual := extractedApex.Args["abis"]
5756	expected := "ARMEABI_V7A,ARM64_V8A"
5757	if actual != expected {
5758		t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual)
5759	}
5760	actual = extractedApex.Args["sdk-version"]
5761	expected = "30"
5762	if actual != expected {
5763		t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual)
5764	}
5765
5766	a := m.Module().(*ApexSet)
5767	expectedOverrides := []string{"foo"}
5768	actualOverrides := android.AndroidMkEntriesForTest(t, config, "", a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
5769	if !reflect.DeepEqual(actualOverrides, expectedOverrides) {
5770		t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES - expected %q vs actual %q", expectedOverrides, actualOverrides)
5771	}
5772}
5773
5774func TestNoStaticLinkingToStubsLib(t *testing.T) {
5775	testApexError(t, `.*required by "mylib" is a native library providing stub.*`, `
5776		apex {
5777			name: "myapex",
5778			key: "myapex.key",
5779			native_shared_libs: ["mylib"],
5780		}
5781
5782		apex_key {
5783			name: "myapex.key",
5784			public_key: "testkey.avbpubkey",
5785			private_key: "testkey.pem",
5786		}
5787
5788		cc_library {
5789			name: "mylib",
5790			srcs: ["mylib.cpp"],
5791			static_libs: ["otherlib"],
5792			system_shared_libs: [],
5793			stl: "none",
5794			apex_available: [ "myapex" ],
5795		}
5796
5797		cc_library {
5798			name: "otherlib",
5799			srcs: ["mylib.cpp"],
5800			system_shared_libs: [],
5801			stl: "none",
5802			stubs: {
5803				versions: ["1", "2", "3"],
5804			},
5805			apex_available: [ "myapex" ],
5806		}
5807	`)
5808}
5809
5810func TestApexKeysTxt(t *testing.T) {
5811	ctx, _ := testApex(t, `
5812		apex {
5813			name: "myapex",
5814			key: "myapex.key",
5815		}
5816
5817		apex_key {
5818			name: "myapex.key",
5819			public_key: "testkey.avbpubkey",
5820			private_key: "testkey.pem",
5821		}
5822
5823		prebuilt_apex {
5824			name: "myapex",
5825			prefer: true,
5826			arch: {
5827				arm64: {
5828					src: "myapex-arm64.apex",
5829				},
5830				arm: {
5831					src: "myapex-arm.apex",
5832				},
5833			},
5834		}
5835
5836		apex_set {
5837			name: "myapex_set",
5838			set: "myapex.apks",
5839			filename: "myapex_set.apex",
5840			overrides: ["myapex"],
5841		}
5842	`)
5843
5844	apexKeysText := ctx.SingletonForTests("apex_keys_text")
5845	content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"]
5846	ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
5847	ensureContains(t, content, `name="myapex.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
5848}
5849
5850func TestAllowedFiles(t *testing.T) {
5851	ctx, _ := testApex(t, `
5852		apex {
5853			name: "myapex",
5854			key: "myapex.key",
5855			apps: ["app"],
5856			allowed_files: "allowed.txt",
5857		}
5858
5859		apex_key {
5860			name: "myapex.key",
5861			public_key: "testkey.avbpubkey",
5862			private_key: "testkey.pem",
5863		}
5864
5865		android_app {
5866			name: "app",
5867			srcs: ["foo/bar/MyClass.java"],
5868			package_name: "foo",
5869			sdk_version: "none",
5870			system_modules: "none",
5871			apex_available: [ "myapex" ],
5872		}
5873	`, withFiles(map[string][]byte{
5874		"sub/Android.bp": []byte(`
5875			override_apex {
5876				name: "override_myapex",
5877				base: "myapex",
5878				apps: ["override_app"],
5879				allowed_files: ":allowed",
5880			}
5881			// Overridable "path" property should be referenced indirectly
5882			filegroup {
5883				name: "allowed",
5884				srcs: ["allowed.txt"],
5885			}
5886			override_android_app {
5887				name: "override_app",
5888				base: "app",
5889				package_name: "bar",
5890			}
5891			`),
5892	}))
5893
5894	rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("diffApexContentRule")
5895	if expected, actual := "allowed.txt", rule.Args["allowed_files_file"]; expected != actual {
5896		t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
5897	}
5898
5899	rule2 := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image").Rule("diffApexContentRule")
5900	if expected, actual := "sub/allowed.txt", rule2.Args["allowed_files_file"]; expected != actual {
5901		t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
5902	}
5903}
5904
5905func TestNonPreferredPrebuiltDependency(t *testing.T) {
5906	_, _ = testApex(t, `
5907		apex {
5908			name: "myapex",
5909			key: "myapex.key",
5910			native_shared_libs: ["mylib"],
5911		}
5912
5913		apex_key {
5914			name: "myapex.key",
5915			public_key: "testkey.avbpubkey",
5916			private_key: "testkey.pem",
5917		}
5918
5919		cc_library {
5920			name: "mylib",
5921			srcs: ["mylib.cpp"],
5922			stubs: {
5923				versions: ["10000"],
5924			},
5925			apex_available: ["myapex"],
5926		}
5927
5928		cc_prebuilt_library_shared {
5929			name: "mylib",
5930			prefer: false,
5931			srcs: ["prebuilt.so"],
5932			stubs: {
5933				versions: ["10000"],
5934			},
5935			apex_available: ["myapex"],
5936		}
5937	`)
5938}
5939
5940func TestMain(m *testing.M) {
5941	run := func() int {
5942		setUp()
5943		defer tearDown()
5944
5945		return m.Run()
5946	}
5947
5948	os.Exit(run())
5949}
5950