1// Copyright (C) 2018 The Android Open Source Project
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
15// package apex implements build rules for creating the APEX files which are container for
16// lower-level system components. See https://source.android.com/devices/tech/ota/apex
17package apex
18
19import (
20	"fmt"
21	"path/filepath"
22	"sort"
23	"strings"
24
25	"github.com/google/blueprint"
26	"github.com/google/blueprint/bootstrap"
27	"github.com/google/blueprint/proptools"
28
29	"android/soong/android"
30	"android/soong/bpf"
31	"android/soong/cc"
32	prebuilt_etc "android/soong/etc"
33	"android/soong/filesystem"
34	"android/soong/java"
35	"android/soong/python"
36	"android/soong/rust"
37	"android/soong/sh"
38)
39
40func init() {
41	registerApexBuildComponents(android.InitRegistrationContext)
42}
43
44func registerApexBuildComponents(ctx android.RegistrationContext) {
45	ctx.RegisterModuleType("apex", BundleFactory)
46	ctx.RegisterModuleType("apex_test", testApexBundleFactory)
47	ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
48	ctx.RegisterModuleType("apex_defaults", defaultsFactory)
49	ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
50	ctx.RegisterModuleType("override_apex", overrideApexFactory)
51	ctx.RegisterModuleType("apex_set", apexSetFactory)
52
53	ctx.PreArchMutators(registerPreArchMutators)
54	ctx.PreDepsMutators(RegisterPreDepsMutators)
55	ctx.PostDepsMutators(RegisterPostDepsMutators)
56}
57
58func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
59	ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
60}
61
62func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
63	ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
64	ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
65}
66
67func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
68	ctx.TopDown("apex_info", apexInfoMutator).Parallel()
69	ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
70	ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
71	ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
72	// Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
73	// it should create a platform variant.
74	ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
75	ctx.BottomUp("apex", apexMutator).Parallel()
76	ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
77	ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
78}
79
80type apexBundleProperties struct {
81	// Json manifest file describing meta info of this APEX bundle. Refer to
82	// system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
83	Manifest *string `android:"path"`
84
85	// AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
86	// a default one is automatically generated.
87	AndroidManifest *string `android:"path"`
88
89	// Canonical name of this APEX bundle. Used to determine the path to the activated APEX on
90	// device (/apex/<apex_name>). If unspecified, follows the name property.
91	Apex_name *string
92
93	// Determines the file contexts file for setting the security contexts to files in this APEX
94	// bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
95	// /system/sepolicy/apex/<module_name>_file_contexts.
96	File_contexts *string `android:"path"`
97
98	ApexNativeDependencies
99
100	Multilib apexMultilibProperties
101
102	// List of bootclasspath fragments that are embedded inside this APEX bundle.
103	Bootclasspath_fragments []string
104
105	// List of systemserverclasspath fragments that are embedded inside this APEX bundle.
106	Systemserverclasspath_fragments []string
107
108	// List of java libraries that are embedded inside this APEX bundle.
109	Java_libs []string
110
111	// List of prebuilt files that are embedded inside this APEX bundle.
112	Prebuilts []string
113
114	// List of platform_compat_config files that are embedded inside this APEX bundle.
115	Compat_configs []string
116
117	// List of BPF programs inside this APEX bundle.
118	Bpfs []string
119
120	// List of filesystem images that are embedded inside this APEX bundle.
121	Filesystems []string
122
123	// The minimum SDK version that this APEX must support at minimum. This is usually set to
124	// the SDK version that the APEX was first introduced.
125	Min_sdk_version *string
126
127	// Whether this APEX is considered updatable or not. When set to true, this will enforce
128	// additional rules for making sure that the APEX is truly updatable. To be updatable,
129	// min_sdk_version should be set as well. This will also disable the size optimizations like
130	// symlinking to the system libs. Default is true.
131	Updatable *bool
132
133	// Whether this APEX is installable to one of the partitions like system, vendor, etc.
134	// Default: true.
135	Installable *bool
136
137	// Whether this APEX can be compressed or not. Setting this property to false means this
138	// APEX will never be compressed. When set to true, APEX will be compressed if other
139	// conditions, e.g, target device needs to support APEX compression, are also fulfilled.
140	// Default: true.
141	Compressible *bool
142
143	// If set true, VNDK libs are considered as stable libs and are not included in this APEX.
144	// Should be only used in non-system apexes (e.g. vendor: true). Default is false.
145	Use_vndk_as_stable *bool
146
147	// List of SDKs that are used to build this APEX. A reference to an SDK should be either
148	// `name#version` or `name` which is an alias for `name#current`. If left empty,
149	// `platform#current` is implied. This value affects all modules included in this APEX. In
150	// other words, they are also built with the SDKs specified here.
151	Uses_sdks []string
152
153	// The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
154	// 'both'. When set to image, contents are stored in a filesystem image inside a zip
155	// container. When set to zip, contents are stored in a zip container directly. This type is
156	// mostly for host-side debugging. When set to both, the two types are both built. Default
157	// is 'image'.
158	Payload_type *string
159
160	// The type of filesystem to use when the payload_type is 'image'. Either 'ext4' or 'f2fs'.
161	// Default 'ext4'.
162	Payload_fs_type *string
163
164	// For telling the APEX to ignore special handling for system libraries such as bionic.
165	// Default is false.
166	Ignore_system_library_special_case *bool
167
168	// Whenever apex_payload.img of the APEX should include dm-verity hashtree.
169	// Default value is true.
170	Generate_hashtree *bool
171
172	// Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
173	// used in tests.
174	Test_only_unsigned_payload *bool
175
176	// Whenever apex should be compressed, regardless of product flag used. Should be only
177	// used in tests.
178	Test_only_force_compression *bool
179
180	// Canonical name of this APEX bundle. Used to determine the path to the
181	// activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
182	// apex mutator variations. For override_apex modules, this is the name of the
183	// overridden base module.
184	ApexVariationName string `blueprint:"mutated"`
185
186	IsCoverageVariant bool `blueprint:"mutated"`
187
188	// List of sanitizer names that this APEX is enabled for
189	SanitizerNames []string `blueprint:"mutated"`
190
191	PreventInstall bool `blueprint:"mutated"`
192
193	HideFromMake bool `blueprint:"mutated"`
194
195	// Internal package method for this APEX. When payload_type is image, this can be either
196	// imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
197	// this becomes zipApex.
198	ApexType apexPackaging `blueprint:"mutated"`
199}
200
201type ApexNativeDependencies struct {
202	// List of native libraries that are embedded inside this APEX.
203	Native_shared_libs []string
204
205	// List of JNI libraries that are embedded inside this APEX.
206	Jni_libs []string
207
208	// List of rust dyn libraries
209	Rust_dyn_libs []string
210
211	// List of native executables that are embedded inside this APEX.
212	Binaries []string
213
214	// List of native tests that are embedded inside this APEX.
215	Tests []string
216
217	// List of filesystem images that are embedded inside this APEX bundle.
218	Filesystems []string
219}
220
221type apexMultilibProperties struct {
222	// Native dependencies whose compile_multilib is "first"
223	First ApexNativeDependencies
224
225	// Native dependencies whose compile_multilib is "both"
226	Both ApexNativeDependencies
227
228	// Native dependencies whose compile_multilib is "prefer32"
229	Prefer32 ApexNativeDependencies
230
231	// Native dependencies whose compile_multilib is "32"
232	Lib32 ApexNativeDependencies
233
234	// Native dependencies whose compile_multilib is "64"
235	Lib64 ApexNativeDependencies
236}
237
238type apexTargetBundleProperties struct {
239	Target struct {
240		// Multilib properties only for android.
241		Android struct {
242			Multilib apexMultilibProperties
243		}
244
245		// Multilib properties only for host.
246		Host struct {
247			Multilib apexMultilibProperties
248		}
249
250		// Multilib properties only for host linux_bionic.
251		Linux_bionic struct {
252			Multilib apexMultilibProperties
253		}
254
255		// Multilib properties only for host linux_glibc.
256		Linux_glibc struct {
257			Multilib apexMultilibProperties
258		}
259	}
260}
261
262type apexArchBundleProperties struct {
263	Arch struct {
264		Arm struct {
265			ApexNativeDependencies
266		}
267		Arm64 struct {
268			ApexNativeDependencies
269		}
270		X86 struct {
271			ApexNativeDependencies
272		}
273		X86_64 struct {
274			ApexNativeDependencies
275		}
276	}
277}
278
279// These properties can be used in override_apex to override the corresponding properties in the
280// base apex.
281type overridableProperties struct {
282	// List of APKs that are embedded inside this APEX.
283	Apps []string
284
285	// List of runtime resource overlays (RROs) that are embedded inside this APEX.
286	Rros []string
287
288	// Names of modules to be overridden. Listed modules can only be other binaries (in Make or
289	// Soong). This does not completely prevent installation of the overridden binaries, but if
290	// both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
291	// be removed from PRODUCT_PACKAGES.
292	Overrides []string
293
294	// Logging parent value.
295	Logging_parent string
296
297	// Apex Container package name. Override value for attribute package:name in
298	// AndroidManifest.xml
299	Package_name string
300
301	// A txt file containing list of files that are allowed to be included in this APEX.
302	Allowed_files *string `android:"path"`
303
304	// Name of the apex_key module that provides the private key to sign this APEX bundle.
305	Key *string
306
307	// Specifies the certificate and the private key to sign the zip container of this APEX. If
308	// this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
309	// as the certificate and the private key, respectively. If this is ":module", then the
310	// certificate and the private key are provided from the android_app_certificate module
311	// named "module".
312	Certificate *string
313}
314
315type apexBundle struct {
316	// Inherited structs
317	android.ModuleBase
318	android.DefaultableModuleBase
319	android.OverridableModuleBase
320	android.SdkBase
321
322	// Properties
323	properties            apexBundleProperties
324	targetProperties      apexTargetBundleProperties
325	archProperties        apexArchBundleProperties
326	overridableProperties overridableProperties
327	vndkProperties        apexVndkProperties // only for apex_vndk modules
328
329	///////////////////////////////////////////////////////////////////////////////////////////
330	// Inputs
331
332	// Keys for apex_paylaod.img
333	publicKeyFile  android.Path
334	privateKeyFile android.Path
335
336	// Cert/priv-key for the zip container
337	containerCertificateFile android.Path
338	containerPrivateKeyFile  android.Path
339
340	// Flags for special variants of APEX
341	testApex bool
342	vndkApex bool
343	artApex  bool
344
345	// Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
346	// one gets installed to the device.
347	primaryApexType bool
348
349	// Suffix of module name in Android.mk ".flattened", ".apex", ".zipapex", or ""
350	suffix string
351
352	// File system type of apex_payload.img
353	payloadFsType fsType
354
355	// Whether to create symlink to the system file instead of having a file inside the apex or
356	// not
357	linkToSystemLib bool
358
359	// List of files to be included in this APEX. This is filled in the first part of
360	// GenerateAndroidBuildActions.
361	filesInfo []apexFile
362
363	// List of other module names that should be installed when this APEX gets installed.
364	requiredDeps []string
365
366	///////////////////////////////////////////////////////////////////////////////////////////
367	// Outputs (final and intermediates)
368
369	// Processed apex manifest in JSONson format (for Q)
370	manifestJsonOut android.WritablePath
371
372	// Processed apex manifest in PB format (for R+)
373	manifestPbOut android.WritablePath
374
375	// Processed file_contexts files
376	fileContexts android.WritablePath
377
378	// Struct holding the merged notice file paths in different formats
379	mergedNotices android.NoticeOutputs
380
381	// The built APEX file. This is the main product.
382	outputFile android.WritablePath
383
384	// The built APEX file in app bundle format. This file is not directly installed to the
385	// device. For an APEX, multiple app bundles are created each of which is for a specific ABI
386	// like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
387	// system) to be merged into a single app bundle file that Play accepts. See
388	// vendor/google/build/build_unbundled_mainline_module.sh for more detail.
389	bundleModuleFile android.WritablePath
390
391	// Target path to install this APEX. Usually out/target/product/<device>/<partition>/apex.
392	installDir android.InstallPath
393
394	// List of commands to create symlinks for backward compatibility. These commands will be
395	// attached as LOCAL_POST_INSTALL_CMD to apex package itself (for unflattened build) or
396	// apex_manifest (for flattened build) so that compat symlinks are always installed
397	// regardless of TARGET_FLATTEN_APEX setting.
398	compatSymlinks []string
399
400	// Text file having the list of individual files that are included in this APEX. Used for
401	// debugging purpose.
402	installedFilesFile android.WritablePath
403
404	// List of module names that this APEX is including (to be shown via *-deps-info target).
405	// Used for debugging purpose.
406	android.ApexBundleDepsInfo
407
408	// Optional list of lint report zip files for apexes that contain java or app modules
409	lintReports android.Paths
410
411	prebuiltFileToDelete string
412
413	isCompressed bool
414
415	// Path of API coverage generate file
416	apisUsedByModuleFile   android.ModuleOutPath
417	apisBackedByModuleFile android.ModuleOutPath
418}
419
420// apexFileClass represents a type of file that can be included in APEX.
421type apexFileClass int
422
423const (
424	app apexFileClass = iota
425	appSet
426	etc
427	goBinary
428	javaSharedLib
429	nativeExecutable
430	nativeSharedLib
431	nativeTest
432	pyBinary
433	shBinary
434)
435
436// apexFile represents a file in an APEX bundle. This is created during the first half of
437// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
438// of the function, this is used to create commands that copies the files into a staging directory,
439// where they are packaged into the APEX file. This struct is also used for creating Make modules
440// for each of the files in case when the APEX is flattened.
441type apexFile struct {
442	// buildFile is put in the installDir inside the APEX.
443	builtFile   android.Path
444	noticeFiles android.Paths
445	installDir  string
446	customStem  string
447	symlinks    []string // additional symlinks
448
449	// Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
450	// module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
451	// suffix>]
452	androidMkModuleName       string             // becomes LOCAL_MODULE
453	class                     apexFileClass      // becomes LOCAL_MODULE_CLASS
454	moduleDir                 string             // becomes LOCAL_PATH
455	requiredModuleNames       []string           // becomes LOCAL_REQUIRED_MODULES
456	targetRequiredModuleNames []string           // becomes LOCAL_TARGET_REQUIRED_MODULES
457	hostRequiredModuleNames   []string           // becomes LOCAL_HOST_REQUIRED_MODULES
458	dataPaths                 []android.DataPath // becomes LOCAL_TEST_DATA
459
460	jacocoReportClassesFile android.Path     // only for javalibs and apps
461	lintDepSets             java.LintDepSets // only for javalibs and apps
462	certificate             java.Certificate // only for apps
463	overriddenPackageName   string           // only for apps
464
465	transitiveDep bool
466	isJniLib      bool
467
468	multilib string
469
470	// TODO(jiyong): remove this
471	module android.Module
472}
473
474// TODO(jiyong): shorten the arglist using an option struct
475func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
476	ret := apexFile{
477		builtFile:           builtFile,
478		installDir:          installDir,
479		androidMkModuleName: androidMkModuleName,
480		class:               class,
481		module:              module,
482	}
483	if module != nil {
484		ret.noticeFiles = module.NoticeFiles()
485		ret.moduleDir = ctx.OtherModuleDir(module)
486		ret.requiredModuleNames = module.RequiredModuleNames()
487		ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
488		ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
489		ret.multilib = module.Target().Arch.ArchType.Multilib
490	}
491	return ret
492}
493
494func (af *apexFile) ok() bool {
495	return af.builtFile != nil && af.builtFile.String() != ""
496}
497
498// apexRelativePath returns the relative path of the given path from the install directory of this
499// apexFile.
500// TODO(jiyong): rename this
501func (af *apexFile) apexRelativePath(path string) string {
502	return filepath.Join(af.installDir, path)
503}
504
505// path returns path of this apex file relative to the APEX root
506func (af *apexFile) path() string {
507	return af.apexRelativePath(af.stem())
508}
509
510// stem returns the base filename of this apex file
511func (af *apexFile) stem() string {
512	if af.customStem != "" {
513		return af.customStem
514	}
515	return af.builtFile.Base()
516}
517
518// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
519func (af *apexFile) symlinkPaths() []string {
520	var ret []string
521	for _, symlink := range af.symlinks {
522		ret = append(ret, af.apexRelativePath(symlink))
523	}
524	return ret
525}
526
527// availableToPlatform tests whether this apexFile is from a module that can be installed to the
528// platform.
529func (af *apexFile) availableToPlatform() bool {
530	if af.module == nil {
531		return false
532	}
533	if am, ok := af.module.(android.ApexModule); ok {
534		return am.AvailableFor(android.AvailableToPlatform)
535	}
536	return false
537}
538
539////////////////////////////////////////////////////////////////////////////////////////////////////
540// Mutators
541//
542// Brief description about mutators for APEX. The following three mutators are the most important
543// ones.
544//
545// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
546// to the (direct) dependencies of this APEX bundle.
547//
548// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
549// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
550// modules are marked as being included in the APEX via BuildForApex().
551//
552// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
553// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
554
555type dependencyTag struct {
556	blueprint.BaseDependencyTag
557	name string
558
559	// Determines if the dependent will be part of the APEX payload. Can be false for the
560	// dependencies to the signing key module, etc.
561	payload bool
562
563	// True if the dependent can only be a source module, false if a prebuilt module is a suitable
564	// replacement. This is needed because some prebuilt modules do not provide all the information
565	// needed by the apex.
566	sourceOnly bool
567}
568
569func (d dependencyTag) ReplaceSourceWithPrebuilt() bool {
570	return !d.sourceOnly
571}
572
573var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
574
575var (
576	androidAppTag   = dependencyTag{name: "androidApp", payload: true}
577	bpfTag          = dependencyTag{name: "bpf", payload: true}
578	certificateTag  = dependencyTag{name: "certificate"}
579	executableTag   = dependencyTag{name: "executable", payload: true}
580	fsTag           = dependencyTag{name: "filesystem", payload: true}
581	bcpfTag         = dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true}
582	sscpfTag        = dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true}
583	compatConfigTag = dependencyTag{name: "compatConfig", payload: true, sourceOnly: true}
584	javaLibTag      = dependencyTag{name: "javaLib", payload: true}
585	jniLibTag       = dependencyTag{name: "jniLib", payload: true}
586	keyTag          = dependencyTag{name: "key"}
587	prebuiltTag     = dependencyTag{name: "prebuilt", payload: true}
588	rroTag          = dependencyTag{name: "rro", payload: true}
589	sharedLibTag    = dependencyTag{name: "sharedLib", payload: true}
590	testForTag      = dependencyTag{name: "test for"}
591	testTag         = dependencyTag{name: "test", payload: true}
592)
593
594// TODO(jiyong): shorten this function signature
595func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
596	binVariations := target.Variations()
597	libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
598	rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
599
600	if ctx.Device() {
601		binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
602		libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
603		rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
604	}
605
606	// Use *FarVariation* to be able to depend on modules having conflicting variations with
607	// this module. This is required since arch variant of an APEX bundle is 'common' but it is
608	// 'arm' or 'arm64' for native shared libs.
609	ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
610	ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
611	ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
612	ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
613	ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
614	ctx.AddFarVariationDependencies(target.Variations(), fsTag, nativeModules.Filesystems...)
615}
616
617func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
618	if ctx.Device() {
619		proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
620	} else {
621		proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
622		if ctx.Os().Bionic() {
623			proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
624		} else {
625			proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
626		}
627	}
628}
629
630// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
631// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
632func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
633	deviceConfig := ctx.DeviceConfig()
634	if a.vndkApex {
635		return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
636	}
637
638	var prefix string
639	var vndkVersion string
640	if deviceConfig.VndkVersion() != "" {
641		if a.SocSpecific() || a.DeviceSpecific() {
642			prefix = cc.VendorVariationPrefix
643			vndkVersion = deviceConfig.VndkVersion()
644		} else if a.ProductSpecific() {
645			prefix = cc.ProductVariationPrefix
646			vndkVersion = deviceConfig.ProductVndkVersion()
647		}
648	}
649	if vndkVersion == "current" {
650		vndkVersion = deviceConfig.PlatformVndkVersion()
651	}
652	if vndkVersion != "" {
653		return prefix + vndkVersion
654	}
655
656	return android.CoreVariation // The usual case
657}
658
659func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
660	// apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
661	// arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
662	// each target os/architectures, appropriate dependencies are selected by their
663	// target.<os>.multilib.<type> groups and are added as (direct) dependencies.
664	targets := ctx.MultiTargets()
665	config := ctx.DeviceConfig()
666	imageVariation := a.getImageVariation(ctx)
667
668	a.combineProperties(ctx)
669
670	has32BitTarget := false
671	for _, target := range targets {
672		if target.Arch.ArchType.Multilib == "lib32" {
673			has32BitTarget = true
674		}
675	}
676	for i, target := range targets {
677		// Don't include artifacts for the host cross targets because there is no way for us
678		// to run those artifacts natively on host
679		if target.HostCross {
680			continue
681		}
682
683		var depsList []ApexNativeDependencies
684
685		// Add native modules targeting both ABIs. When multilib.* is omitted for
686		// native_shared_libs/jni_libs/tests, it implies multilib.both
687		depsList = append(depsList, a.properties.Multilib.Both)
688		depsList = append(depsList, ApexNativeDependencies{
689			Native_shared_libs: a.properties.Native_shared_libs,
690			Tests:              a.properties.Tests,
691			Jni_libs:           a.properties.Jni_libs,
692			Binaries:           nil,
693		})
694
695		// Add native modules targeting the first ABI When multilib.* is omitted for
696		// binaries, it implies multilib.first
697		isPrimaryAbi := i == 0
698		if isPrimaryAbi {
699			depsList = append(depsList, a.properties.Multilib.First)
700			depsList = append(depsList, ApexNativeDependencies{
701				Native_shared_libs: nil,
702				Tests:              nil,
703				Jni_libs:           nil,
704				Binaries:           a.properties.Binaries,
705			})
706		}
707
708		// Add native modules targeting either 32-bit or 64-bit ABI
709		switch target.Arch.ArchType.Multilib {
710		case "lib32":
711			depsList = append(depsList, a.properties.Multilib.Lib32)
712			depsList = append(depsList, a.properties.Multilib.Prefer32)
713		case "lib64":
714			depsList = append(depsList, a.properties.Multilib.Lib64)
715			if !has32BitTarget {
716				depsList = append(depsList, a.properties.Multilib.Prefer32)
717			}
718		}
719
720		// Add native modules targeting a specific arch variant
721		switch target.Arch.ArchType {
722		case android.Arm:
723			depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
724		case android.Arm64:
725			depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
726		case android.X86:
727			depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
728		case android.X86_64:
729			depsList = append(depsList, a.archProperties.Arch.X86_64.ApexNativeDependencies)
730		default:
731			panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
732		}
733
734		for _, d := range depsList {
735			addDependenciesForNativeModules(ctx, d, target, imageVariation)
736		}
737	}
738
739	// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
740	// regardless of the TARGET_PREFER_* setting. See b/144532908
741	archForPrebuiltEtc := config.Arches()[0]
742	for _, arch := range config.Arches() {
743		// Prefer 64-bit arch if there is any
744		if arch.ArchType.Multilib == "lib64" {
745			archForPrebuiltEtc = arch
746			break
747		}
748	}
749	ctx.AddFarVariationDependencies([]blueprint.Variation{
750		{Mutator: "os", Variation: ctx.Os().String()},
751		{Mutator: "arch", Variation: archForPrebuiltEtc.String()},
752	}, prebuiltTag, a.properties.Prebuilts...)
753
754	// Common-arch dependencies come next
755	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
756	ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
757	ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments...)
758	ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
759	ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.properties.Bpfs...)
760	ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
761	ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
762
763	if a.artApex {
764		// With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library.
765		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
766			ctx.AddFarVariationDependencies(commonVariation, javaLibTag, "jacocoagent")
767		}
768	}
769
770	// Marks that this APEX (in fact all the modules in it) has to be built with the given SDKs.
771	// This field currently isn't used.
772	// TODO(jiyong): consider dropping this feature
773	// TODO(jiyong): ensure that all apexes are with non-empty uses_sdks
774	if len(a.properties.Uses_sdks) > 0 {
775		sdkRefs := []android.SdkRef{}
776		for _, str := range a.properties.Uses_sdks {
777			parsed := android.ParseSdkRef(ctx, str, "uses_sdks")
778			sdkRefs = append(sdkRefs, parsed)
779		}
780		a.BuildWithSdks(sdkRefs)
781	}
782}
783
784// DepsMutator for the overridden properties.
785func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
786	if a.overridableProperties.Allowed_files != nil {
787		android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
788	}
789
790	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
791	ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
792	ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
793
794	// Dependencies for signing
795	if String(a.overridableProperties.Key) == "" {
796		ctx.PropertyErrorf("key", "missing")
797		return
798	}
799	ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
800
801	cert := android.SrcIsModule(a.getCertString(ctx))
802	if cert != "" {
803		ctx.AddDependency(ctx.Module(), certificateTag, cert)
804		// empty cert is not an error. Cert and private keys will be directly found under
805		// PRODUCT_DEFAULT_DEV_CERTIFICATE
806	}
807}
808
809type ApexBundleInfo struct {
810	Contents *android.ApexContents
811}
812
813var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_info")
814
815var _ ApexInfoMutator = (*apexBundle)(nil)
816
817func (a *apexBundle) ApexVariationName() string {
818	return a.properties.ApexVariationName
819}
820
821// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
822// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
823// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
824// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
825// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
826//
827// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
828// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
829// The apexMutator uses that list to create module variants for the apexes to which it belongs.
830// The relationship between module variants and apexes is not one-to-one as variants will be
831// shared between compatible apexes.
832func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
833
834	// The VNDK APEX is special. For the APEX, the membership is described in a very different
835	// way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
836	// libraries are self-identified by their vndk.enabled properties. There is no need to run
837	// this mutator for the APEX as nothing will be collected. So, let's return fast.
838	if a.vndkApex {
839		return
840	}
841
842	// Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
843	// provided with a property named use_vndk_as_stable, which when set to true doesn't collect
844	// VNDK libraries as transitive dependencies. This option is useful for reducing the size of
845	// the non-system APEXes because the VNDK libraries won't be included (and duped) in the
846	// APEX, but shared across APEXes via the VNDK APEX.
847	useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
848	excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
849	if !useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) {
850		mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
851		return
852	}
853
854	continueApexDepsWalk := func(child, parent android.Module) bool {
855		am, ok := child.(android.ApexModule)
856		if !ok || !am.CanHaveApexVariants() {
857			return false
858		}
859		depTag := mctx.OtherModuleDependencyTag(child)
860
861		// Check to see if the tag always requires that the child module has an apex variant for every
862		// apex variant of the parent module. If it does not then it is still possible for something
863		// else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
864		if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
865			return true
866		}
867		if !android.IsDepInSameApex(mctx, parent, child) {
868			return false
869		}
870		if excludeVndkLibs {
871			if c, ok := child.(*cc.Module); ok && c.IsVndk() {
872				return false
873			}
874		}
875		// By default, all the transitive dependencies are collected, unless filtered out
876		// above.
877		return true
878	}
879
880	// Records whether a certain module is included in this apexBundle via direct dependency or
881	// inndirect dependency.
882	contents := make(map[string]android.ApexMembership)
883	mctx.WalkDeps(func(child, parent android.Module) bool {
884		if !continueApexDepsWalk(child, parent) {
885			return false
886		}
887		// If the parent is apexBundle, this child is directly depended.
888		_, directDep := parent.(*apexBundle)
889		depName := mctx.OtherModuleName(child)
890		contents[depName] = contents[depName].Add(directDep)
891		return true
892	})
893
894	// The membership information is saved for later access
895	apexContents := android.NewApexContents(contents)
896	mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
897		Contents: apexContents,
898	})
899
900	minSdkVersion := a.minSdkVersion(mctx)
901	// When min_sdk_version is not set, the apex is built against FutureApiLevel.
902	if minSdkVersion.IsNone() {
903		minSdkVersion = android.FutureApiLevel
904	}
905
906	// This is the main part of this mutator. Mark the collected dependencies that they need to
907	// be built for this apexBundle.
908
909	apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
910	a.properties.ApexVariationName = apexVariationName
911	apexInfo := android.ApexInfo{
912		ApexVariationName: apexVariationName,
913		MinSdkVersion:     minSdkVersion,
914		RequiredSdks:      a.RequiredSdks(),
915		Updatable:         a.Updatable(),
916		InApexVariants:    []string{apexVariationName},
917		InApexModules:     []string{a.Name()}, // could be com.mycompany.android.foo
918		ApexContents:      []*android.ApexContents{apexContents},
919	}
920	mctx.WalkDeps(func(child, parent android.Module) bool {
921		if !continueApexDepsWalk(child, parent) {
922			return false
923		}
924		child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
925		return true
926	})
927}
928
929type ApexInfoMutator interface {
930	// ApexVariationName returns the name of the APEX variation to use in the apex
931	// mutator etc. It is the same name as ApexInfo.ApexVariationName.
932	ApexVariationName() string
933
934	// ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
935	// depended upon by an apex and which require an apex specific variant.
936	ApexInfoMutator(android.TopDownMutatorContext)
937}
938
939// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
940// specific variant to modules that support the ApexInfoMutator.
941func apexInfoMutator(mctx android.TopDownMutatorContext) {
942	if !mctx.Module().Enabled() {
943		return
944	}
945
946	if a, ok := mctx.Module().(ApexInfoMutator); ok {
947		a.ApexInfoMutator(mctx)
948		return
949	}
950}
951
952// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
953// unique apex variations for this module. See android/apex.go for more about unique apex variant.
954// TODO(jiyong): move this to android/apex.go?
955func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
956	if !mctx.Module().Enabled() {
957		return
958	}
959	if am, ok := mctx.Module().(android.ApexModule); ok {
960		android.UpdateUniqueApexVariationsForDeps(mctx, am)
961	}
962}
963
964// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
965// the apex in order to retrieve its contents later.
966// TODO(jiyong): move this to android/apex.go?
967func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
968	if !mctx.Module().Enabled() {
969		return
970	}
971	if am, ok := mctx.Module().(android.ApexModule); ok {
972		if testFor := am.TestFor(); len(testFor) > 0 {
973			mctx.AddFarVariationDependencies([]blueprint.Variation{
974				{Mutator: "os", Variation: am.Target().OsVariation()},
975				{"arch", "common"},
976			}, testForTag, testFor...)
977		}
978	}
979}
980
981// TODO(jiyong): move this to android/apex.go?
982func apexTestForMutator(mctx android.BottomUpMutatorContext) {
983	if !mctx.Module().Enabled() {
984		return
985	}
986	if _, ok := mctx.Module().(android.ApexModule); ok {
987		var contents []*android.ApexContents
988		for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
989			abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo)
990			contents = append(contents, abInfo.Contents)
991		}
992		mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{
993			ApexContents: contents,
994		})
995	}
996}
997
998// markPlatformAvailability marks whether or not a module can be available to platform. A module
999// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1000// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1001// be) available to platform
1002// TODO(jiyong): move this to android/apex.go?
1003func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1004	// Host and recovery are not considered as platform
1005	if mctx.Host() || mctx.Module().InstallInRecovery() {
1006		return
1007	}
1008
1009	am, ok := mctx.Module().(android.ApexModule)
1010	if !ok {
1011		return
1012	}
1013
1014	availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
1015
1016	// If any of the dep is not available to platform, this module is also considered as being
1017	// not available to platform even if it has "//apex_available:platform"
1018	mctx.VisitDirectDeps(func(child android.Module) {
1019		if !android.IsDepInSameApex(mctx, am, child) {
1020			// if the dependency crosses apex boundary, don't consider it
1021			return
1022		}
1023		if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1024			availableToPlatform = false
1025			// TODO(b/154889534) trigger an error when 'am' has
1026			// "//apex_available:platform"
1027		}
1028	})
1029
1030	// Exception 1: check to see if the module always requires it.
1031	if am.AlwaysRequiresPlatformApexVariant() {
1032		availableToPlatform = true
1033	}
1034
1035	// Exception 2: bootstrap bionic libraries are also always available to platform
1036	if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1037		availableToPlatform = true
1038	}
1039
1040	if !availableToPlatform {
1041		am.SetNotAvailableForPlatform()
1042	}
1043}
1044
1045// apexMutator visits each module and creates apex variations if the module was marked in the
1046// previous run of apexInfoMutator.
1047func apexMutator(mctx android.BottomUpMutatorContext) {
1048	if !mctx.Module().Enabled() {
1049		return
1050	}
1051
1052	// This is the usual path.
1053	if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
1054		android.CreateApexVariations(mctx, am)
1055		return
1056	}
1057
1058	// apexBundle itself is mutated so that it and its dependencies have the same apex variant.
1059	if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1060		apexBundleName := ai.ApexVariationName()
1061		mctx.CreateVariations(apexBundleName)
1062		if strings.HasPrefix(apexBundleName, "com.android.art") {
1063			// Create an alias from the platform variant. This is done to make
1064			// test_for dependencies work for modules that are split by the APEX
1065			// mutator, since test_for dependencies always go to the platform variant.
1066			// This doesn't happen for normal APEXes that are disjunct, so only do
1067			// this for the overlapping ART APEXes.
1068			// TODO(b/183882457): Remove this if the test_for functionality is
1069			// refactored to depend on the proper APEX variants instead of platform.
1070			mctx.CreateAliasVariation("", apexBundleName)
1071		}
1072	} else if o, ok := mctx.Module().(*OverrideApex); ok {
1073		apexBundleName := o.GetOverriddenModuleName()
1074		if apexBundleName == "" {
1075			mctx.ModuleErrorf("base property is not set")
1076			return
1077		}
1078		// Workaround the issue reported in b/191269918 by using the unprefixed module name of this
1079		// module as the default variation to use if dependencies of this module do not have the correct
1080		// apex variant name. This name matches the name used to create the variations of modules for
1081		// which apexModuleTypeRequiresVariant return true.
1082		// TODO(b/191269918): Remove this workaround.
1083		unprefixedModuleName := android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName())
1084		mctx.SetDefaultDependencyVariation(&unprefixedModuleName)
1085		mctx.CreateVariations(apexBundleName)
1086		if strings.HasPrefix(apexBundleName, "com.android.art") {
1087			// TODO(b/183882457): See note for CreateAliasVariation above.
1088			mctx.CreateAliasVariation("", apexBundleName)
1089		}
1090	}
1091}
1092
1093// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1094// variant.
1095func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
1096	if a, ok := module.(*apexBundle); ok {
1097		// TODO(jiyong): document the reason why the VNDK APEX is an exception here.
1098		return !a.vndkApex
1099	}
1100
1101	return true
1102}
1103
1104// See android.UpdateDirectlyInAnyApex
1105// TODO(jiyong): move this to android/apex.go?
1106func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
1107	if !mctx.Module().Enabled() {
1108		return
1109	}
1110	if am, ok := mctx.Module().(android.ApexModule); ok {
1111		android.UpdateDirectlyInAnyApex(mctx, am)
1112	}
1113}
1114
1115// apexPackaging represents a specific packaging method for an APEX.
1116type apexPackaging int
1117
1118const (
1119	// imageApex is a packaging method where contents are included in a filesystem image which
1120	// is then included in a zip container. This is the most typical way of packaging.
1121	imageApex apexPackaging = iota
1122
1123	// zipApex is a packaging method where contents are directly included in the zip container.
1124	// This is used for host-side testing - because the contents are easily accessible by
1125	// unzipping the container.
1126	zipApex
1127
1128	// flattendApex is a packaging method where contents are not included in the APEX file, but
1129	// installed to /apex/<apexname> directory on the device. This packaging method is used for
1130	// old devices where the filesystem-based APEX file can't be supported.
1131	flattenedApex
1132)
1133
1134const (
1135	// File extensions of an APEX for different packaging methods
1136	imageApexSuffix = ".apex"
1137	zipApexSuffix   = ".zipapex"
1138	flattenedSuffix = ".flattened"
1139
1140	// variant names each of which is for a packaging method
1141	imageApexType     = "image"
1142	zipApexType       = "zip"
1143	flattenedApexType = "flattened"
1144
1145	ext4FsType = "ext4"
1146	f2fsFsType = "f2fs"
1147)
1148
1149// The suffix for the output "file", not the module
1150func (a apexPackaging) suffix() string {
1151	switch a {
1152	case imageApex:
1153		return imageApexSuffix
1154	case zipApex:
1155		return zipApexSuffix
1156	default:
1157		panic(fmt.Errorf("unknown APEX type %d", a))
1158	}
1159}
1160
1161func (a apexPackaging) name() string {
1162	switch a {
1163	case imageApex:
1164		return imageApexType
1165	case zipApex:
1166		return zipApexType
1167	default:
1168		panic(fmt.Errorf("unknown APEX type %d", a))
1169	}
1170}
1171
1172// apexFlattenedMutator creates one or more variations each of which is for a packaging method.
1173// TODO(jiyong): give a better name to this mutator
1174func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
1175	if !mctx.Module().Enabled() {
1176		return
1177	}
1178	if ab, ok := mctx.Module().(*apexBundle); ok {
1179		var variants []string
1180		switch proptools.StringDefault(ab.properties.Payload_type, "image") {
1181		case "image":
1182			// This is the normal case. Note that both image and flattend APEXes are
1183			// created. The image type is installed to the system partition, while the
1184			// flattened APEX is (optionally) installed to the system_ext partition.
1185			// This is mostly for GSI which has to support wide range of devices. If GSI
1186			// is installed on a newer (APEX-capable) device, the image APEX in the
1187			// system will be used. However, if the same GSI is installed on an old
1188			// device which can't support image APEX, the flattened APEX in the
1189			// system_ext partion (which still is part of GSI) is used instead.
1190			variants = append(variants, imageApexType, flattenedApexType)
1191		case "zip":
1192			variants = append(variants, zipApexType)
1193		case "both":
1194			variants = append(variants, imageApexType, zipApexType, flattenedApexType)
1195		default:
1196			mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
1197			return
1198		}
1199
1200		modules := mctx.CreateLocalVariations(variants...)
1201
1202		for i, v := range variants {
1203			switch v {
1204			case imageApexType:
1205				modules[i].(*apexBundle).properties.ApexType = imageApex
1206			case zipApexType:
1207				modules[i].(*apexBundle).properties.ApexType = zipApex
1208			case flattenedApexType:
1209				modules[i].(*apexBundle).properties.ApexType = flattenedApex
1210				// See the comment above for why system_ext.
1211				if !mctx.Config().FlattenApex() && ab.Platform() {
1212					modules[i].(*apexBundle).MakeAsSystemExt()
1213				}
1214			}
1215		}
1216	} else if _, ok := mctx.Module().(*OverrideApex); ok {
1217		// payload_type is forcibly overridden to "image"
1218		// TODO(jiyong): is this the right decision?
1219		mctx.CreateVariations(imageApexType, flattenedApexType)
1220	}
1221}
1222
1223var _ android.DepIsInSameApex = (*apexBundle)(nil)
1224
1225// Implements android.DepInInSameApex
1226func (a *apexBundle) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1227	// direct deps of an APEX bundle are all part of the APEX bundle
1228	// TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
1229	return true
1230}
1231
1232var _ android.OutputFileProducer = (*apexBundle)(nil)
1233
1234// Implements android.OutputFileProducer
1235func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1236	switch tag {
1237	case "", android.DefaultDistTag:
1238		// This is the default dist path.
1239		return android.Paths{a.outputFile}, nil
1240	default:
1241		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1242	}
1243}
1244
1245var _ cc.Coverage = (*apexBundle)(nil)
1246
1247// Implements cc.Coverage
1248func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1249	return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1250}
1251
1252// Implements cc.Coverage
1253func (a *apexBundle) SetPreventInstall() {
1254	a.properties.PreventInstall = true
1255}
1256
1257// Implements cc.Coverage
1258func (a *apexBundle) HideFromMake() {
1259	a.properties.HideFromMake = true
1260	// This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1261	// TODO(ccross): untangle these
1262	a.ModuleBase.HideFromMake()
1263}
1264
1265// Implements cc.Coverage
1266func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1267	a.properties.IsCoverageVariant = coverage
1268}
1269
1270// Implements cc.Coverage
1271func (a *apexBundle) EnableCoverageIfNeeded() {}
1272
1273var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1274
1275// Implements android.ApexBudleDepsInfoIntf
1276func (a *apexBundle) Updatable() bool {
1277	return proptools.BoolDefault(a.properties.Updatable, true)
1278}
1279
1280// getCertString returns the name of the cert that should be used to sign this APEX. This is
1281// basically from the "certificate" property, but could be overridden by the device config.
1282func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
1283	moduleName := ctx.ModuleName()
1284	// VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1285	// OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1286	// overridden.
1287	if a.vndkApex {
1288		moduleName = vndkApexName
1289	}
1290	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
1291	if overridden {
1292		return ":" + certificate
1293	}
1294	return String(a.overridableProperties.Certificate)
1295}
1296
1297// See the installable property
1298func (a *apexBundle) installable() bool {
1299	return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
1300}
1301
1302// See the generate_hashtree property
1303func (a *apexBundle) shouldGenerateHashtree() bool {
1304	return proptools.BoolDefault(a.properties.Generate_hashtree, true)
1305}
1306
1307// See the test_only_unsigned_payload property
1308func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1309	return proptools.Bool(a.properties.Test_only_unsigned_payload)
1310}
1311
1312// See the test_only_force_compression property
1313func (a *apexBundle) testOnlyShouldForceCompression() bool {
1314	return proptools.Bool(a.properties.Test_only_force_compression)
1315}
1316
1317// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1318// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1319// sanitizers, extra dependencies can be forcibly added as well.
1320
1321func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1322	if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1323		a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1324	}
1325}
1326
1327func (a *apexBundle) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool {
1328	if android.InList(sanitizerName, a.properties.SanitizerNames) {
1329		return true
1330	}
1331
1332	// Then follow the global setting
1333	globalSanitizerNames := []string{}
1334	if a.Host() {
1335		globalSanitizerNames = ctx.Config().SanitizeHost()
1336	} else {
1337		arches := ctx.Config().SanitizeDeviceArch()
1338		if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
1339			globalSanitizerNames = ctx.Config().SanitizeDevice()
1340		}
1341	}
1342	return android.InList(sanitizerName, globalSanitizerNames)
1343}
1344
1345func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
1346	// TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1347	// Keep only the mechanism here.
1348	if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
1349		imageVariation := a.getImageVariation(ctx)
1350		for _, target := range ctx.MultiTargets() {
1351			if target.Arch.ArchType.Multilib == "lib64" {
1352				addDependenciesForNativeModules(ctx, ApexNativeDependencies{
1353					Native_shared_libs: []string{"libclang_rt.hwasan-aarch64-android"},
1354					Tests:              nil,
1355					Jni_libs:           nil,
1356					Binaries:           nil,
1357				}, target, imageVariation)
1358				break
1359			}
1360		}
1361	}
1362}
1363
1364// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1365// returned apexFile saves information about the Soong module that will be used for creating the
1366// build rules.
1367func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
1368	// Decide the APEX-local directory by the multilib of the library In the future, we may
1369	// query this to the module.
1370	// TODO(jiyong): use the new PackagingSpec
1371	var dirInApex string
1372	switch ccMod.Arch().ArchType.Multilib {
1373	case "lib32":
1374		dirInApex = "lib"
1375	case "lib64":
1376		dirInApex = "lib64"
1377	}
1378	if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
1379		dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
1380	}
1381	dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
1382	if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
1383		// Special case for Bionic libs and other libs installed with them. This is to
1384		// prevent those libs from being included in the search path
1385		// /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1386		// in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1387		// init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1388		// will be loaded into the default linker namespace (aka "platform" namespace). If
1389		// the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1390		// be loaded again into the runtime linker namespace, which will result in double
1391		// loading of them, which isn't supported.
1392		dirInApex = filepath.Join(dirInApex, "bionic")
1393	}
1394
1395	fileToCopy := ccMod.OutputFile().Path()
1396	androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1397	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
1398}
1399
1400func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
1401	dirInApex := "bin"
1402	if cc.Target().NativeBridge == android.NativeBridgeEnabled {
1403		dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
1404	}
1405	dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
1406	fileToCopy := cc.OutputFile().Path()
1407	androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1408	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
1409	af.symlinks = cc.Symlinks()
1410	af.dataPaths = cc.DataPaths()
1411	return af
1412}
1413
1414func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1415	dirInApex := "bin"
1416	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1417		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1418	}
1419	fileToCopy := rustm.OutputFile().Path()
1420	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1421	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1422	return af
1423}
1424
1425func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1426	// Decide the APEX-local directory by the multilib of the library
1427	// In the future, we may query this to the module.
1428	var dirInApex string
1429	switch rustm.Arch().ArchType.Multilib {
1430	case "lib32":
1431		dirInApex = "lib"
1432	case "lib64":
1433		dirInApex = "lib64"
1434	}
1435	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1436		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1437	}
1438	fileToCopy := rustm.OutputFile().Path()
1439	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1440	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1441}
1442
1443func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
1444	dirInApex := "bin"
1445	fileToCopy := py.HostToolPath().Path()
1446	return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
1447}
1448
1449func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
1450	dirInApex := "bin"
1451	s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
1452	if err != nil {
1453		ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath())
1454		return apexFile{}
1455	}
1456	fileToCopy := android.PathForOutput(ctx, s)
1457	// NB: Since go binaries are static we don't need the module for anything here, which is
1458	// good since the go tool is a blueprint.Module not an android.Module like we would
1459	// normally use.
1460	return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
1461}
1462
1463func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
1464	dirInApex := filepath.Join("bin", sh.SubDir())
1465	fileToCopy := sh.OutputFile()
1466	af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
1467	af.symlinks = sh.Symlinks()
1468	return af
1469}
1470
1471func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
1472	dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
1473	fileToCopy := prebuilt.OutputFile()
1474	return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
1475}
1476
1477func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1478	dirInApex := filepath.Join("etc", config.SubDir())
1479	fileToCopy := config.CompatConfig()
1480	return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1481}
1482
1483// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1484// way.
1485type javaModule interface {
1486	android.Module
1487	BaseModuleName() string
1488	DexJarBuildPath() android.Path
1489	JacocoReportClassesFile() android.Path
1490	LintDepSets() java.LintDepSets
1491	Stem() string
1492}
1493
1494var _ javaModule = (*java.Library)(nil)
1495var _ javaModule = (*java.Import)(nil)
1496var _ javaModule = (*java.SdkLibrary)(nil)
1497var _ javaModule = (*java.DexImport)(nil)
1498var _ javaModule = (*java.SdkLibraryImport)(nil)
1499
1500// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
1501func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
1502	return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath())
1503}
1504
1505// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1506func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
1507	dirInApex := "javalib"
1508	af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
1509	af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1510	af.lintDepSets = module.LintDepSets()
1511	af.customStem = module.Stem() + ".jar"
1512	return af
1513}
1514
1515// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1516// the same way.
1517type androidApp interface {
1518	android.Module
1519	Privileged() bool
1520	InstallApkName() string
1521	OutputFile() android.Path
1522	JacocoReportClassesFile() android.Path
1523	Certificate() java.Certificate
1524	BaseModuleName() string
1525	LintDepSets() java.LintDepSets
1526}
1527
1528var _ androidApp = (*java.AndroidApp)(nil)
1529var _ androidApp = (*java.AndroidAppImport)(nil)
1530
1531func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
1532	appDir := "app"
1533	if aapp.Privileged() {
1534		appDir = "priv-app"
1535	}
1536	dirInApex := filepath.Join(appDir, aapp.InstallApkName())
1537	fileToCopy := aapp.OutputFile()
1538	af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
1539	af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
1540	af.lintDepSets = aapp.LintDepSets()
1541	af.certificate = aapp.Certificate()
1542
1543	if app, ok := aapp.(interface {
1544		OverriddenManifestPackageName() string
1545	}); ok {
1546		af.overriddenPackageName = app.OverriddenManifestPackageName()
1547	}
1548	return af
1549}
1550
1551func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1552	rroDir := "overlay"
1553	dirInApex := filepath.Join(rroDir, rro.Theme())
1554	fileToCopy := rro.OutputFile()
1555	af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1556	af.certificate = rro.Certificate()
1557
1558	if a, ok := rro.(interface {
1559		OverriddenManifestPackageName() string
1560	}); ok {
1561		af.overriddenPackageName = a.OverriddenManifestPackageName()
1562	}
1563	return af
1564}
1565
1566func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, bpfProgram bpf.BpfModule) apexFile {
1567	dirInApex := filepath.Join("etc", "bpf")
1568	return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1569}
1570
1571func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1572	dirInApex := filepath.Join("etc", "fs")
1573	return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1574}
1575
1576// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
1577// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1578// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1579// modules. This is used in check* functions below.
1580func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
1581	ctx.WalkDeps(func(child, parent android.Module) bool {
1582		am, ok := child.(android.ApexModule)
1583		if !ok || !am.CanHaveApexVariants() {
1584			return false
1585		}
1586
1587		// Filter-out unwanted depedendencies
1588		depTag := ctx.OtherModuleDependencyTag(child)
1589		if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1590			return false
1591		}
1592		if dt, ok := depTag.(dependencyTag); ok && !dt.payload {
1593			return false
1594		}
1595
1596		ai := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
1597		externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
1598
1599		// Visit actually
1600		return do(ctx, parent, am, externalDep)
1601	})
1602}
1603
1604// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1605type fsType int
1606
1607const (
1608	ext4 fsType = iota
1609	f2fs
1610)
1611
1612func (f fsType) string() string {
1613	switch f {
1614	case ext4:
1615		return ext4FsType
1616	case f2fs:
1617		return f2fsFsType
1618	default:
1619		panic(fmt.Errorf("unknown APEX payload type %d", f))
1620	}
1621}
1622
1623// Creates build rules for an APEX. It consists of the following major steps:
1624//
1625// 1) do some validity checks such as apex_available, min_sdk_version, etc.
1626// 2) traverse the dependency tree to collect apexFile structs from them.
1627// 3) some fields in apexBundle struct are configured
1628// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
1629func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1630	////////////////////////////////////////////////////////////////////////////////////////////
1631	// 1) do some validity checks such as apex_available, min_sdk_version, etc.
1632	a.checkApexAvailability(ctx)
1633	a.checkUpdatable(ctx)
1634	a.checkMinSdkVersion(ctx)
1635	a.checkStaticLinkingToStubLibraries(ctx)
1636	if len(a.properties.Tests) > 0 && !a.testApex {
1637		ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
1638		return
1639	}
1640
1641	////////////////////////////////////////////////////////////////////////////////////////////
1642	// 2) traverse the dependency tree to collect apexFile structs from them.
1643
1644	// all the files that will be included in this APEX
1645	var filesInfo []apexFile
1646
1647	// native lib dependencies
1648	var provideNativeLibs []string
1649	var requireNativeLibs []string
1650
1651	handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
1652
1653	// TODO(jiyong): do this using WalkPayloadDeps
1654	// TODO(jiyong): make this clean!!!
1655	ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
1656		depTag := ctx.OtherModuleDependencyTag(child)
1657		if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1658			return false
1659		}
1660		depName := ctx.OtherModuleName(child)
1661		if _, isDirectDep := parent.(*apexBundle); isDirectDep {
1662			switch depTag {
1663			case sharedLibTag, jniLibTag:
1664				isJniLib := depTag == jniLibTag
1665				if c, ok := child.(*cc.Module); ok {
1666					fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs)
1667					fi.isJniLib = isJniLib
1668					filesInfo = append(filesInfo, fi)
1669					// Collect the list of stub-providing libs except:
1670					// - VNDK libs are only for vendors
1671					// - bootstrap bionic libs are treated as provided by system
1672					if c.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
1673						provideNativeLibs = append(provideNativeLibs, fi.stem())
1674					}
1675					return true // track transitive dependencies
1676				} else if r, ok := child.(*rust.Module); ok {
1677					fi := apexFileForRustLibrary(ctx, r)
1678					filesInfo = append(filesInfo, fi)
1679				} else {
1680					propertyName := "native_shared_libs"
1681					if isJniLib {
1682						propertyName = "jni_libs"
1683					}
1684					ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
1685				}
1686			case executableTag:
1687				if cc, ok := child.(*cc.Module); ok {
1688					filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc))
1689					return true // track transitive dependencies
1690				} else if sh, ok := child.(*sh.ShBinary); ok {
1691					filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh))
1692				} else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() {
1693					filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py))
1694				} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
1695					filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb))
1696				} else if rust, ok := child.(*rust.Module); ok {
1697					filesInfo = append(filesInfo, apexFileForRustExecutable(ctx, rust))
1698					return true // track transitive dependencies
1699				} else {
1700					ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
1701				}
1702			case bcpfTag:
1703				{
1704					if _, ok := child.(*java.BootclasspathFragmentModule); !ok {
1705						ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
1706						return false
1707					}
1708
1709					filesToAdd := apexBootclasspathFragmentFiles(ctx, child)
1710					filesInfo = append(filesInfo, filesToAdd...)
1711					return true
1712				}
1713			case sscpfTag:
1714				{
1715					if _, ok := child.(*java.SystemServerClasspathModule); !ok {
1716						ctx.PropertyErrorf("systemserverclasspath_fragments", "%q is not a systemserverclasspath_fragment module", depName)
1717						return false
1718					}
1719					filesInfo = append(filesInfo, apexClasspathFragmentProtoFile(ctx, child))
1720					return true
1721				}
1722			case javaLibTag:
1723				switch child.(type) {
1724				case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
1725					af := apexFileForJavaModule(ctx, child.(javaModule))
1726					if !af.ok() {
1727						ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
1728						return false
1729					}
1730					filesInfo = append(filesInfo, af)
1731					return true // track transitive dependencies
1732				default:
1733					ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
1734				}
1735			case androidAppTag:
1736				if ap, ok := child.(*java.AndroidApp); ok {
1737					filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
1738					return true // track transitive dependencies
1739				} else if ap, ok := child.(*java.AndroidAppImport); ok {
1740					filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
1741				} else if ap, ok := child.(*java.AndroidTestHelperApp); ok {
1742					filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
1743				} else if ap, ok := child.(*java.AndroidAppSet); ok {
1744					appDir := "app"
1745					if ap.Privileged() {
1746						appDir = "priv-app"
1747					}
1748					af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(),
1749						filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
1750					af.certificate = java.PresignedCertificate
1751					filesInfo = append(filesInfo, af)
1752				} else {
1753					ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
1754				}
1755			case rroTag:
1756				if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
1757					filesInfo = append(filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
1758				} else {
1759					ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
1760				}
1761			case bpfTag:
1762				if bpfProgram, ok := child.(bpf.BpfModule); ok {
1763					filesToCopy, _ := bpfProgram.OutputFiles("")
1764					for _, bpfFile := range filesToCopy {
1765						filesInfo = append(filesInfo, apexFileForBpfProgram(ctx, bpfFile, bpfProgram))
1766					}
1767				} else {
1768					ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
1769				}
1770			case fsTag:
1771				if fs, ok := child.(filesystem.Filesystem); ok {
1772					filesInfo = append(filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
1773				} else {
1774					ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
1775				}
1776			case prebuiltTag:
1777				if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
1778					filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
1779				} else {
1780					ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
1781				}
1782			case compatConfigTag:
1783				if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
1784					filesInfo = append(filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
1785				} else {
1786					ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
1787				}
1788			case testTag:
1789				if ccTest, ok := child.(*cc.Module); ok {
1790					if ccTest.IsTestPerSrcAllTestsVariation() {
1791						// Multiple-output test module (where `test_per_src: true`).
1792						//
1793						// `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
1794						// We do not add this variation to `filesInfo`, as it has no output;
1795						// however, we do add the other variations of this module as indirect
1796						// dependencies (see below).
1797					} else {
1798						// Single-output test module (where `test_per_src: false`).
1799						af := apexFileForExecutable(ctx, ccTest)
1800						af.class = nativeTest
1801						filesInfo = append(filesInfo, af)
1802					}
1803					return true // track transitive dependencies
1804				} else {
1805					ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
1806				}
1807			case keyTag:
1808				if key, ok := child.(*apexKey); ok {
1809					a.privateKeyFile = key.privateKeyFile
1810					a.publicKeyFile = key.publicKeyFile
1811				} else {
1812					ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
1813				}
1814				return false
1815			case certificateTag:
1816				if dep, ok := child.(*java.AndroidAppCertificate); ok {
1817					a.containerCertificateFile = dep.Certificate.Pem
1818					a.containerPrivateKeyFile = dep.Certificate.Key
1819				} else {
1820					ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
1821				}
1822			case android.PrebuiltDepTag:
1823				// If the prebuilt is force disabled, remember to delete the prebuilt file
1824				// that might have been installed in the previous builds
1825				if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
1826					a.prebuiltFileToDelete = prebuilt.InstallFilename()
1827				}
1828			}
1829		} else if !a.vndkApex {
1830			// indirect dependencies
1831			if am, ok := child.(android.ApexModule); ok {
1832				// We cannot use a switch statement on `depTag` here as the checked
1833				// tags used below are private (e.g. `cc.sharedDepTag`).
1834				if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
1835					if cc, ok := child.(*cc.Module); ok {
1836						if cc.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && cc.IsVndk() {
1837							requireNativeLibs = append(requireNativeLibs, ":vndk")
1838							return false
1839						}
1840						af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
1841						af.transitiveDep = true
1842
1843						// Always track transitive dependencies for host.
1844						if a.Host() {
1845							filesInfo = append(filesInfo, af)
1846							return true
1847						}
1848
1849						abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
1850						if !abInfo.Contents.DirectlyInApex(depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
1851							// If the dependency is a stubs lib, don't include it in this APEX,
1852							// but make sure that the lib is installed on the device.
1853							// In case no APEX is having the lib, the lib is installed to the system
1854							// partition.
1855							//
1856							// Always include if we are a host-apex however since those won't have any
1857							// system libraries.
1858							if !am.DirectlyInAnyApex() {
1859								// we need a module name for Make
1860								name := cc.ImplementationModuleNameForMake(ctx) + cc.Properties.SubName
1861								if !android.InList(name, a.requiredDeps) {
1862									a.requiredDeps = append(a.requiredDeps, name)
1863								}
1864							}
1865							requireNativeLibs = append(requireNativeLibs, af.stem())
1866							// Don't track further
1867							return false
1868						}
1869
1870						// If the dep is not considered to be in the same
1871						// apex, don't add it to filesInfo so that it is not
1872						// included in this APEX.
1873						// TODO(jiyong): move this to at the top of the
1874						// else-if clause for the indirect dependencies.
1875						// Currently, that's impossible because we would
1876						// like to record requiredNativeLibs even when
1877						// DepIsInSameAPex is false. We also shouldn't do
1878						// this for host.
1879						//
1880						// TODO(jiyong): explain why the same module is passed in twice.
1881						// Switching the first am to parent breaks lots of tests.
1882						if !android.IsDepInSameApex(ctx, am, am) {
1883							return false
1884						}
1885
1886						filesInfo = append(filesInfo, af)
1887						return true // track transitive dependencies
1888					} else if rm, ok := child.(*rust.Module); ok {
1889						af := apexFileForRustLibrary(ctx, rm)
1890						af.transitiveDep = true
1891						filesInfo = append(filesInfo, af)
1892						return true // track transitive dependencies
1893					}
1894				} else if cc.IsTestPerSrcDepTag(depTag) {
1895					if cc, ok := child.(*cc.Module); ok {
1896						af := apexFileForExecutable(ctx, cc)
1897						// Handle modules created as `test_per_src` variations of a single test module:
1898						// use the name of the generated test binary (`fileToCopy`) instead of the name
1899						// of the original test module (`depName`, shared by all `test_per_src`
1900						// variations of that module).
1901						af.androidMkModuleName = filepath.Base(af.builtFile.String())
1902						// these are not considered transitive dep
1903						af.transitiveDep = false
1904						filesInfo = append(filesInfo, af)
1905						return true // track transitive dependencies
1906					}
1907				} else if cc.IsHeaderDepTag(depTag) {
1908					// nothing
1909				} else if java.IsJniDepTag(depTag) {
1910					// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
1911					return false
1912				} else if java.IsXmlPermissionsFileDepTag(depTag) {
1913					if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
1914						filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
1915					}
1916				} else if rust.IsDylibDepTag(depTag) {
1917					if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
1918						af := apexFileForRustLibrary(ctx, rustm)
1919						af.transitiveDep = true
1920						filesInfo = append(filesInfo, af)
1921						return true // track transitive dependencies
1922					}
1923				} else if rust.IsRlibDepTag(depTag) {
1924					// Rlib is statically linked, but it might have shared lib
1925					// dependencies. Track them.
1926					return true
1927				} else if java.IsBootclasspathFragmentContentDepTag(depTag) {
1928					// Add the contents of the bootclasspath fragment to the apex.
1929					switch child.(type) {
1930					case *java.Library, *java.SdkLibrary:
1931						javaModule := child.(javaModule)
1932						af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
1933						if !af.ok() {
1934							ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
1935							return false
1936						}
1937						filesInfo = append(filesInfo, af)
1938						return true // track transitive dependencies
1939					default:
1940						ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
1941					}
1942				} else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
1943					// Add the contents of the systemserverclasspath fragment to the apex.
1944					switch child.(type) {
1945					case *java.Library, *java.SdkLibrary:
1946						af := apexFileForJavaModule(ctx, child.(javaModule))
1947						filesInfo = append(filesInfo, af)
1948						return true // track transitive dependencies
1949					default:
1950						ctx.PropertyErrorf("systemserverclasspath_fragments", "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
1951					}
1952				} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
1953					// nothing
1954				} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
1955					ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
1956				}
1957			}
1958		}
1959		return false
1960	})
1961	if a.privateKeyFile == nil {
1962		ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
1963		return
1964	}
1965
1966	// Remove duplicates in filesInfo
1967	removeDup := func(filesInfo []apexFile) []apexFile {
1968		encountered := make(map[string]apexFile)
1969		for _, f := range filesInfo {
1970			dest := filepath.Join(f.installDir, f.builtFile.Base())
1971			if e, ok := encountered[dest]; !ok {
1972				encountered[dest] = f
1973			} else {
1974				// If a module is directly included and also transitively depended on
1975				// consider it as directly included.
1976				e.transitiveDep = e.transitiveDep && f.transitiveDep
1977				encountered[dest] = e
1978			}
1979		}
1980		var result []apexFile
1981		for _, v := range encountered {
1982			result = append(result, v)
1983		}
1984		return result
1985	}
1986	filesInfo = removeDup(filesInfo)
1987
1988	// Sort to have consistent build rules
1989	sort.Slice(filesInfo, func(i, j int) bool {
1990		// Sort by destination path so as to ensure consistent ordering even if the source of the files
1991		// changes.
1992		return filesInfo[i].path() < filesInfo[j].path()
1993	})
1994
1995	////////////////////////////////////////////////////////////////////////////////////////////
1996	// 3) some fields in apexBundle struct are configured
1997	a.installDir = android.PathForModuleInstall(ctx, "apex")
1998	a.filesInfo = filesInfo
1999
2000	// Set suffix and primaryApexType depending on the ApexType
2001	buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuildApps()
2002	switch a.properties.ApexType {
2003	case imageApex:
2004		if buildFlattenedAsDefault {
2005			a.suffix = imageApexSuffix
2006		} else {
2007			a.suffix = ""
2008			a.primaryApexType = true
2009
2010			if ctx.Config().InstallExtraFlattenedApexes() {
2011				a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
2012			}
2013		}
2014	case zipApex:
2015		if proptools.String(a.properties.Payload_type) == "zip" {
2016			a.suffix = ""
2017			a.primaryApexType = true
2018		} else {
2019			a.suffix = zipApexSuffix
2020		}
2021	case flattenedApex:
2022		if buildFlattenedAsDefault {
2023			a.suffix = ""
2024			a.primaryApexType = true
2025		} else {
2026			a.suffix = flattenedSuffix
2027		}
2028	}
2029
2030	switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
2031	case ext4FsType:
2032		a.payloadFsType = ext4
2033	case f2fsFsType:
2034		a.payloadFsType = f2fs
2035	default:
2036		ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs]", *a.properties.Payload_fs_type)
2037	}
2038
2039	// Optimization. If we are building bundled APEX, for the files that are gathered due to the
2040	// transitive dependencies, don't place them inside the APEX, but place a symlink pointing
2041	// the same library in the system partition, thus effectively sharing the same libraries
2042	// across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
2043	// in the APEX.
2044	a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
2045
2046	// APEXes targeting other than system/system_ext partitions use vendor/product variants.
2047	// So we can't link them to /system/lib libs which are core variants.
2048	if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2049		a.linkToSystemLib = false
2050	}
2051
2052	forced := ctx.Config().ForceApexSymlinkOptimization()
2053
2054	// We don't need the optimization for updatable APEXes, as it might give false signal
2055	// to the system health when the APEXes are still bundled (b/149805758).
2056	if !forced && a.Updatable() && a.properties.ApexType == imageApex {
2057		a.linkToSystemLib = false
2058	}
2059
2060	// We also don't want the optimization for host APEXes, because it doesn't make sense.
2061	if ctx.Host() {
2062		a.linkToSystemLib = false
2063	}
2064
2065	a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
2066
2067	////////////////////////////////////////////////////////////////////////////////////////////
2068	// 4) generate the build rules to create the APEX. This is done in builder.go.
2069	a.buildManifest(ctx, provideNativeLibs, requireNativeLibs)
2070	if a.properties.ApexType == flattenedApex {
2071		a.buildFlattenedApex(ctx)
2072	} else {
2073		a.buildUnflattenedApex(ctx)
2074	}
2075	a.buildApexDependencyInfo(ctx)
2076	a.buildLintReports(ctx)
2077
2078	// Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
2079	if a.installable() {
2080		// For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
2081		// along with other ordinary files. (Note that this is done by apexer for
2082		// non-flattened APEXes)
2083		a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
2084
2085		// Place the public key as apex_pubkey. This is also done by apexer for
2086		// non-flattened APEXes case.
2087		// TODO(jiyong): Why do we need this CP rule?
2088		copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
2089		ctx.Build(pctx, android.BuildParams{
2090			Rule:   android.Cp,
2091			Input:  a.publicKeyFile,
2092			Output: copiedPubkey,
2093		})
2094		a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
2095	}
2096}
2097
2098// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2099// the bootclasspath_fragment contributes to the apex.
2100func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2101	bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2102	var filesToAdd []apexFile
2103
2104	// Add the boot image files, e.g. .art, .oat and .vdex files.
2105	for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
2106		dirInApex := filepath.Join("javalib", arch.String())
2107		for _, f := range files {
2108			androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2109			// TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
2110			af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
2111			filesToAdd = append(filesToAdd, af)
2112		}
2113	}
2114
2115	// Add classpaths.proto config.
2116	filesToAdd = append(filesToAdd, apexClasspathFragmentProtoFile(ctx, module))
2117
2118	return filesToAdd
2119}
2120
2121// apexClasspathFragmentProtoFile returns apexFile structure defining the classpath.proto config that
2122// the module contributes to the apex.
2123func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) apexFile {
2124	fragmentInfo := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
2125	classpathProtoOutput := fragmentInfo.ClasspathFragmentProtoOutput
2126	return newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), fragmentInfo.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2127}
2128
2129// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2130// content module, i.e. a library that is part of the bootclasspath.
2131func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2132	bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
2133
2134	// Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2135	// hidden API encpding.
2136	dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2137	if err != nil {
2138		ctx.ModuleErrorf("%s", err)
2139	}
2140
2141	// Create an apexFile as for a normal java module but with the dex boot jar provided by the
2142	// bootclasspath_fragment.
2143	af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2144	return af
2145}
2146
2147///////////////////////////////////////////////////////////////////////////////////////////////////
2148// Factory functions
2149//
2150
2151func newApexBundle() *apexBundle {
2152	module := &apexBundle{}
2153
2154	module.AddProperties(&module.properties)
2155	module.AddProperties(&module.targetProperties)
2156	module.AddProperties(&module.archProperties)
2157	module.AddProperties(&module.overridableProperties)
2158
2159	android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2160	android.InitDefaultableModule(module)
2161	android.InitSdkAwareModule(module)
2162	android.InitOverridableModule(module, &module.overridableProperties.Overrides)
2163	return module
2164}
2165
2166func ApexBundleFactory(testApex bool, artApex bool) android.Module {
2167	bundle := newApexBundle()
2168	bundle.testApex = testApex
2169	bundle.artApex = artApex
2170	return bundle
2171}
2172
2173// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2174// certain compatibility checks such as apex_available are not done for apex_test.
2175func testApexBundleFactory() android.Module {
2176	bundle := newApexBundle()
2177	bundle.testApex = true
2178	return bundle
2179}
2180
2181// apex packages other modules into an APEX file which is a packaging format for system-level
2182// components like binaries, shared libraries, etc.
2183func BundleFactory() android.Module {
2184	return newApexBundle()
2185}
2186
2187type Defaults struct {
2188	android.ModuleBase
2189	android.DefaultsModuleBase
2190}
2191
2192// apex_defaults provides defaultable properties to other apex modules.
2193func defaultsFactory() android.Module {
2194	return DefaultsFactory()
2195}
2196
2197func DefaultsFactory(props ...interface{}) android.Module {
2198	module := &Defaults{}
2199
2200	module.AddProperties(props...)
2201	module.AddProperties(
2202		&apexBundleProperties{},
2203		&apexTargetBundleProperties{},
2204		&overridableProperties{},
2205	)
2206
2207	android.InitDefaultsModule(module)
2208	return module
2209}
2210
2211type OverrideApex struct {
2212	android.ModuleBase
2213	android.OverrideModuleBase
2214}
2215
2216func (o *OverrideApex) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2217	// All the overrides happen in the base module.
2218}
2219
2220// override_apex is used to create an apex module based on another apex module by overriding some of
2221// its properties.
2222func overrideApexFactory() android.Module {
2223	m := &OverrideApex{}
2224
2225	m.AddProperties(&overridableProperties{})
2226
2227	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2228	android.InitOverrideModule(m)
2229	return m
2230}
2231
2232///////////////////////////////////////////////////////////////////////////////////////////////////
2233// Vality check routines
2234//
2235// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2236// certain conditions are not met.
2237//
2238// TODO(jiyong): move these checks to a separate go file.
2239
2240// Entures that min_sdk_version of the included modules are equal or less than the min_sdk_version
2241// of this apexBundle.
2242func (a *apexBundle) checkMinSdkVersion(ctx android.ModuleContext) {
2243	if a.testApex || a.vndkApex {
2244		return
2245	}
2246	// apexBundle::minSdkVersion reports its own errors.
2247	minSdkVersion := a.minSdkVersion(ctx)
2248	android.CheckMinSdkVersion(a, ctx, minSdkVersion)
2249}
2250
2251func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) android.ApiLevel {
2252	ver := proptools.String(a.properties.Min_sdk_version)
2253	if ver == "" {
2254		return android.NoneApiLevel
2255	}
2256	apiLevel, err := android.ApiLevelFromUser(ctx, ver)
2257	if err != nil {
2258		ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
2259		return android.NoneApiLevel
2260	}
2261	return apiLevel
2262}
2263
2264// Ensures that a lib providing stub isn't statically linked
2265func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2266	// Practically, we only care about regular APEXes on the device.
2267	if ctx.Host() || a.testApex || a.vndkApex {
2268		return
2269	}
2270
2271	abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
2272
2273	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2274		if ccm, ok := to.(*cc.Module); ok {
2275			apexName := ctx.ModuleName()
2276			fromName := ctx.OtherModuleName(from)
2277			toName := ctx.OtherModuleName(to)
2278
2279			// If `to` is not actually in the same APEX as `from` then it does not need
2280			// apex_available and neither do any of its dependencies.
2281			//
2282			// It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
2283			if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2284				// As soon as the dependency graph crosses the APEX boundary, don't go further.
2285				return false
2286			}
2287
2288			// The dynamic linker and crash_dump tool in the runtime APEX is the only
2289			// exception to this rule. It can't make the static dependencies dynamic
2290			// because it can't do the dynamic linking for itself.
2291			// Same rule should be applied to linkerconfig, because it should be executed
2292			// only with static linked libraries before linker is available with ld.config.txt
2293			if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
2294				return false
2295			}
2296
2297			isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
2298			if isStubLibraryFromOtherApex && !externalDep {
2299				ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2300					"It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2301			}
2302
2303		}
2304		return true
2305	})
2306}
2307
2308// Enforce that Java deps of the apex are using stable SDKs to compile
2309func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2310	if a.Updatable() {
2311		if String(a.properties.Min_sdk_version) == "" {
2312			ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2313		}
2314		a.checkJavaStableSdkVersion(ctx)
2315	}
2316}
2317
2318func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
2319	// Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2320	// java's checkLinkType guarantees correct usage for transitive deps
2321	ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2322		tag := ctx.OtherModuleDependencyTag(module)
2323		switch tag {
2324		case javaLibTag, androidAppTag:
2325			if m, ok := module.(interface {
2326				CheckStableSdkVersion(ctx android.BaseModuleContext) error
2327			}); ok {
2328				if err := m.CheckStableSdkVersion(ctx); err != nil {
2329					ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2330				}
2331			}
2332		}
2333	})
2334}
2335
2336// Ensures that the all the dependencies are marked as available for this APEX
2337func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2338	// Let's be practical. Availability for test, host, and the VNDK apex isn't important
2339	if ctx.Host() || a.testApex || a.vndkApex {
2340		return
2341	}
2342
2343	// Because APEXes targeting other than system/system_ext partitions can't set
2344	// apex_available, we skip checks for these APEXes
2345	if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2346		return
2347	}
2348
2349	// Coverage build adds additional dependencies for the coverage-only runtime libraries.
2350	// Requiring them and their transitive depencies with apex_available is not right
2351	// because they just add noise.
2352	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2353		return
2354	}
2355
2356	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2357		// As soon as the dependency graph crosses the APEX boundary, don't go further.
2358		if externalDep {
2359			return false
2360		}
2361
2362		apexName := ctx.ModuleName()
2363		fromName := ctx.OtherModuleName(from)
2364		toName := ctx.OtherModuleName(to)
2365
2366		// If `to` is not actually in the same APEX as `from` then it does not need
2367		// apex_available and neither do any of its dependencies.
2368		//
2369		// It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
2370		if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2371			// As soon as the dependency graph crosses the APEX boundary, don't go
2372			// further.
2373			return false
2374		}
2375
2376		if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
2377			return true
2378		}
2379		ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2380			"\n\nDependency path:%s\n\n"+
2381			"Consider adding %q to 'apex_available' property of %q",
2382			fromName, toName, ctx.GetPathString(true), apexName, toName)
2383		// Visit this module's dependencies to check and report any issues with their availability.
2384		return true
2385	})
2386}
2387
2388var (
2389	apexAvailBaseline        = makeApexAvailableBaseline()
2390	inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
2391)
2392
2393func baselineApexAvailable(apex, moduleName string) bool {
2394	key := apex
2395	moduleName = normalizeModuleName(moduleName)
2396
2397	if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
2398		return true
2399	}
2400
2401	key = android.AvailableToAnyApex
2402	if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
2403		return true
2404	}
2405
2406	return false
2407}
2408
2409func normalizeModuleName(moduleName string) string {
2410	// Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
2411	// system. Trim the prefix for the check since they are confusing
2412	moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
2413	if strings.HasPrefix(moduleName, "libclang_rt.") {
2414		// This module has many arch variants that depend on the product being built.
2415		// We don't want to list them all
2416		moduleName = "libclang_rt"
2417	}
2418	if strings.HasPrefix(moduleName, "androidx.") {
2419		// TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
2420		moduleName = "androidx"
2421	}
2422	return moduleName
2423}
2424
2425// Transform the map of apex -> modules to module -> apexes.
2426func invertApexBaseline(m map[string][]string) map[string][]string {
2427	r := make(map[string][]string)
2428	for apex, modules := range m {
2429		for _, module := range modules {
2430			r[module] = append(r[module], apex)
2431		}
2432	}
2433	return r
2434}
2435
2436// Retrieve the baseline of apexes to which the supplied module belongs.
2437func BaselineApexAvailable(moduleName string) []string {
2438	return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
2439}
2440
2441// This is a map from apex to modules, which overrides the apex_available setting for that
2442// particular module to make it available for the apex regardless of its setting.
2443// TODO(b/147364041): remove this
2444func makeApexAvailableBaseline() map[string][]string {
2445	// The "Module separator"s below are employed to minimize merge conflicts.
2446	m := make(map[string][]string)
2447	//
2448	// Module separator
2449	//
2450	m["com.android.appsearch"] = []string{
2451		"icing-java-proto-lite",
2452		"libprotobuf-java-lite",
2453	}
2454	//
2455	// Module separator
2456	//
2457	m["com.android.bluetooth.updatable"] = []string{
2458		"android.hardware.audio.common@5.0",
2459		"android.hardware.bluetooth.a2dp@1.0",
2460		"android.hardware.bluetooth.audio@2.0",
2461		"android.hardware.bluetooth@1.0",
2462		"android.hardware.bluetooth@1.1",
2463		"android.hardware.graphics.bufferqueue@1.0",
2464		"android.hardware.graphics.bufferqueue@2.0",
2465		"android.hardware.graphics.common@1.0",
2466		"android.hardware.graphics.common@1.1",
2467		"android.hardware.graphics.common@1.2",
2468		"android.hardware.media@1.0",
2469		"android.hidl.safe_union@1.0",
2470		"android.hidl.token@1.0",
2471		"android.hidl.token@1.0-utils",
2472		"avrcp-target-service",
2473		"avrcp_headers",
2474		"bluetooth-protos-lite",
2475		"bluetooth.mapsapi",
2476		"com.android.vcard",
2477		"dnsresolver_aidl_interface-V2-java",
2478		"ipmemorystore-aidl-interfaces-V5-java",
2479		"ipmemorystore-aidl-interfaces-java",
2480		"internal_include_headers",
2481		"lib-bt-packets",
2482		"lib-bt-packets-avrcp",
2483		"lib-bt-packets-base",
2484		"libFraunhoferAAC",
2485		"libaudio-a2dp-hw-utils",
2486		"libaudio-hearing-aid-hw-utils",
2487		"libbluetooth",
2488		"libbluetooth-types",
2489		"libbluetooth-types-header",
2490		"libbluetooth_gd",
2491		"libbluetooth_headers",
2492		"libbluetooth_jni",
2493		"libbt-audio-hal-interface",
2494		"libbt-bta",
2495		"libbt-common",
2496		"libbt-hci",
2497		"libbt-platform-protos-lite",
2498		"libbt-protos-lite",
2499		"libbt-sbc-decoder",
2500		"libbt-sbc-encoder",
2501		"libbt-stack",
2502		"libbt-utils",
2503		"libbtcore",
2504		"libbtdevice",
2505		"libbte",
2506		"libbtif",
2507		"libchrome",
2508		"libevent",
2509		"libfmq",
2510		"libg722codec",
2511		"libgui_headers",
2512		"libmedia_headers",
2513		"libmodpb64",
2514		"libosi",
2515		"libstagefright_foundation_headers",
2516		"libstagefright_headers",
2517		"libstatslog",
2518		"libstatssocket",
2519		"libtinyxml2",
2520		"libudrv-uipc",
2521		"libz",
2522		"media_plugin_headers",
2523		"net-utils-services-common",
2524		"netd_aidl_interface-unstable-java",
2525		"netd_event_listener_interface-java",
2526		"netlink-client",
2527		"networkstack-client",
2528		"sap-api-java-static",
2529		"services.net",
2530	}
2531	//
2532	// Module separator
2533	//
2534	m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
2535	//
2536	// Module separator
2537	//
2538	m["com.android.extservices"] = []string{
2539		"error_prone_annotations",
2540		"ExtServices-core",
2541		"ExtServices",
2542		"libtextclassifier-java",
2543		"libz_current",
2544		"textclassifier-statsd",
2545		"TextClassifierNotificationLibNoManifest",
2546		"TextClassifierServiceLibNoManifest",
2547	}
2548	//
2549	// Module separator
2550	//
2551	m["com.android.neuralnetworks"] = []string{
2552		"android.hardware.neuralnetworks@1.0",
2553		"android.hardware.neuralnetworks@1.1",
2554		"android.hardware.neuralnetworks@1.2",
2555		"android.hardware.neuralnetworks@1.3",
2556		"android.hidl.allocator@1.0",
2557		"android.hidl.memory.token@1.0",
2558		"android.hidl.memory@1.0",
2559		"android.hidl.safe_union@1.0",
2560		"libarect",
2561		"libbuildversion",
2562		"libmath",
2563		"libprocpartition",
2564		"libsync",
2565	}
2566	//
2567	// Module separator
2568	//
2569	m["com.android.media"] = []string{
2570		"android.frameworks.bufferhub@1.0",
2571		"android.hardware.cas.native@1.0",
2572		"android.hardware.cas@1.0",
2573		"android.hardware.configstore-utils",
2574		"android.hardware.configstore@1.0",
2575		"android.hardware.configstore@1.1",
2576		"android.hardware.graphics.allocator@2.0",
2577		"android.hardware.graphics.allocator@3.0",
2578		"android.hardware.graphics.bufferqueue@1.0",
2579		"android.hardware.graphics.bufferqueue@2.0",
2580		"android.hardware.graphics.common@1.0",
2581		"android.hardware.graphics.common@1.1",
2582		"android.hardware.graphics.common@1.2",
2583		"android.hardware.graphics.mapper@2.0",
2584		"android.hardware.graphics.mapper@2.1",
2585		"android.hardware.graphics.mapper@3.0",
2586		"android.hardware.media.omx@1.0",
2587		"android.hardware.media@1.0",
2588		"android.hidl.allocator@1.0",
2589		"android.hidl.memory.token@1.0",
2590		"android.hidl.memory@1.0",
2591		"android.hidl.token@1.0",
2592		"android.hidl.token@1.0-utils",
2593		"bionic_libc_platform_headers",
2594		"exoplayer2-extractor",
2595		"exoplayer2-extractor-annotation-stubs",
2596		"gl_headers",
2597		"jsr305",
2598		"libEGL",
2599		"libEGL_blobCache",
2600		"libEGL_getProcAddress",
2601		"libFLAC",
2602		"libFLAC-config",
2603		"libFLAC-headers",
2604		"libGLESv2",
2605		"libaacextractor",
2606		"libamrextractor",
2607		"libarect",
2608		"libaudio_system_headers",
2609		"libaudioclient",
2610		"libaudioclient_headers",
2611		"libaudiofoundation",
2612		"libaudiofoundation_headers",
2613		"libaudiomanager",
2614		"libaudiopolicy",
2615		"libaudioutils",
2616		"libaudioutils_fixedfft",
2617		"libbluetooth-types-header",
2618		"libbufferhub",
2619		"libbufferhub_headers",
2620		"libbufferhubqueue",
2621		"libc_malloc_debug_backtrace",
2622		"libcamera_client",
2623		"libcamera_metadata",
2624		"libdvr_headers",
2625		"libexpat",
2626		"libfifo",
2627		"libflacextractor",
2628		"libgrallocusage",
2629		"libgraphicsenv",
2630		"libgui",
2631		"libgui_headers",
2632		"libhardware_headers",
2633		"libinput",
2634		"liblzma",
2635		"libmath",
2636		"libmedia",
2637		"libmedia_codeclist",
2638		"libmedia_headers",
2639		"libmedia_helper",
2640		"libmedia_helper_headers",
2641		"libmedia_midiiowrapper",
2642		"libmedia_omx",
2643		"libmediautils",
2644		"libmidiextractor",
2645		"libmkvextractor",
2646		"libmp3extractor",
2647		"libmp4extractor",
2648		"libmpeg2extractor",
2649		"libnativebase_headers",
2650		"libnativewindow_headers",
2651		"libnblog",
2652		"liboggextractor",
2653		"libpackagelistparser",
2654		"libpdx",
2655		"libpdx_default_transport",
2656		"libpdx_headers",
2657		"libpdx_uds",
2658		"libprocinfo",
2659		"libspeexresampler",
2660		"libspeexresampler",
2661		"libstagefright_esds",
2662		"libstagefright_flacdec",
2663		"libstagefright_flacdec",
2664		"libstagefright_foundation",
2665		"libstagefright_foundation_headers",
2666		"libstagefright_foundation_without_imemory",
2667		"libstagefright_headers",
2668		"libstagefright_id3",
2669		"libstagefright_metadatautils",
2670		"libstagefright_mpeg2extractor",
2671		"libstagefright_mpeg2support",
2672		"libsync",
2673		"libui",
2674		"libui_headers",
2675		"libunwindstack",
2676		"libvibrator",
2677		"libvorbisidec",
2678		"libwavextractor",
2679		"libwebm",
2680		"media_ndk_headers",
2681		"media_plugin_headers",
2682		"updatable-media",
2683	}
2684	//
2685	// Module separator
2686	//
2687	m["com.android.media.swcodec"] = []string{
2688		"android.frameworks.bufferhub@1.0",
2689		"android.hardware.common-ndk_platform",
2690		"android.hardware.configstore-utils",
2691		"android.hardware.configstore@1.0",
2692		"android.hardware.configstore@1.1",
2693		"android.hardware.graphics.allocator@2.0",
2694		"android.hardware.graphics.allocator@3.0",
2695		"android.hardware.graphics.allocator@4.0",
2696		"android.hardware.graphics.bufferqueue@1.0",
2697		"android.hardware.graphics.bufferqueue@2.0",
2698		"android.hardware.graphics.common-ndk_platform",
2699		"android.hardware.graphics.common@1.0",
2700		"android.hardware.graphics.common@1.1",
2701		"android.hardware.graphics.common@1.2",
2702		"android.hardware.graphics.mapper@2.0",
2703		"android.hardware.graphics.mapper@2.1",
2704		"android.hardware.graphics.mapper@3.0",
2705		"android.hardware.graphics.mapper@4.0",
2706		"android.hardware.media.bufferpool@2.0",
2707		"android.hardware.media.c2@1.0",
2708		"android.hardware.media.c2@1.1",
2709		"android.hardware.media.omx@1.0",
2710		"android.hardware.media@1.0",
2711		"android.hardware.media@1.0",
2712		"android.hidl.memory.token@1.0",
2713		"android.hidl.memory@1.0",
2714		"android.hidl.safe_union@1.0",
2715		"android.hidl.token@1.0",
2716		"android.hidl.token@1.0-utils",
2717		"libEGL",
2718		"libFLAC",
2719		"libFLAC-config",
2720		"libFLAC-headers",
2721		"libFraunhoferAAC",
2722		"libLibGuiProperties",
2723		"libarect",
2724		"libaudio_system_headers",
2725		"libaudioutils",
2726		"libaudioutils",
2727		"libaudioutils_fixedfft",
2728		"libavcdec",
2729		"libavcenc",
2730		"libavservices_minijail",
2731		"libavservices_minijail",
2732		"libbinderthreadstateutils",
2733		"libbluetooth-types-header",
2734		"libbufferhub_headers",
2735		"libcodec2",
2736		"libcodec2_headers",
2737		"libcodec2_hidl@1.0",
2738		"libcodec2_hidl@1.1",
2739		"libcodec2_internal",
2740		"libcodec2_soft_aacdec",
2741		"libcodec2_soft_aacenc",
2742		"libcodec2_soft_amrnbdec",
2743		"libcodec2_soft_amrnbenc",
2744		"libcodec2_soft_amrwbdec",
2745		"libcodec2_soft_amrwbenc",
2746		"libcodec2_soft_av1dec_gav1",
2747		"libcodec2_soft_avcdec",
2748		"libcodec2_soft_avcenc",
2749		"libcodec2_soft_common",
2750		"libcodec2_soft_flacdec",
2751		"libcodec2_soft_flacenc",
2752		"libcodec2_soft_g711alawdec",
2753		"libcodec2_soft_g711mlawdec",
2754		"libcodec2_soft_gsmdec",
2755		"libcodec2_soft_h263dec",
2756		"libcodec2_soft_h263enc",
2757		"libcodec2_soft_hevcdec",
2758		"libcodec2_soft_hevcenc",
2759		"libcodec2_soft_mp3dec",
2760		"libcodec2_soft_mpeg2dec",
2761		"libcodec2_soft_mpeg4dec",
2762		"libcodec2_soft_mpeg4enc",
2763		"libcodec2_soft_opusdec",
2764		"libcodec2_soft_opusenc",
2765		"libcodec2_soft_rawdec",
2766		"libcodec2_soft_vorbisdec",
2767		"libcodec2_soft_vp8dec",
2768		"libcodec2_soft_vp8enc",
2769		"libcodec2_soft_vp9dec",
2770		"libcodec2_soft_vp9enc",
2771		"libcodec2_vndk",
2772		"libdvr_headers",
2773		"libfmq",
2774		"libfmq",
2775		"libgav1",
2776		"libgralloctypes",
2777		"libgrallocusage",
2778		"libgraphicsenv",
2779		"libgsm",
2780		"libgui_bufferqueue_static",
2781		"libgui_headers",
2782		"libhardware",
2783		"libhardware_headers",
2784		"libhevcdec",
2785		"libhevcenc",
2786		"libion",
2787		"libjpeg",
2788		"liblzma",
2789		"libmath",
2790		"libmedia_codecserviceregistrant",
2791		"libmedia_headers",
2792		"libmpeg2dec",
2793		"libnativebase_headers",
2794		"libnativewindow_headers",
2795		"libpdx_headers",
2796		"libscudo_wrapper",
2797		"libsfplugin_ccodec_utils",
2798		"libspeexresampler",
2799		"libstagefright_amrnb_common",
2800		"libstagefright_amrnbdec",
2801		"libstagefright_amrnbenc",
2802		"libstagefright_amrwbdec",
2803		"libstagefright_amrwbenc",
2804		"libstagefright_bufferpool@2.0.1",
2805		"libstagefright_enc_common",
2806		"libstagefright_flacdec",
2807		"libstagefright_foundation",
2808		"libstagefright_foundation_headers",
2809		"libstagefright_headers",
2810		"libstagefright_m4vh263dec",
2811		"libstagefright_m4vh263enc",
2812		"libstagefright_mp3dec",
2813		"libsync",
2814		"libui",
2815		"libui_headers",
2816		"libunwindstack",
2817		"libvorbisidec",
2818		"libvpx",
2819		"libyuv",
2820		"libyuv_static",
2821		"media_ndk_headers",
2822		"media_plugin_headers",
2823		"mediaswcodec",
2824	}
2825	//
2826	// Module separator
2827	//
2828	m["com.android.mediaprovider"] = []string{
2829		"MediaProvider",
2830		"MediaProviderGoogle",
2831		"fmtlib_ndk",
2832		"libbase_ndk",
2833		"libfuse",
2834		"libfuse_jni",
2835	}
2836	//
2837	// Module separator
2838	//
2839	m["com.android.permission"] = []string{
2840		"car-ui-lib",
2841		"iconloader",
2842		"kotlin-annotations",
2843		"kotlin-stdlib",
2844		"kotlin-stdlib-jdk7",
2845		"kotlin-stdlib-jdk8",
2846		"kotlinx-coroutines-android",
2847		"kotlinx-coroutines-android-nodeps",
2848		"kotlinx-coroutines-core",
2849		"kotlinx-coroutines-core-nodeps",
2850		"permissioncontroller-statsd",
2851		"GooglePermissionController",
2852		"PermissionController",
2853		"SettingsLibActionBarShadow",
2854		"SettingsLibAppPreference",
2855		"SettingsLibBarChartPreference",
2856		"SettingsLibLayoutPreference",
2857		"SettingsLibProgressBar",
2858		"SettingsLibSearchWidget",
2859		"SettingsLibSettingsTheme",
2860		"SettingsLibRestrictedLockUtils",
2861		"SettingsLibHelpUtils",
2862	}
2863	//
2864	// Module separator
2865	//
2866	m["com.android.runtime"] = []string{
2867		"bionic_libc_platform_headers",
2868		"libarm-optimized-routines-math",
2869		"libc_aeabi",
2870		"libc_bionic",
2871		"libc_bionic_ndk",
2872		"libc_bootstrap",
2873		"libc_common",
2874		"libc_common_shared",
2875		"libc_common_static",
2876		"libc_dns",
2877		"libc_dynamic_dispatch",
2878		"libc_fortify",
2879		"libc_freebsd",
2880		"libc_freebsd_large_stack",
2881		"libc_gdtoa",
2882		"libc_init_dynamic",
2883		"libc_init_static",
2884		"libc_jemalloc_wrapper",
2885		"libc_netbsd",
2886		"libc_nomalloc",
2887		"libc_nopthread",
2888		"libc_openbsd",
2889		"libc_openbsd_large_stack",
2890		"libc_openbsd_ndk",
2891		"libc_pthread",
2892		"libc_static_dispatch",
2893		"libc_syscalls",
2894		"libc_tzcode",
2895		"libc_unwind_static",
2896		"libdebuggerd",
2897		"libdebuggerd_common_headers",
2898		"libdebuggerd_handler_core",
2899		"libdebuggerd_handler_fallback",
2900		"libdl_static",
2901		"libjemalloc5",
2902		"liblinker_main",
2903		"liblinker_malloc",
2904		"liblz4",
2905		"liblzma",
2906		"libprocinfo",
2907		"libpropertyinfoparser",
2908		"libscudo",
2909		"libstdc++",
2910		"libsystemproperties",
2911		"libtombstoned_client_static",
2912		"libunwindstack",
2913		"libz",
2914		"libziparchive",
2915	}
2916	//
2917	// Module separator
2918	//
2919	m["com.android.tethering"] = []string{
2920		"android.hardware.tetheroffload.config-V1.0-java",
2921		"android.hardware.tetheroffload.control-V1.0-java",
2922		"android.hidl.base-V1.0-java",
2923		"libcgrouprc",
2924		"libcgrouprc_format",
2925		"libtetherutilsjni",
2926		"libvndksupport",
2927		"net-utils-framework-common",
2928		"netd_aidl_interface-V3-java",
2929		"netlink-client",
2930		"networkstack-aidl-interfaces-java",
2931		"tethering-aidl-interfaces-java",
2932		"TetheringApiCurrentLib",
2933	}
2934	//
2935	// Module separator
2936	//
2937	m["com.android.wifi"] = []string{
2938		"PlatformProperties",
2939		"android.hardware.wifi-V1.0-java",
2940		"android.hardware.wifi-V1.0-java-constants",
2941		"android.hardware.wifi-V1.1-java",
2942		"android.hardware.wifi-V1.2-java",
2943		"android.hardware.wifi-V1.3-java",
2944		"android.hardware.wifi-V1.4-java",
2945		"android.hardware.wifi.hostapd-V1.0-java",
2946		"android.hardware.wifi.hostapd-V1.1-java",
2947		"android.hardware.wifi.hostapd-V1.2-java",
2948		"android.hardware.wifi.supplicant-V1.0-java",
2949		"android.hardware.wifi.supplicant-V1.1-java",
2950		"android.hardware.wifi.supplicant-V1.2-java",
2951		"android.hardware.wifi.supplicant-V1.3-java",
2952		"android.hidl.base-V1.0-java",
2953		"android.hidl.manager-V1.0-java",
2954		"android.hidl.manager-V1.1-java",
2955		"android.hidl.manager-V1.2-java",
2956		"bouncycastle-unbundled",
2957		"dnsresolver_aidl_interface-V2-java",
2958		"error_prone_annotations",
2959		"framework-wifi-pre-jarjar",
2960		"framework-wifi-util-lib",
2961		"ipmemorystore-aidl-interfaces-V3-java",
2962		"ipmemorystore-aidl-interfaces-java",
2963		"ksoap2",
2964		"libnanohttpd",
2965		"libwifi-jni",
2966		"net-utils-services-common",
2967		"netd_aidl_interface-V2-java",
2968		"netd_aidl_interface-unstable-java",
2969		"netd_event_listener_interface-java",
2970		"netlink-client",
2971		"networkstack-client",
2972		"services.net",
2973		"wifi-lite-protos",
2974		"wifi-nano-protos",
2975		"wifi-service-pre-jarjar",
2976		"wifi-service-resources",
2977	}
2978	//
2979	// Module separator
2980	//
2981	m["com.android.os.statsd"] = []string{
2982		"libstatssocket",
2983	}
2984	//
2985	// Module separator
2986	//
2987	m[android.AvailableToAnyApex] = []string{
2988		// TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
2989		"androidx",
2990		"androidx-constraintlayout_constraintlayout",
2991		"androidx-constraintlayout_constraintlayout-nodeps",
2992		"androidx-constraintlayout_constraintlayout-solver",
2993		"androidx-constraintlayout_constraintlayout-solver-nodeps",
2994		"com.google.android.material_material",
2995		"com.google.android.material_material-nodeps",
2996
2997		"libclang_rt",
2998		"libprofile-clang-extras",
2999		"libprofile-clang-extras_ndk",
3000		"libprofile-extras",
3001		"libprofile-extras_ndk",
3002		"libunwind",
3003	}
3004	return m
3005}
3006
3007func init() {
3008	android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...)
3009	android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...)
3010}
3011
3012func createApexPermittedPackagesRules(modules_packages map[string][]string) []android.Rule {
3013	rules := make([]android.Rule, 0, len(modules_packages))
3014	for module_name, module_packages := range modules_packages {
3015		permittedPackagesRule := android.NeverAllow().
3016			BootclasspathJar().
3017			With("apex_available", module_name).
3018			WithMatcher("permitted_packages", android.NotInList(module_packages)).
3019			Because("jars that are part of the " + module_name +
3020				" module may only allow these packages: " + strings.Join(module_packages, ",") +
3021				". Please jarjar or move code around.")
3022		rules = append(rules, permittedPackagesRule)
3023	}
3024	return rules
3025}
3026
3027// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
3028// Adding code to the bootclasspath in new packages will cause issues on module update.
3029func qModulesPackages() map[string][]string {
3030	return map[string][]string{
3031		"com.android.conscrypt": []string{
3032			"android.net.ssl",
3033			"com.android.org.conscrypt",
3034		},
3035		"com.android.media": []string{
3036			"android.media",
3037		},
3038	}
3039}
3040
3041// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
3042// Adding code to the bootclasspath in new packages will cause issues on module update.
3043func rModulesPackages() map[string][]string {
3044	return map[string][]string{
3045		"com.android.mediaprovider": []string{
3046			"android.provider",
3047		},
3048		"com.android.permission": []string{
3049			"android.permission",
3050			"android.app.role",
3051			"com.android.permission",
3052			"com.android.role",
3053		},
3054		"com.android.sdkext": []string{
3055			"android.os.ext",
3056		},
3057		"com.android.os.statsd": []string{
3058			"android.app",
3059			"android.os",
3060			"android.util",
3061			"com.android.internal.statsd",
3062			"com.android.server.stats",
3063		},
3064		"com.android.wifi": []string{
3065			"com.android.server.wifi",
3066			"com.android.wifi.x",
3067			"android.hardware.wifi",
3068			"android.net.wifi",
3069		},
3070		"com.android.tethering": []string{
3071			"android.net",
3072		},
3073	}
3074}
3075