// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// package apex implements build rules for creating the APEX files which are container for
// lower-level system components. See https://source.android.com/devices/tech/ota/apex
package apex

import (
	"fmt"
	"log"
	"path/filepath"
	"regexp"
	"sort"
	"strings"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/bpf"
	"android/soong/cc"
	prebuilt_etc "android/soong/etc"
	"android/soong/filesystem"
	"android/soong/java"
	"android/soong/multitree"
	"android/soong/rust"
	"android/soong/sh"
)

func init() {
	registerApexBuildComponents(android.InitRegistrationContext)
}

func registerApexBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("apex", BundleFactory)
	ctx.RegisterModuleType("apex_test", TestApexBundleFactory)
	ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
	ctx.RegisterModuleType("apex_defaults", DefaultsFactory)
	ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
	ctx.RegisterModuleType("override_apex", OverrideApexFactory)
	ctx.RegisterModuleType("apex_set", apexSetFactory)

	ctx.PreArchMutators(registerPreArchMutators)
	ctx.PreDepsMutators(RegisterPreDepsMutators)
	ctx.PostDepsMutators(RegisterPostDepsMutators)
}

func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
	ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
}

func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
	ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
	ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
}

func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
	ctx.TopDown("apex_info", apexInfoMutator).Parallel()
	ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
	ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
	ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
	// Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
	// it should create a platform variant.
	ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
	ctx.BottomUp("apex", apexMutator).Parallel()
	ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
	ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
	// Register after apex_info mutator so that it can use ApexVariationName
	ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
}

type apexBundleProperties struct {
	// Json manifest file describing meta info of this APEX bundle. Refer to
	// system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
	Manifest *string `android:"path"`

	// AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
	// a default one is automatically generated.
	AndroidManifest *string `android:"path"`

	// Determines the file contexts file for setting the security contexts to files in this APEX
	// bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
	// /system/sepolicy/apex/<module_name>_file_contexts.
	File_contexts *string `android:"path"`

	// By default, file_contexts is amended by force-labelling / and /apex_manifest.pb as system_file
	// to avoid mistakes. When set as true, no force-labelling.
	Use_file_contexts_as_is *bool

	// Path to the canned fs config file for customizing file's
	// uid/gid/mod/capabilities. The content of this file is appended to the
	// default config, so that the custom entries are preferred. The format is
	// /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where
	// path_or_glob is a path or glob pattern for a file or set of files,
	// uid/gid are numerial values of user ID and group ID, mode is octal value
	// for the file mode, and cap is hexadecimal value for the capability.
	Canned_fs_config *string `android:"path"`

	ApexNativeDependencies

	Multilib apexMultilibProperties

	// List of runtime resource overlays (RROs) that are embedded inside this APEX.
	Rros []string

	// List of bootclasspath fragments that are embedded inside this APEX bundle.
	Bootclasspath_fragments []string

	// List of systemserverclasspath fragments that are embedded inside this APEX bundle.
	Systemserverclasspath_fragments []string

	// List of java libraries that are embedded inside this APEX bundle.
	Java_libs []string

	// List of sh binaries that are embedded inside this APEX bundle.
	Sh_binaries []string

	// List of platform_compat_config files that are embedded inside this APEX bundle.
	Compat_configs []string

	// List of filesystem images that are embedded inside this APEX bundle.
	Filesystems []string

	// List of module names which we don't want to add as transitive deps. This can be used as
	// a workaround when the current implementation collects more than necessary. For example,
	// Rust binaries with prefer_rlib:true add unnecessary dependencies.
	Unwanted_transitive_deps []string

	// The minimum SDK version that this APEX must support at minimum. This is usually set to
	// the SDK version that the APEX was first introduced.
	Min_sdk_version *string

	// Whether this APEX is considered updatable or not. When set to true, this will enforce
	// additional rules for making sure that the APEX is truly updatable. To be updatable,
	// min_sdk_version should be set as well. This will also disable the size optimizations like
	// symlinking to the system libs. Default is true.
	Updatable *bool

	// Marks that this APEX is designed to be updatable in the future, although it's not
	// updatable yet. This is used to mimic some of the build behaviors that are applied only to
	// updatable APEXes. Currently, this disables the size optimization, so that the size of
	// APEX will not increase when the APEX is actually marked as truly updatable. Default is
	// false.
	Future_updatable *bool

	// Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
	// false`. Default is false.
	Platform_apis *bool

	// Whether this APEX is installable to one of the partitions like system, vendor, etc.
	// Default: true.
	Installable *bool

	// If set true, VNDK libs are considered as stable libs and are not included in this APEX.
	// Should be only used in non-system apexes (e.g. vendor: true). Default is false.
	Use_vndk_as_stable *bool

	// The type of filesystem to use. Either 'ext4', 'f2fs' or 'erofs'. Default 'ext4'.
	Payload_fs_type *string

	// For telling the APEX to ignore special handling for system libraries such as bionic.
	// Default is false.
	Ignore_system_library_special_case *bool

	// Whenever apex_payload.img of the APEX should include dm-verity hashtree.
	// Default value is true.
	Generate_hashtree *bool

	// Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
	// used in tests.
	Test_only_unsigned_payload *bool

	// Whenever apex should be compressed, regardless of product flag used. Should be only
	// used in tests.
	Test_only_force_compression *bool

	// Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
	// with the tool to sign payload contents.
	Custom_sign_tool *string

	// Whether this is a dynamic common lib apex, if so the native shared libs will be placed
	// in a special way that include the digest of the lib file under /lib(64)?
	Dynamic_common_lib_apex *bool

	// Canonical name of this APEX bundle. Used to determine the path to the
	// activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
	// apex mutator variations. For override_apex modules, this is the name of the
	// overridden base module.
	ApexVariationName string `blueprint:"mutated"`

	IsCoverageVariant bool `blueprint:"mutated"`

	// List of sanitizer names that this APEX is enabled for
	SanitizerNames []string `blueprint:"mutated"`

	PreventInstall bool `blueprint:"mutated"`

	HideFromMake bool `blueprint:"mutated"`

	// Name that dependencies can specify in their apex_available properties to refer to this module.
	// If not specified, this defaults to Soong module name. This must be the name of a Soong module.
	Apex_available_name *string

	// Variant version of the mainline module. Must be an integer between 0-9
	Variant_version *string
}

type ApexNativeDependencies struct {
	// List of native libraries that are embedded inside this APEX.
	Native_shared_libs []string

	// List of JNI libraries that are embedded inside this APEX.
	Jni_libs []string

	// List of rust dyn libraries that are embedded inside this APEX.
	Rust_dyn_libs []string

	// List of native executables that are embedded inside this APEX.
	Binaries []string

	// List of native tests that are embedded inside this APEX.
	Tests []string

	// List of filesystem images that are embedded inside this APEX bundle.
	Filesystems []string

	// List of prebuilt_etcs that are embedded inside this APEX bundle.
	Prebuilts []string

	// List of native libraries to exclude from this APEX.
	Exclude_native_shared_libs []string

	// List of JNI libraries to exclude from this APEX.
	Exclude_jni_libs []string

	// List of rust dyn libraries to exclude from this APEX.
	Exclude_rust_dyn_libs []string

	// List of native executables to exclude from this APEX.
	Exclude_binaries []string

	// List of native tests to exclude from this APEX.
	Exclude_tests []string

	// List of filesystem images to exclude from this APEX bundle.
	Exclude_filesystems []string

	// List of prebuilt_etcs to exclude from this APEX bundle.
	Exclude_prebuilts []string
}

// Merge combines another ApexNativeDependencies into this one
func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
	a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
	a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
	a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
	a.Binaries = append(a.Binaries, b.Binaries...)
	a.Tests = append(a.Tests, b.Tests...)
	a.Filesystems = append(a.Filesystems, b.Filesystems...)
	a.Prebuilts = append(a.Prebuilts, b.Prebuilts...)

	a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
	a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
	a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
	a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
	a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
	a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
	a.Exclude_prebuilts = append(a.Exclude_prebuilts, b.Exclude_prebuilts...)
}

type apexMultilibProperties struct {
	// Native dependencies whose compile_multilib is "first"
	First ApexNativeDependencies

	// Native dependencies whose compile_multilib is "both"
	Both ApexNativeDependencies

	// Native dependencies whose compile_multilib is "prefer32"
	Prefer32 ApexNativeDependencies

	// Native dependencies whose compile_multilib is "32"
	Lib32 ApexNativeDependencies

	// Native dependencies whose compile_multilib is "64"
	Lib64 ApexNativeDependencies
}

type apexTargetBundleProperties struct {
	Target struct {
		// Multilib properties only for android.
		Android struct {
			Multilib apexMultilibProperties
		}

		// Multilib properties only for host.
		Host struct {
			Multilib apexMultilibProperties
		}

		// Multilib properties only for host linux_bionic.
		Linux_bionic struct {
			Multilib apexMultilibProperties
		}

		// Multilib properties only for host linux_glibc.
		Linux_glibc struct {
			Multilib apexMultilibProperties
		}
	}
}

type apexArchBundleProperties struct {
	Arch struct {
		Arm struct {
			ApexNativeDependencies
		}
		Arm64 struct {
			ApexNativeDependencies
		}
		Riscv64 struct {
			ApexNativeDependencies
		}
		X86 struct {
			ApexNativeDependencies
		}
		X86_64 struct {
			ApexNativeDependencies
		}
	}
}

// These properties can be used in override_apex to override the corresponding properties in the
// base apex.
type overridableProperties struct {
	// List of APKs that are embedded inside this APEX.
	Apps []string

	// List of prebuilt files that are embedded inside this APEX bundle.
	Prebuilts []string

	// List of BPF programs inside this APEX bundle.
	Bpfs []string

	// Names of modules to be overridden. Listed modules can only be other binaries (in Make or
	// Soong). This does not completely prevent installation of the overridden binaries, but if
	// both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
	// be removed from PRODUCT_PACKAGES.
	Overrides []string

	// Logging parent value.
	Logging_parent string

	// Apex Container package name. Override value for attribute package:name in
	// AndroidManifest.xml
	Package_name string

	// A txt file containing list of files that are allowed to be included in this APEX.
	Allowed_files *string `android:"path"`

	// Name of the apex_key module that provides the private key to sign this APEX bundle.
	Key *string

	// Specifies the certificate and the private key to sign the zip container of this APEX. If
	// this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
	// as the certificate and the private key, respectively. If this is ":module", then the
	// certificate and the private key are provided from the android_app_certificate module
	// named "module".
	Certificate *string

	// Whether this APEX can be compressed or not. Setting this property to false means this
	// APEX will never be compressed. When set to true, APEX will be compressed if other
	// conditions, e.g., target device needs to support APEX compression, are also fulfilled.
	// Default: false.
	Compressible *bool

	// Trim against a specific Dynamic Common Lib APEX
	Trim_against *string
}

type apexBundle struct {
	// Inherited structs
	android.ModuleBase
	android.DefaultableModuleBase
	android.OverridableModuleBase
	multitree.ExportableModuleBase

	// Properties
	properties            apexBundleProperties
	targetProperties      apexTargetBundleProperties
	archProperties        apexArchBundleProperties
	overridableProperties overridableProperties
	vndkProperties        apexVndkProperties // only for apex_vndk modules

	///////////////////////////////////////////////////////////////////////////////////////////
	// Inputs

	// Keys for apex_payload.img
	publicKeyFile  android.Path
	privateKeyFile android.Path

	// Cert/priv-key for the zip container
	containerCertificateFile android.Path
	containerPrivateKeyFile  android.Path

	// Flags for special variants of APEX
	testApex bool
	vndkApex bool

	// File system type of apex_payload.img
	payloadFsType fsType

	// Whether to create symlink to the system file instead of having a file inside the apex or
	// not
	linkToSystemLib bool

	// List of files to be included in this APEX. This is filled in the first part of
	// GenerateAndroidBuildActions.
	filesInfo []apexFile

	// List of other module names that should be installed when this APEX gets installed (LOCAL_REQUIRED_MODULES).
	makeModulesToInstall []string

	///////////////////////////////////////////////////////////////////////////////////////////
	// Outputs (final and intermediates)

	// Processed apex manifest in JSONson format (for Q)
	manifestJsonOut android.WritablePath

	// Processed apex manifest in PB format (for R+)
	manifestPbOut android.WritablePath

	// Processed file_contexts files
	fileContexts android.WritablePath

	// The built APEX file. This is the main product.
	// Could be .apex or .capex
	outputFile android.WritablePath

	// The built uncompressed .apex file.
	outputApexFile android.WritablePath

	// The built APEX file in app bundle format. This file is not directly installed to the
	// device. For an APEX, multiple app bundles are created each of which is for a specific ABI
	// like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
	// system) to be merged into a single app bundle file that Play accepts. See
	// vendor/google/build/build_unbundled_mainline_module.sh for more detail.
	bundleModuleFile android.WritablePath

	// Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
	installDir android.InstallPath

	// Path where this APEX was installed.
	installedFile android.InstallPath

	// fragment for this apex for apexkeys.txt
	apexKeysPath android.WritablePath

	// Installed locations of symlinks for backward compatibility.
	compatSymlinks android.InstallPaths

	// Text file having the list of individual files that are included in this APEX. Used for
	// debugging purpose.
	installedFilesFile android.WritablePath

	// List of module names that this APEX is including (to be shown via *-deps-info target).
	// Used for debugging purpose.
	android.ApexBundleDepsInfo

	// Optional list of lint report zip files for apexes that contain java or app modules
	lintReports android.Paths

	isCompressed bool

	// Path of API coverage generate file
	nativeApisUsedByModuleFile   android.ModuleOutPath
	nativeApisBackedByModuleFile android.ModuleOutPath
	javaApisUsedByModuleFile     android.ModuleOutPath

	aconfigFiles []android.Path

	// Single aconfig "cache file" merged from this module and all dependencies.
	mergedAconfigFiles map[string]android.Paths
}

// apexFileClass represents a type of file that can be included in APEX.
type apexFileClass int

const (
	app apexFileClass = iota
	appSet
	etc
	javaSharedLib
	nativeExecutable
	nativeSharedLib
	nativeTest
	shBinary
)

var (
	classes = map[string]apexFileClass{
		"app":              app,
		"appSet":           appSet,
		"etc":              etc,
		"javaSharedLib":    javaSharedLib,
		"nativeExecutable": nativeExecutable,
		"nativeSharedLib":  nativeSharedLib,
		"nativeTest":       nativeTest,
		"shBinary":         shBinary,
	}
)

// apexFile represents a file in an APEX bundle. This is created during the first half of
// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
// of the function, this is used to create commands that copies the files into a staging directory,
// where they are packaged into the APEX file.
type apexFile struct {
	// buildFile is put in the installDir inside the APEX.
	builtFile  android.Path
	installDir string
	partition  string
	customStem string
	symlinks   []string // additional symlinks

	// Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
	// module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
	// suffix>]
	androidMkModuleName       string             // becomes LOCAL_MODULE
	class                     apexFileClass      // becomes LOCAL_MODULE_CLASS
	moduleDir                 string             // becomes LOCAL_PATH
	requiredModuleNames       []string           // becomes LOCAL_REQUIRED_MODULES
	targetRequiredModuleNames []string           // becomes LOCAL_TARGET_REQUIRED_MODULES
	hostRequiredModuleNames   []string           // becomes LOCAL_HOST_REQUIRED_MODULES
	dataPaths                 []android.DataPath // becomes LOCAL_TEST_DATA

	jacocoReportClassesFile android.Path     // only for javalibs and apps
	lintDepSets             java.LintDepSets // only for javalibs and apps
	certificate             java.Certificate // only for apps
	overriddenPackageName   string           // only for apps

	transitiveDep bool
	isJniLib      bool

	multilib string

	// TODO(jiyong): remove this
	module android.Module
}

// TODO(jiyong): shorten the arglist using an option struct
func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
	ret := apexFile{
		builtFile:           builtFile,
		installDir:          installDir,
		androidMkModuleName: androidMkModuleName,
		class:               class,
		module:              module,
	}
	if module != nil {
		ret.moduleDir = ctx.OtherModuleDir(module)
		ret.partition = module.PartitionTag(ctx.DeviceConfig())
		ret.requiredModuleNames = module.RequiredModuleNames()
		ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
		ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
		ret.multilib = module.Target().Arch.ArchType.Multilib
	}
	return ret
}

func (af *apexFile) ok() bool {
	return af.builtFile != nil && af.builtFile.String() != ""
}

// apexRelativePath returns the relative path of the given path from the install directory of this
// apexFile.
// TODO(jiyong): rename this
func (af *apexFile) apexRelativePath(path string) string {
	return filepath.Join(af.installDir, path)
}

// path returns path of this apex file relative to the APEX root
func (af *apexFile) path() string {
	return af.apexRelativePath(af.stem())
}

// stem returns the base filename of this apex file
func (af *apexFile) stem() string {
	if af.customStem != "" {
		return af.customStem
	}
	return af.builtFile.Base()
}

// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
func (af *apexFile) symlinkPaths() []string {
	var ret []string
	for _, symlink := range af.symlinks {
		ret = append(ret, af.apexRelativePath(symlink))
	}
	return ret
}

// availableToPlatform tests whether this apexFile is from a module that can be installed to the
// platform.
func (af *apexFile) availableToPlatform() bool {
	if af.module == nil {
		return false
	}
	if am, ok := af.module.(android.ApexModule); ok {
		return am.AvailableFor(android.AvailableToPlatform)
	}
	return false
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mutators
//
// Brief description about mutators for APEX. The following three mutators are the most important
// ones.
//
// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
// to the (direct) dependencies of this APEX bundle.
//
// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
// modules are marked as being included in the APEX via BuildForApex().
//
// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name string

	// Determines if the dependent will be part of the APEX payload. Can be false for the
	// dependencies to the signing key module, etc.
	payload bool

	// True if the dependent can only be a source module, false if a prebuilt module is a suitable
	// replacement. This is needed because some prebuilt modules do not provide all the information
	// needed by the apex.
	sourceOnly bool

	// If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
	// also be added as exported members of that SDK.
	memberType android.SdkMemberType
}

func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
	return d.memberType
}

func (d *dependencyTag) ExportMember() bool {
	return true
}

func (d *dependencyTag) String() string {
	return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
}

func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
	return !d.sourceOnly
}

var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
var _ android.SdkMemberDependencyTag = &dependencyTag{}

var (
	androidAppTag   = &dependencyTag{name: "androidApp", payload: true}
	bpfTag          = &dependencyTag{name: "bpf", payload: true}
	certificateTag  = &dependencyTag{name: "certificate"}
	dclaTag         = &dependencyTag{name: "dcla"}
	executableTag   = &dependencyTag{name: "executable", payload: true}
	fsTag           = &dependencyTag{name: "filesystem", payload: true}
	bcpfTag         = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
	sscpfTag        = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
	compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
	javaLibTag      = &dependencyTag{name: "javaLib", payload: true}
	jniLibTag       = &dependencyTag{name: "jniLib", payload: true}
	keyTag          = &dependencyTag{name: "key"}
	prebuiltTag     = &dependencyTag{name: "prebuilt", payload: true}
	rroTag          = &dependencyTag{name: "rro", payload: true}
	sharedLibTag    = &dependencyTag{name: "sharedLib", payload: true}
	testForTag      = &dependencyTag{name: "test for"}
	testTag         = &dependencyTag{name: "test", payload: true}
	shBinaryTag     = &dependencyTag{name: "shBinary", payload: true}
)

// TODO(jiyong): shorten this function signature
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
	binVariations := target.Variations()
	libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
	rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})

	// Append "image" variation
	binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
	libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
	rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})

	// Use *FarVariation* to be able to depend on modules having conflicting variations with
	// this module. This is required since arch variant of an APEX bundle is 'common' but it is
	// 'arm' or 'arm64' for native shared libs.
	ctx.AddFarVariationDependencies(binVariations, executableTag,
		android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
	ctx.AddFarVariationDependencies(binVariations, testTag,
		android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
	ctx.AddFarVariationDependencies(libVariations, jniLibTag,
		android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
	ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
		android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
	ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
		android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
	ctx.AddFarVariationDependencies(target.Variations(), fsTag,
		android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
	ctx.AddFarVariationDependencies(target.Variations(), prebuiltTag,
		android.RemoveListFromList(nativeModules.Prebuilts, nativeModules.Exclude_prebuilts)...)
}

func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
	proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
}

// getImageVariationPair returns a pair for the image variation name as its
// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
// suffix indicates the vndk version for vendor/product if vndk is enabled.
// getImageVariation can simply join the result of this function to get the
// image variation name.
func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
	if a.vndkApex {
		return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
	}

	prefix := android.CoreVariation
	vndkVersion := ""
	if deviceConfig.VndkVersion() != "" {
		if a.SocSpecific() || a.DeviceSpecific() {
			prefix = cc.VendorVariationPrefix
			vndkVersion = deviceConfig.VndkVersion()
		} else if a.ProductSpecific() {
			prefix = cc.ProductVariationPrefix
			vndkVersion = deviceConfig.PlatformVndkVersion()
		}
	} else {
		if a.SocSpecific() || a.DeviceSpecific() {
			prefix = cc.VendorVariation
		} else if a.ProductSpecific() {
			prefix = cc.ProductVariation
		}
	}
	if vndkVersion == "current" {
		vndkVersion = deviceConfig.PlatformVndkVersion()
	}

	return prefix, vndkVersion
}

// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
	prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
	return prefix + vndkVersion
}

func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
	// apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
	// arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
	// each target os/architectures, appropriate dependencies are selected by their
	// target.<os>.multilib.<type> groups and are added as (direct) dependencies.
	targets := ctx.MultiTargets()
	imageVariation := a.getImageVariation(ctx)

	a.combineProperties(ctx)

	has32BitTarget := false
	for _, target := range targets {
		if target.Arch.ArchType.Multilib == "lib32" {
			has32BitTarget = true
		}
	}
	for i, target := range targets {
		var deps ApexNativeDependencies

		// Add native modules targeting both ABIs. When multilib.* is omitted for
		// native_shared_libs/jni_libs/tests, it implies multilib.both
		deps.Merge(a.properties.Multilib.Both)
		deps.Merge(ApexNativeDependencies{
			Native_shared_libs: a.properties.Native_shared_libs,
			Tests:              a.properties.Tests,
			Jni_libs:           a.properties.Jni_libs,
			Binaries:           nil,
		})

		// Add native modules targeting the first ABI When multilib.* is omitted for
		// binaries, it implies multilib.first
		isPrimaryAbi := i == 0
		if isPrimaryAbi {
			deps.Merge(a.properties.Multilib.First)
			deps.Merge(ApexNativeDependencies{
				Native_shared_libs: nil,
				Tests:              nil,
				Jni_libs:           nil,
				Binaries:           a.properties.Binaries,
			})
		}

		// Add native modules targeting either 32-bit or 64-bit ABI
		switch target.Arch.ArchType.Multilib {
		case "lib32":
			deps.Merge(a.properties.Multilib.Lib32)
			deps.Merge(a.properties.Multilib.Prefer32)
		case "lib64":
			deps.Merge(a.properties.Multilib.Lib64)
			if !has32BitTarget {
				deps.Merge(a.properties.Multilib.Prefer32)
			}
		}

		// Add native modules targeting a specific arch variant
		switch target.Arch.ArchType {
		case android.Arm:
			deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
		case android.Arm64:
			deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
		case android.Riscv64:
			deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
		case android.X86:
			deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
		case android.X86_64:
			deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
		default:
			panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
		}

		addDependenciesForNativeModules(ctx, deps, target, imageVariation)
		if isPrimaryAbi {
			ctx.AddFarVariationDependencies([]blueprint.Variation{
				{Mutator: "os", Variation: target.OsVariation()},
				{Mutator: "arch", Variation: target.ArchVariation()},
			}, shBinaryTag, a.properties.Sh_binaries...)
		}
	}

	// Common-arch dependencies come next
	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
	ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...)
	ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
	ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments...)
	ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
	ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
	ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
}

// DepsMutator for the overridden properties.
func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
	if a.overridableProperties.Allowed_files != nil {
		android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
	}

	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
	ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
	ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
	if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
		// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
		// regardless of the TARGET_PREFER_* setting. See b/144532908
		arches := ctx.DeviceConfig().Arches()
		if len(arches) != 0 {
			archForPrebuiltEtc := arches[0]
			for _, arch := range arches {
				// Prefer 64-bit arch if there is any
				if arch.ArchType.Multilib == "lib64" {
					archForPrebuiltEtc = arch
					break
				}
			}
			ctx.AddFarVariationDependencies([]blueprint.Variation{
				{Mutator: "os", Variation: ctx.Os().String()},
				{Mutator: "arch", Variation: archForPrebuiltEtc.String()},
			}, prebuiltTag, prebuilts...)
		}
	}

	// Dependencies for signing
	if String(a.overridableProperties.Key) == "" {
		ctx.PropertyErrorf("key", "missing")
		return
	}
	ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))

	cert := android.SrcIsModule(a.getCertString(ctx))
	if cert != "" {
		ctx.AddDependency(ctx.Module(), certificateTag, cert)
		// empty cert is not an error. Cert and private keys will be directly found under
		// PRODUCT_DEFAULT_DEV_CERTIFICATE
	}
}

func apexDCLADepsMutator(mctx android.BottomUpMutatorContext) {
	if !mctx.Config().ApexTrimEnabled() {
		return
	}
	if a, ok := mctx.Module().(*apexBundle); ok && a.overridableProperties.Trim_against != nil {
		commonVariation := mctx.Config().AndroidCommonTarget.Variations()
		mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(a.overridableProperties.Trim_against))
	} else if o, ok := mctx.Module().(*OverrideApex); ok {
		for _, p := range o.GetProperties() {
			properties, ok := p.(*overridableProperties)
			if !ok {
				continue
			}
			if properties.Trim_against != nil {
				commonVariation := mctx.Config().AndroidCommonTarget.Variations()
				mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(properties.Trim_against))
			}
		}
	}
}

type DCLAInfo struct {
	ProvidedLibs []string
}

var DCLAInfoProvider = blueprint.NewMutatorProvider[DCLAInfo]("apex_info")

var _ ApexInfoMutator = (*apexBundle)(nil)

func (a *apexBundle) ApexVariationName() string {
	return a.properties.ApexVariationName
}

// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
//
// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
// The apexMutator uses that list to create module variants for the apexes to which it belongs.
// The relationship between module variants and apexes is not one-to-one as variants will be
// shared between compatible apexes.
func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {

	// The VNDK APEX is special. For the APEX, the membership is described in a very different
	// way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
	// libraries are self-identified by their vndk.enabled properties. There is no need to run
	// this mutator for the APEX as nothing will be collected. So, let's return fast.
	if a.vndkApex {
		return
	}

	// Special casing for APEXes on non-system (e.g., vendor, odm, etc.) partitions. They are
	// provided with a property named use_vndk_as_stable, which when set to true doesn't collect
	// VNDK libraries as transitive dependencies. This option is useful for reducing the size of
	// the non-system APEXes because the VNDK libraries won't be included (and duped) in the
	// APEX, but shared across APEXes via the VNDK APEX.
	useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
	excludeVndkLibs := useVndk && a.useVndkAsStable(mctx)
	if proptools.Bool(a.properties.Use_vndk_as_stable) {
		if !useVndk {
			mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
		}
		if a.minSdkVersionValue(mctx) != "" {
			mctx.PropertyErrorf("use_vndk_as_stable", "not supported when min_sdk_version is set")
		}
		mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
			if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
				mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
			}
		})
		if mctx.Failed() {
			return
		}
	}

	continueApexDepsWalk := func(child, parent android.Module) bool {
		am, ok := child.(android.ApexModule)
		if !ok || !am.CanHaveApexVariants() {
			return false
		}
		depTag := mctx.OtherModuleDependencyTag(child)

		// Check to see if the tag always requires that the child module has an apex variant for every
		// apex variant of the parent module. If it does not then it is still possible for something
		// else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
		if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
			return true
		}
		if !android.IsDepInSameApex(mctx, parent, child) {
			return false
		}
		if excludeVndkLibs {
			if c, ok := child.(*cc.Module); ok && c.IsVndk() {
				return false
			}
		}

		//TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated.
		if useVndk && mctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" {
			log.Print("Libbinder is linked from Vendor APEX ", a.Name(), " with module ", parent.Name())
			return false
		}

		// By default, all the transitive dependencies are collected, unless filtered out
		// above.
		return true
	}

	// Records whether a certain module is included in this apexBundle via direct dependency or
	// inndirect dependency.
	contents := make(map[string]android.ApexMembership)
	mctx.WalkDeps(func(child, parent android.Module) bool {
		if !continueApexDepsWalk(child, parent) {
			return false
		}
		// If the parent is apexBundle, this child is directly depended.
		_, directDep := parent.(*apexBundle)
		depName := mctx.OtherModuleName(child)
		contents[depName] = contents[depName].Add(directDep)
		return true
	})

	// The membership information is saved for later access
	apexContents := android.NewApexContents(contents)
	android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{
		Contents: apexContents,
	})

	minSdkVersion := a.minSdkVersion(mctx)
	// When min_sdk_version is not set, the apex is built against FutureApiLevel.
	if minSdkVersion.IsNone() {
		minSdkVersion = android.FutureApiLevel
	}

	// This is the main part of this mutator. Mark the collected dependencies that they need to
	// be built for this apexBundle.

	apexVariationName := mctx.ModuleName() // could be com.android.foo
	a.properties.ApexVariationName = apexVariationName
	testApexes := []string{}
	if a.testApex {
		testApexes = []string{apexVariationName}
	}
	apexInfo := android.ApexInfo{
		ApexVariationName: apexVariationName,
		MinSdkVersion:     minSdkVersion,
		Updatable:         a.Updatable(),
		UsePlatformApis:   a.UsePlatformApis(),
		InApexVariants:    []string{apexVariationName},
		InApexModules:     []string{a.Name()}, // could be com.mycompany.android.foo
		ApexContents:      []*android.ApexContents{apexContents},
		TestApexes:        testApexes,
	}
	mctx.WalkDeps(func(child, parent android.Module) bool {
		if !continueApexDepsWalk(child, parent) {
			return false
		}
		child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
		return true
	})

	if a.dynamic_common_lib_apex() {
		android.SetProvider(mctx, DCLAInfoProvider, DCLAInfo{
			ProvidedLibs: a.properties.Native_shared_libs,
		})
	}
}

type ApexInfoMutator interface {
	// ApexVariationName returns the name of the APEX variation to use in the apex
	// mutator etc. It is the same name as ApexInfo.ApexVariationName.
	ApexVariationName() string

	// ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
	// depended upon by an apex and which require an apex specific variant.
	ApexInfoMutator(android.TopDownMutatorContext)
}

// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
// specific variant to modules that support the ApexInfoMutator.
// It also propagates updatable=true to apps of updatable apexes
func apexInfoMutator(mctx android.TopDownMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}

	if a, ok := mctx.Module().(ApexInfoMutator); ok {
		a.ApexInfoMutator(mctx)
	}
	enforceAppUpdatability(mctx)
}

// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
// This check is enforced for updatable modules
func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}
	if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting() {
		mctx.WalkDeps(func(child, parent android.Module) bool {
			// b/208656169 Do not propagate strict updatability linting to libcore/
			// These libs are available on the classpath during compilation
			// These libs are transitive deps of the sdk. See java/sdk.go:decodeSdkDep
			// Only skip libraries defined in libcore root, not subdirectories
			if mctx.OtherModuleDir(child) == "libcore" {
				// Do not traverse transitive deps of libcore/ libs
				return false
			}
			if android.InList(child.Name(), skipLintJavalibAllowlist) {
				return false
			}
			if lintable, ok := child.(java.LintDepSetsIntf); ok {
				lintable.SetStrictUpdatabilityLinting(true)
			}
			// visit transitive deps
			return true
		})
	}
}

// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
func enforceAppUpdatability(mctx android.TopDownMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}
	if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
		// checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
		mctx.VisitDirectDeps(func(module android.Module) {
			// ignore android_test_app
			if app, ok := module.(*java.AndroidApp); ok {
				app.SetUpdatable(true)
			}
		})
	}
}

// TODO: b/215736885 Whittle the denylist
// Transitive deps of certain mainline modules baseline NewApi errors
// Skip these mainline modules for now
var (
	skipStrictUpdatabilityLintAllowlist = []string{
		// go/keep-sorted start
		"PackageManagerTestApex",
		"com.android.adservices",
		"com.android.appsearch",
		"com.android.art",
		"com.android.art.debug",
		"com.android.btservices",
		"com.android.cellbroadcast",
		"com.android.configinfrastructure",
		"com.android.conscrypt",
		"com.android.extservices",
		"com.android.extservices_tplus",
		"com.android.healthfitness",
		"com.android.ipsec",
		"com.android.media",
		"com.android.mediaprovider",
		"com.android.ondevicepersonalization",
		"com.android.os.statsd",
		"com.android.permission",
		"com.android.profiling",
		"com.android.rkpd",
		"com.android.scheduling",
		"com.android.tethering",
		"com.android.uwb",
		"com.android.wifi",
		"test_com.android.art",
		"test_com.android.cellbroadcast",
		"test_com.android.conscrypt",
		"test_com.android.extservices",
		"test_com.android.ipsec",
		"test_com.android.media",
		"test_com.android.mediaprovider",
		"test_com.android.os.statsd",
		"test_com.android.permission",
		"test_com.android.wifi",
		"test_jitzygote_com.android.art",
		// go/keep-sorted end
	}

	// TODO: b/215736885 Remove this list
	skipLintJavalibAllowlist = []string{
		"conscrypt.module.platform.api.stubs",
		"conscrypt.module.public.api.stubs",
		"conscrypt.module.public.api.stubs.system",
		"conscrypt.module.public.api.stubs.module_lib",
		"framework-media.stubs",
		"framework-media.stubs.system",
		"framework-media.stubs.module_lib",
	}
)

func (a *apexBundle) checkStrictUpdatabilityLinting() bool {
	return a.Updatable() && !android.InList(a.ApexVariationName(), skipStrictUpdatabilityLintAllowlist)
}

// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
// unique apex variations for this module. See android/apex.go for more about unique apex variant.
// TODO(jiyong): move this to android/apex.go?
func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}
	if am, ok := mctx.Module().(android.ApexModule); ok {
		android.UpdateUniqueApexVariationsForDeps(mctx, am)
	}
}

// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on
// the apex in order to retrieve its contents later.
// TODO(jiyong): move this to android/apex.go?
func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}
	if am, ok := mctx.Module().(android.ApexModule); ok {
		if testFor := am.TestFor(); len(testFor) > 0 {
			mctx.AddFarVariationDependencies([]blueprint.Variation{
				{Mutator: "os", Variation: am.Target().OsVariation()},
				{"arch", "common"},
			}, testForTag, testFor...)
		}
	}
}

// TODO(jiyong): move this to android/apex.go?
func apexTestForMutator(mctx android.BottomUpMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}
	if _, ok := mctx.Module().(android.ApexModule); ok {
		var contents []*android.ApexContents
		for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) {
			abInfo, _ := android.OtherModuleProvider(mctx, testFor, android.ApexBundleInfoProvider)
			contents = append(contents, abInfo.Contents)
		}
		android.SetProvider(mctx, android.ApexTestForInfoProvider, android.ApexTestForInfo{
			ApexContents: contents,
		})
	}
}

// markPlatformAvailability marks whether or not a module can be available to platform. A module
// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
// be) available to platform
// TODO(jiyong): move this to android/apex.go?
func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
	// Recovery is not considered as platform
	if mctx.Module().InstallInRecovery() {
		return
	}

	am, ok := mctx.Module().(android.ApexModule)
	if !ok {
		return
	}

	availableToPlatform := am.AvailableFor(android.AvailableToPlatform)

	// If any of the dep is not available to platform, this module is also considered as being
	// not available to platform even if it has "//apex_available:platform"
	mctx.VisitDirectDeps(func(child android.Module) {
		if !android.IsDepInSameApex(mctx, am, child) {
			// if the dependency crosses apex boundary, don't consider it
			return
		}
		if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
			availableToPlatform = false
			// TODO(b/154889534) trigger an error when 'am' has
			// "//apex_available:platform"
		}
	})

	// Exception 1: check to see if the module always requires it.
	if am.AlwaysRequiresPlatformApexVariant() {
		availableToPlatform = true
	}

	// Exception 2: bootstrap bionic libraries are also always available to platform
	if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
		availableToPlatform = true
	}

	if !availableToPlatform {
		am.SetNotAvailableForPlatform()
	}
}

// apexMutator visits each module and creates apex variations if the module was marked in the
// previous run of apexInfoMutator.
func apexMutator(mctx android.BottomUpMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}

	// This is the usual path.
	if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
		android.CreateApexVariations(mctx, am)
		return
	}

	// apexBundle itself is mutated so that it and its dependencies have the same apex variant.
	if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
		apexBundleName := ai.ApexVariationName()
		mctx.CreateVariations(apexBundleName)
		if strings.HasPrefix(apexBundleName, "com.android.art") {
			// Create an alias from the platform variant. This is done to make
			// test_for dependencies work for modules that are split by the APEX
			// mutator, since test_for dependencies always go to the platform variant.
			// This doesn't happen for normal APEXes that are disjunct, so only do
			// this for the overlapping ART APEXes.
			// TODO(b/183882457): Remove this if the test_for functionality is
			// refactored to depend on the proper APEX variants instead of platform.
			mctx.CreateAliasVariation("", apexBundleName)
		}
	} else if o, ok := mctx.Module().(*OverrideApex); ok {
		apexBundleName := o.GetOverriddenModuleName()
		if apexBundleName == "" {
			mctx.ModuleErrorf("base property is not set")
			return
		}
		mctx.CreateVariations(apexBundleName)
		if strings.HasPrefix(apexBundleName, "com.android.art") {
			// TODO(b/183882457): See note for CreateAliasVariation above.
			mctx.CreateAliasVariation("", apexBundleName)
		}
	}
}

// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
// variant.
func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
	if a, ok := module.(*apexBundle); ok {
		// TODO(jiyong): document the reason why the VNDK APEX is an exception here.
		return !a.vndkApex
	}

	return true
}

// See android.UpdateDirectlyInAnyApex
// TODO(jiyong): move this to android/apex.go?
func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
	if !mctx.Module().Enabled() {
		return
	}
	if am, ok := mctx.Module().(android.ApexModule); ok {
		android.UpdateDirectlyInAnyApex(mctx, am)
	}
}

const (
	// File extensions of an APEX for different packaging methods
	imageApexSuffix  = ".apex"
	imageCapexSuffix = ".capex"

	// variant names each of which is for a packaging method
	imageApexType = "image"

	ext4FsType  = "ext4"
	f2fsFsType  = "f2fs"
	erofsFsType = "erofs"
)

var _ android.DepIsInSameApex = (*apexBundle)(nil)

// Implements android.DepInInSameApex
func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
	// direct deps of an APEX bundle are all part of the APEX bundle
	// TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
	return true
}

var _ android.OutputFileProducer = (*apexBundle)(nil)

// Implements android.OutputFileProducer
func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
	switch tag {
	case "", android.DefaultDistTag:
		// This is the default dist path.
		return android.Paths{a.outputFile}, nil
	case imageApexSuffix:
		// uncompressed one
		if a.outputApexFile != nil {
			return android.Paths{a.outputApexFile}, nil
		}
		fallthrough
	default:
		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
	}
}

var _ multitree.Exportable = (*apexBundle)(nil)

func (a *apexBundle) Exportable() bool {
	return true
}

func (a *apexBundle) TaggedOutputs() map[string]android.Paths {
	ret := make(map[string]android.Paths)
	ret["apex"] = android.Paths{a.outputFile}
	return ret
}

var _ cc.Coverage = (*apexBundle)(nil)

// Implements cc.Coverage
func (a *apexBundle) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
	return ctx.DeviceConfig().NativeCoverageEnabled()
}

// Implements cc.Coverage
func (a *apexBundle) SetPreventInstall() {
	a.properties.PreventInstall = true
}

// Implements cc.Coverage
func (a *apexBundle) HideFromMake() {
	a.properties.HideFromMake = true
	// This HideFromMake is shadowing the ModuleBase one, call through to it for now.
	// TODO(ccross): untangle these
	a.ModuleBase.HideFromMake()
}

// Implements cc.Coverage
func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
	a.properties.IsCoverageVariant = coverage
}

// Implements cc.Coverage
func (a *apexBundle) EnableCoverageIfNeeded() {}

var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)

// Implements android.ApexBundleDepsInfoIntf
func (a *apexBundle) Updatable() bool {
	return proptools.BoolDefault(a.properties.Updatable, true)
}

func (a *apexBundle) FutureUpdatable() bool {
	return proptools.BoolDefault(a.properties.Future_updatable, false)
}

func (a *apexBundle) UsePlatformApis() bool {
	return proptools.BoolDefault(a.properties.Platform_apis, false)
}

// getCertString returns the name of the cert that should be used to sign this APEX. This is
// basically from the "certificate" property, but could be overridden by the device config.
func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
	moduleName := ctx.ModuleName()
	// VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
	// OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
	// overridden.
	if a.vndkApex {
		moduleName = vndkApexName
	}
	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
	if overridden {
		return ":" + certificate
	}
	return String(a.overridableProperties.Certificate)
}

// See the installable property
func (a *apexBundle) installable() bool {
	return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
}

// See the generate_hashtree property
func (a *apexBundle) shouldGenerateHashtree() bool {
	return proptools.BoolDefault(a.properties.Generate_hashtree, true)
}

// See the test_only_unsigned_payload property
func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
	return proptools.Bool(a.properties.Test_only_unsigned_payload)
}

// See the test_only_force_compression property
func (a *apexBundle) testOnlyShouldForceCompression() bool {
	return proptools.Bool(a.properties.Test_only_force_compression)
}

// See the dynamic_common_lib_apex property
func (a *apexBundle) dynamic_common_lib_apex() bool {
	return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
}

// See the list of libs to trim
func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string {
	dclaModules := ctx.GetDirectDepsWithTag(dclaTag)
	if len(dclaModules) > 1 {
		panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules)))
	}
	if len(dclaModules) > 0 {
		DCLAInfo, _ := android.OtherModuleProvider(ctx, dclaModules[0], DCLAInfoProvider)
		return DCLAInfo.ProvidedLibs
	}
	return []string{}
}

// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
// members) can be sanitized, either forcibly, or by the global configuration. For some of the
// sanitizers, extra dependencies can be forcibly added as well.

func (a *apexBundle) EnableSanitizer(sanitizerName string) {
	if !android.InList(sanitizerName, a.properties.SanitizerNames) {
		a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
	}
}

func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
	if android.InList(sanitizerName, a.properties.SanitizerNames) {
		return true
	}

	// Then follow the global setting
	var globalSanitizerNames []string
	arches := config.SanitizeDeviceArch()
	if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
		globalSanitizerNames = config.SanitizeDevice()
	}
	return android.InList(sanitizerName, globalSanitizerNames)
}

func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
	// TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
	// Keep only the mechanism here.
	if sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
		imageVariation := a.getImageVariation(ctx)
		for _, target := range ctx.MultiTargets() {
			if target.Arch.ArchType.Multilib == "lib64" {
				addDependenciesForNativeModules(ctx, ApexNativeDependencies{
					Native_shared_libs: []string{"libclang_rt.hwasan"},
					Tests:              nil,
					Jni_libs:           nil,
					Binaries:           nil,
				}, target, imageVariation)
				break
			}
		}
	}
}

// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
// returned apexFile saves information about the Soong module that will be used for creating the
// build rules.
func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
	// Decide the APEX-local directory by the multilib of the library In the future, we may
	// query this to the module.
	// TODO(jiyong): use the new PackagingSpec
	var dirInApex string
	switch ccMod.Arch().ArchType.Multilib {
	case "lib32":
		dirInApex = "lib"
	case "lib64":
		dirInApex = "lib64"
	}
	if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
		dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
	}
	if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
		// Special case for Bionic libs and other libs installed with them. This is to
		// prevent those libs from being included in the search path
		// /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
		// in the Runtime APEX are available via the legacy paths in /system/lib/. By the
		// init process, the libs in the APEX are bind-mounted to the legacy paths and thus
		// will be loaded into the default linker namespace (aka "platform" namespace). If
		// the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
		// be loaded again into the runtime linker namespace, which will result in double
		// loading of them, which isn't supported.
		dirInApex = filepath.Join(dirInApex, "bionic")
	}
	// This needs to go after the runtime APEX handling because otherwise we would get
	// weird paths like lib64/rel_install_path/bionic rather than
	// lib64/bionic/rel_install_path.
	dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())

	fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
	androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
}

func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
	dirInApex := "bin"
	if cc.Target().NativeBridge == android.NativeBridgeEnabled {
		dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
	}
	dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
	fileToCopy := android.OutputFileForModule(ctx, cc, "")
	androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
	af.symlinks = cc.Symlinks()
	af.dataPaths = cc.DataPaths()
	return af
}

func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
	dirInApex := "bin"
	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
	}
	dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
	fileToCopy := android.OutputFileForModule(ctx, rustm, "")
	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
	return af
}

func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
	// Decide the APEX-local directory by the multilib of the library
	// In the future, we may query this to the module.
	var dirInApex string
	switch rustm.Arch().ArchType.Multilib {
	case "lib32":
		dirInApex = "lib"
	case "lib64":
		dirInApex = "lib64"
	}
	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
	}
	dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
	fileToCopy := android.OutputFileForModule(ctx, rustm, "")
	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
}

func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
	dirInApex := filepath.Join("bin", sh.SubDir())
	if sh.Target().NativeBridge == android.NativeBridgeEnabled {
		dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
	}
	fileToCopy := sh.OutputFile()
	af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
	af.symlinks = sh.Symlinks()
	return af
}

func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
	dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
	fileToCopy := prebuilt.OutputFile()
	return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
}

func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
	dirInApex := filepath.Join("etc", config.SubDir())
	fileToCopy := config.CompatConfig()
	return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
}

// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
// way.
type javaModule interface {
	android.Module
	BaseModuleName() string
	DexJarBuildPath(ctx android.ModuleErrorfContext) java.OptionalDexJarPath
	JacocoReportClassesFile() android.Path
	LintDepSets() java.LintDepSets
	Stem() string
}

var _ javaModule = (*java.Library)(nil)
var _ javaModule = (*java.Import)(nil)
var _ javaModule = (*java.SdkLibrary)(nil)
var _ javaModule = (*java.DexImport)(nil)
var _ javaModule = (*java.SdkLibraryImport)(nil)

// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
	return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath(ctx).PathOrNil())
}

// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
	dirInApex := "javalib"
	af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
	af.jacocoReportClassesFile = module.JacocoReportClassesFile()
	af.lintDepSets = module.LintDepSets()
	af.customStem = module.Stem() + ".jar"
	if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
		for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
			af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
		}
	}
	return af
}

func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile {
	if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
		if profilePathOnHost := dexpreopter.OutputProfilePathOnHost(); profilePathOnHost != nil {
			dirInApex := "javalib"
			af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil)
			af.customStem = module.Stem() + ".jar.prof"
			return &af
		}
	}
	return nil
}

// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
// the same way.
type androidApp interface {
	android.Module
	Privileged() bool
	InstallApkName() string
	OutputFile() android.Path
	JacocoReportClassesFile() android.Path
	Certificate() java.Certificate
	BaseModuleName() string
	LintDepSets() java.LintDepSets
	PrivAppAllowlist() android.OptionalPath
}

var _ androidApp = (*java.AndroidApp)(nil)
var _ androidApp = (*java.AndroidAppImport)(nil)

func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
	buildId := ctx.Config().BuildId()

	// The build ID is used as a suffix for a filename, so ensure that
	// the set of characters being used are sanitized.
	// - any word character: [a-zA-Z0-9_]
	// - dots: .
	// - dashes: -
	validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
	if !validRegex.MatchString(buildId) {
		ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
	}
	return buildId
}

func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []apexFile {
	appDir := "app"
	if aapp.Privileged() {
		appDir = "priv-app"
	}

	// TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
	// so that PackageManager correctly invalidates the existing installed apk
	// in favour of the new APK-in-APEX.  See bugs for more information.
	dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
	fileToCopy := aapp.OutputFile()

	af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
	af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
	af.lintDepSets = aapp.LintDepSets()
	af.certificate = aapp.Certificate()

	if app, ok := aapp.(interface {
		OverriddenManifestPackageName() string
	}); ok {
		af.overriddenPackageName = app.OverriddenManifestPackageName()
	}

	apexFiles := []apexFile{}

	if allowlist := aapp.PrivAppAllowlist(); allowlist.Valid() {
		dirInApex := filepath.Join("etc", "permissions")
		privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"_privapp", dirInApex, etc, aapp)
		apexFiles = append(apexFiles, privAppAllowlist)
	}

	apexFiles = append(apexFiles, af)

	return apexFiles
}

func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
	rroDir := "overlay"
	dirInApex := filepath.Join(rroDir, rro.Theme())
	fileToCopy := rro.OutputFile()
	af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
	af.certificate = rro.Certificate()

	if a, ok := rro.(interface {
		OverriddenManifestPackageName() string
	}); ok {
		af.overriddenPackageName = a.OverriddenManifestPackageName()
	}
	return af
}

func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
	dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
	return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
}

func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
	dirInApex := filepath.Join("etc", "fs")
	return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
}

// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
// visited module, the `do` callback is executed. Returning true in the callback continues the visit
// to the child modules. Returning false makes the visit to continue in the sibling or the parent
// modules. This is used in check* functions below.
func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
	ctx.WalkDeps(func(child, parent android.Module) bool {
		am, ok := child.(android.ApexModule)
		if !ok || !am.CanHaveApexVariants() {
			return false
		}

		// Filter-out unwanted depedendencies
		depTag := ctx.OtherModuleDependencyTag(child)
		if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
			return false
		}
		if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
			return false
		}

		ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
		externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)

		// Visit actually
		return do(ctx, parent, am, externalDep)
	})
}

// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
type fsType int

const (
	ext4 fsType = iota
	f2fs
	erofs
)

func (f fsType) string() string {
	switch f {
	case ext4:
		return ext4FsType
	case f2fs:
		return f2fsFsType
	case erofs:
		return erofsFsType
	default:
		panic(fmt.Errorf("unknown APEX payload type %d", f))
	}
}

func (a *apexBundle) setCompression(ctx android.ModuleContext) {
	if a.testOnlyShouldForceCompression() {
		a.isCompressed = true
	} else {
		a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
	}
}

func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
	// Optimization. If we are building bundled APEX, for the files that are gathered due to the
	// transitive dependencies, don't place them inside the APEX, but place a symlink pointing
	// the same library in the system partition, thus effectively sharing the same libraries
	// across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
	// in the APEX.
	a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()

	// APEXes targeting other than system/system_ext partitions use vendor/product variants.
	// So we can't link them to /system/lib libs which are core variants.
	if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
		a.linkToSystemLib = false
	}

	forced := ctx.Config().ForceApexSymlinkOptimization()
	updatable := a.Updatable() || a.FutureUpdatable()

	// We don't need the optimization for updatable APEXes, as it might give false signal
	// to the system health when the APEXes are still bundled (b/149805758).
	if !forced && updatable {
		a.linkToSystemLib = false
	}
}

func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
	switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
	case ext4FsType:
		a.payloadFsType = ext4
	case f2fsFsType:
		a.payloadFsType = f2fs
	case erofsFsType:
		a.payloadFsType = erofs
	default:
		ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
	}
}

func (a *apexBundle) isCompressable() bool {
	return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
}

func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
	a.checkApexAvailability(ctx)
	a.checkUpdatable(ctx)
	a.CheckMinSdkVersion(ctx)
	a.checkStaticLinkingToStubLibraries(ctx)
	a.checkStaticExecutables(ctx)
	if len(a.properties.Tests) > 0 && !a.testApex {
		ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
		return false
	}
	return true
}

type visitorContext struct {
	// all the files that will be included in this APEX
	filesInfo []apexFile

	// native lib dependencies
	provideNativeLibs []string
	requireNativeLibs []string

	handleSpecialLibs bool

	// if true, raise error on duplicate apexFile
	checkDuplicate bool

	// visitor skips these from this list of module names
	unwantedTransitiveDeps []string

	aconfigFiles []android.Path
}

func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
	encountered := make(map[string]apexFile)
	for _, f := range vctx.filesInfo {
		// Skips unwanted transitive deps. This happens, for example, with Rust binaries with prefer_rlib:true.
		// TODO(b/295593640)
		// Needs additional verification for the resulting APEX to ensure that skipped artifacts don't make problems.
		// For example, DT_NEEDED modules should be found within the APEX unless they are marked in `requiredNativeLibs`.
		if f.transitiveDep && f.module != nil && android.InList(mctx.OtherModuleName(f.module), vctx.unwantedTransitiveDeps) {
			continue
		}
		dest := filepath.Join(f.installDir, f.builtFile.Base())
		if e, ok := encountered[dest]; !ok {
			encountered[dest] = f
		} else {
			if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
				mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
					dest, e.builtFile, f.builtFile)
				return
			}
			// If a module is directly included and also transitively depended on
			// consider it as directly included.
			e.transitiveDep = e.transitiveDep && f.transitiveDep
			// If a module is added as both a JNI library and a regular shared library, consider it as a
			// JNI library.
			e.isJniLib = e.isJniLib || f.isJniLib
			encountered[dest] = e
		}
	}
	vctx.filesInfo = vctx.filesInfo[:0]
	for _, v := range encountered {
		vctx.filesInfo = append(vctx.filesInfo, v)
	}
	sort.Slice(vctx.filesInfo, func(i, j int) bool {
		// Sort by destination path so as to ensure consistent ordering even if the source of the files
		// changes.
		return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
	})
}

func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
	depTag := ctx.OtherModuleDependencyTag(child)
	if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
		return false
	}
	if mod, ok := child.(android.Module); ok && !mod.Enabled() {
		return false
	}
	depName := ctx.OtherModuleName(child)
	if _, isDirectDep := parent.(*apexBundle); isDirectDep {
		switch depTag {
		case sharedLibTag, jniLibTag:
			isJniLib := depTag == jniLibTag
			propertyName := "native_shared_libs"
			if isJniLib {
				propertyName = "jni_libs"
			}
			switch ch := child.(type) {
			case *cc.Module:
				if ch.IsStubs() {
					ctx.PropertyErrorf(propertyName, "%q is a stub. Remove it from the list.", depName)
				}
				fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
				fi.isJniLib = isJniLib
				vctx.filesInfo = append(vctx.filesInfo, fi)
				addAconfigFiles(vctx, ctx, child)
				// Collect the list of stub-providing libs except:
				// - VNDK libs are only for vendors
				// - bootstrap bionic libs are treated as provided by system
				if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
					vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
				}
				return true // track transitive dependencies
			case *rust.Module:
				fi := apexFileForRustLibrary(ctx, ch)
				fi.isJniLib = isJniLib
				vctx.filesInfo = append(vctx.filesInfo, fi)
				addAconfigFiles(vctx, ctx, child)
				return true // track transitive dependencies
			default:
				ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
			}
		case executableTag:
			switch ch := child.(type) {
			case *cc.Module:
				vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
				addAconfigFiles(vctx, ctx, child)
				return true // track transitive dependencies
			case *rust.Module:
				vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
				addAconfigFiles(vctx, ctx, child)
				return true // track transitive dependencies
			default:
				ctx.PropertyErrorf("binaries",
					"%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
			}
		case shBinaryTag:
			if csh, ok := child.(*sh.ShBinary); ok {
				vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
			} else {
				ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
			}
		case bcpfTag:
			_, ok := child.(*java.BootclasspathFragmentModule)
			if !ok {
				ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
				return false
			}

			vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
			return true
		case sscpfTag:
			if _, ok := child.(*java.SystemServerClasspathModule); !ok {
				ctx.PropertyErrorf("systemserverclasspath_fragments",
					"%q is not a systemserverclasspath_fragment module", depName)
				return false
			}
			if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
				vctx.filesInfo = append(vctx.filesInfo, *af)
			}
			return true
		case javaLibTag:
			switch child.(type) {
			case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
				af := apexFileForJavaModule(ctx, child.(javaModule))
				if !af.ok() {
					ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
					return false
				}
				vctx.filesInfo = append(vctx.filesInfo, af)
				addAconfigFiles(vctx, ctx, child)
				return true // track transitive dependencies
			default:
				ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
			}
		case androidAppTag:
			switch ap := child.(type) {
			case *java.AndroidApp:
				vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
				addAconfigFiles(vctx, ctx, child)
				return true // track transitive dependencies
			case *java.AndroidAppImport:
				vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
				addAconfigFiles(vctx, ctx, child)
			case *java.AndroidTestHelperApp:
				vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
				addAconfigFiles(vctx, ctx, child)
			case *java.AndroidAppSet:
				appDir := "app"
				if ap.Privileged() {
					appDir = "priv-app"
				}
				// TODO(b/224589412, b/226559955): Ensure that the dirname is
				// suffixed so that PackageManager correctly invalidates the
				// existing installed apk in favour of the new APK-in-APEX.
				// See bugs for more information.
				appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
				af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
				af.certificate = java.PresignedCertificate
				vctx.filesInfo = append(vctx.filesInfo, af)
				addAconfigFiles(vctx, ctx, child)
			default:
				ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
			}
		case rroTag:
			if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
				vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
			} else {
				ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
			}
		case bpfTag:
			if bpfProgram, ok := child.(bpf.BpfModule); ok {
				filesToCopy, _ := bpfProgram.OutputFiles("")
				apex_sub_dir := bpfProgram.SubDir()
				for _, bpfFile := range filesToCopy {
					vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
				}
			} else {
				ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
			}
		case fsTag:
			if fs, ok := child.(filesystem.Filesystem); ok {
				vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
			} else {
				ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
			}
		case prebuiltTag:
			if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
				vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
				addAconfigFiles(vctx, ctx, child)
			} else {
				ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
			}
		case compatConfigTag:
			if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
				vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
			} else {
				ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
			}
		case testTag:
			if ccTest, ok := child.(*cc.Module); ok {
				if ccTest.IsTestPerSrcAllTestsVariation() {
					// Multiple-output test module (where `test_per_src: true`).
					//
					// `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
					// We do not add this variation to `filesInfo`, as it has no output;
					// however, we do add the other variations of this module as indirect
					// dependencies (see below).
				} else {
					// Single-output test module (where `test_per_src: false`).
					af := apexFileForExecutable(ctx, ccTest)
					af.class = nativeTest
					vctx.filesInfo = append(vctx.filesInfo, af)
					addAconfigFiles(vctx, ctx, child)
				}
				return true // track transitive dependencies
			} else {
				ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
			}
		case keyTag:
			if key, ok := child.(*apexKey); ok {
				a.privateKeyFile = key.privateKeyFile
				a.publicKeyFile = key.publicKeyFile
			} else {
				ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
			}
		case certificateTag:
			if dep, ok := child.(*java.AndroidAppCertificate); ok {
				a.containerCertificateFile = dep.Certificate.Pem
				a.containerPrivateKeyFile = dep.Certificate.Key
			} else {
				ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
			}
		}
		return false
	}

	if a.vndkApex {
		return false
	}

	// indirect dependencies
	am, ok := child.(android.ApexModule)
	if !ok {
		return false
	}
	// We cannot use a switch statement on `depTag` here as the checked
	// tags used below are private (e.g. `cc.sharedDepTag`).
	if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
		if ch, ok := child.(*cc.Module); ok {
			if ch.UseVndk() && a.useVndkAsStable(ctx) && ch.IsVndk() {
				vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
				return false
			}

			//TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated.
			if ch.InVendorOrProduct() && ctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" {
				return false
			}
			af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
			af.transitiveDep = true

			abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider)
			if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
				// If the dependency is a stubs lib, don't include it in this APEX,
				// but make sure that the lib is installed on the device.
				// In case no APEX is having the lib, the lib is installed to the system
				// partition.
				//
				// Always include if we are a host-apex however since those won't have any
				// system libraries.
				//
				// Skip the dependency in unbundled builds where the device image is not
				// being built.
				if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() && !ctx.Config().UnbundledBuild() {
					// we need a module name for Make
					name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
					if !android.InList(name, a.makeModulesToInstall) {
						a.makeModulesToInstall = append(a.makeModulesToInstall, name)
					}
				}
				vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
				// Don't track further
				return false
			}

			// If the dep is not considered to be in the same
			// apex, don't add it to filesInfo so that it is not
			// included in this APEX.
			// TODO(jiyong): move this to at the top of the
			// else-if clause for the indirect dependencies.
			// Currently, that's impossible because we would
			// like to record requiredNativeLibs even when
			// DepIsInSameAPex is false. We also shouldn't do
			// this for host.
			//
			// TODO(jiyong): explain why the same module is passed in twice.
			// Switching the first am to parent breaks lots of tests.
			if !android.IsDepInSameApex(ctx, am, am) {
				return false
			}

			vctx.filesInfo = append(vctx.filesInfo, af)
			addAconfigFiles(vctx, ctx, child)
			return true // track transitive dependencies
		} else if rm, ok := child.(*rust.Module); ok {
			af := apexFileForRustLibrary(ctx, rm)
			af.transitiveDep = true
			vctx.filesInfo = append(vctx.filesInfo, af)
			addAconfigFiles(vctx, ctx, child)
			return true // track transitive dependencies
		}
	} else if cc.IsTestPerSrcDepTag(depTag) {
		if ch, ok := child.(*cc.Module); ok {
			af := apexFileForExecutable(ctx, ch)
			// Handle modules created as `test_per_src` variations of a single test module:
			// use the name of the generated test binary (`fileToCopy`) instead of the name
			// of the original test module (`depName`, shared by all `test_per_src`
			// variations of that module).
			af.androidMkModuleName = filepath.Base(af.builtFile.String())
			// these are not considered transitive dep
			af.transitiveDep = false
			vctx.filesInfo = append(vctx.filesInfo, af)
			return true // track transitive dependencies
		}
	} else if cc.IsHeaderDepTag(depTag) {
		// nothing
	} else if java.IsJniDepTag(depTag) {
		// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
	} else if java.IsXmlPermissionsFileDepTag(depTag) {
		if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
			vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
		}
	} else if rust.IsDylibDepTag(depTag) {
		if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
			af := apexFileForRustLibrary(ctx, rustm)
			af.transitiveDep = true
			vctx.filesInfo = append(vctx.filesInfo, af)
			addAconfigFiles(vctx, ctx, child)
			return true // track transitive dependencies
		}
	} else if rust.IsRlibDepTag(depTag) {
		// Rlib is statically linked, but it might have shared lib
		// dependencies. Track them.
		return true
	} else if java.IsBootclasspathFragmentContentDepTag(depTag) {
		// Add the contents of the bootclasspath fragment to the apex.
		switch child.(type) {
		case *java.Library, *java.SdkLibrary:
			javaModule := child.(javaModule)
			af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
			if !af.ok() {
				ctx.PropertyErrorf("bootclasspath_fragments",
					"bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
				return false
			}
			vctx.filesInfo = append(vctx.filesInfo, af)
			addAconfigFiles(vctx, ctx, child)
			return true // track transitive dependencies
		default:
			ctx.PropertyErrorf("bootclasspath_fragments",
				"bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
		}
	} else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
		// Add the contents of the systemserverclasspath fragment to the apex.
		switch child.(type) {
		case *java.Library, *java.SdkLibrary:
			af := apexFileForJavaModule(ctx, child.(javaModule))
			vctx.filesInfo = append(vctx.filesInfo, af)
			if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil {
				vctx.filesInfo = append(vctx.filesInfo, *profileAf)
			}
			addAconfigFiles(vctx, ctx, child)
			return true // track transitive dependencies
		default:
			ctx.PropertyErrorf("systemserverclasspath_fragments",
				"systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
		}
	} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
		// nothing
	} else if depTag == android.DarwinUniversalVariantTag {
		// nothing
	} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
		ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
	}
	return false
}

func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
	dep, _ := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider)
	if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
		vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
	}
}

func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
	// TODO(b/263308293) remove this
	if a.properties.IsCoverageVariant {
		return false
	}
	if ctx.DeviceConfig().DeviceArch() == "" {
		return false
	}
	return true
}

// Creates build rules for an APEX. It consists of the following major steps:
//
// 1) do some validity checks such as apex_available, min_sdk_version, etc.
// 2) traverse the dependency tree to collect apexFile structs from them.
// 3) some fields in apexBundle struct are configured
// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	////////////////////////////////////////////////////////////////////////////////////////////
	// 1) do some validity checks such as apex_available, min_sdk_version, etc.
	if !a.commonBuildActions(ctx) {
		return
	}
	////////////////////////////////////////////////////////////////////////////////////////////
	// 2) traverse the dependency tree to collect apexFile structs from them.

	// TODO(jiyong): do this using WalkPayloadDeps
	// TODO(jiyong): make this clean!!!
	vctx := visitorContext{
		handleSpecialLibs:      !android.Bool(a.properties.Ignore_system_library_special_case),
		checkDuplicate:         a.shouldCheckDuplicate(ctx),
		unwantedTransitiveDeps: a.properties.Unwanted_transitive_deps,
	}
	ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
	vctx.normalizeFileInfo(ctx)
	if a.privateKeyFile == nil {
		if ctx.Config().AllowMissingDependencies() {
			// TODO(b/266099037): a better approach for slim manifests.
			ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
			// Create placeholder paths for later stages that expect to see those paths,
			// though they won't be used.
			var unusedPath = android.PathForModuleOut(ctx, "nonexistentprivatekey")
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.ErrorRule,
				Output: unusedPath,
				Args: map[string]string{
					"error": "Private key not available",
				},
			})
			a.privateKeyFile = unusedPath
		} else {
			ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
			return
		}
	}

	if a.publicKeyFile == nil {
		if ctx.Config().AllowMissingDependencies() {
			// TODO(b/266099037): a better approach for slim manifests.
			ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
			// Create placeholder paths for later stages that expect to see those paths,
			// though they won't be used.
			var unusedPath = android.PathForModuleOut(ctx, "nonexistentpublickey")
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.ErrorRule,
				Output: unusedPath,
				Args: map[string]string{
					"error": "Public key not available",
				},
			})
			a.publicKeyFile = unusedPath
		} else {
			ctx.PropertyErrorf("key", "public_key for %q could not be found", String(a.overridableProperties.Key))
			return
		}
	}
	android.CollectDependencyAconfigFiles(ctx, &a.mergedAconfigFiles)

	////////////////////////////////////////////////////////////////////////////////////////////
	// 3) some fields in apexBundle struct are configured
	a.installDir = android.PathForModuleInstall(ctx, "apex")
	a.filesInfo = vctx.filesInfo
	a.aconfigFiles = android.FirstUniquePaths(vctx.aconfigFiles)

	a.setPayloadFsType(ctx)
	a.setSystemLibLink(ctx)
	a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)

	////////////////////////////////////////////////////////////////////////////////////////////
	// 4) generate the build rules to create the APEX. This is done in builder.go.
	a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
	a.buildApex(ctx)
	a.buildApexDependencyInfo(ctx)
	a.buildLintReports(ctx)

	// Set a provider for dexpreopt of bootjars
	a.provideApexExportsInfo(ctx)
}

// Set a provider containing information about the jars and .prof provided by the apex
// Apexes built from source retrieve this information by visiting `bootclasspath_fragments`
// Used by dex_bootjars to generate the boot image
func (a *apexBundle) provideApexExportsInfo(ctx android.ModuleContext) {
	ctx.VisitDirectDepsWithTag(bcpfTag, func(child android.Module) {
		if info, ok := android.OtherModuleProvider(ctx, child, java.BootclasspathFragmentApexContentInfoProvider); ok {
			exports := android.ApexExportsInfo{
				ApexName:                      a.ApexVariationName(),
				ProfilePathOnHost:             info.ProfilePathOnHost(),
				LibraryNameToDexJarPathOnHost: info.DexBootJarPathMap(),
			}
			android.SetProvider(ctx, android.ApexExportsInfoProvider, exports)
		}
	})
}

// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
// the bootclasspath_fragment contributes to the apex.
func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
	bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, module, java.BootclasspathFragmentApexContentInfoProvider)
	var filesToAdd []apexFile

	// Add classpaths.proto config.
	if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
		filesToAdd = append(filesToAdd, *af)
	}

	pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
	if pathInApex != "" {
		pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
		tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)

		if pathOnHost != nil {
			// We need to copy the profile to a temporary path with the right filename because the apexer
			// will take the filename as is.
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.Cp,
				Input:  pathOnHost,
				Output: tempPath,
			})
		} else {
			// At this point, the boot image profile cannot be generated. It is probably because the boot
			// image profile source file does not exist on the branch, or it is not available for the
			// current build target.
			// However, we cannot enforce the boot image profile to be generated because some build
			// targets (such as module SDK) do not need it. It is only needed when the APEX is being
			// built. Therefore, we create an error rule so that an error will occur at the ninja phase
			// only if the APEX is being built.
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.ErrorRule,
				Output: tempPath,
				Args: map[string]string{
					"error": "Boot image profile cannot be generated",
				},
			})
		}

		androidMkModuleName := filepath.Base(pathInApex)
		af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
		filesToAdd = append(filesToAdd, af)
	}

	return filesToAdd
}

// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
// the module contributes to the apex; or nil if the proto config was not generated.
func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
	info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider)
	if !info.ClasspathFragmentProtoGenerated {
		return nil
	}
	classpathProtoOutput := info.ClasspathFragmentProtoOutput
	af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
	return &af
}

// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
// content module, i.e. a library that is part of the bootclasspath.
func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
	bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragmentModule, java.BootclasspathFragmentApexContentInfoProvider)

	// Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
	// hidden API encpding.
	dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
	if err != nil {
		ctx.ModuleErrorf("%s", err)
	}

	// Create an apexFile as for a normal java module but with the dex boot jar provided by the
	// bootclasspath_fragment.
	af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
	return af
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// Factory functions
//

func newApexBundle() *apexBundle {
	module := &apexBundle{}

	module.AddProperties(&module.properties)
	module.AddProperties(&module.targetProperties)
	module.AddProperties(&module.archProperties)
	module.AddProperties(&module.overridableProperties)

	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
	android.InitDefaultableModule(module)
	android.InitOverridableModule(module, &module.overridableProperties.Overrides)
	multitree.InitExportableModule(module)
	return module
}

func ApexBundleFactory(testApex bool) android.Module {
	bundle := newApexBundle()
	bundle.testApex = testApex
	return bundle
}

// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
// certain compatibility checks such as apex_available are not done for apex_test.
func TestApexBundleFactory() android.Module {
	bundle := newApexBundle()
	bundle.testApex = true
	return bundle
}

// apex packages other modules into an APEX file which is a packaging format for system-level
// components like binaries, shared libraries, etc.
func BundleFactory() android.Module {
	return newApexBundle()
}

type Defaults struct {
	android.ModuleBase
	android.DefaultsModuleBase

	// Single aconfig "cache file" merged from this module and all dependencies.
	mergedAconfigFiles map[string]android.Paths
}

// apex_defaults provides defaultable properties to other apex modules.
func DefaultsFactory() android.Module {
	module := &Defaults{}

	module.AddProperties(
		&apexBundleProperties{},
		&apexTargetBundleProperties{},
		&apexArchBundleProperties{},
		&overridableProperties{},
	)

	android.InitDefaultsModule(module)
	return module
}

type OverrideApex struct {
	android.ModuleBase
	android.OverrideModuleBase
}

func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
}

func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
	// All the overrides happen in the base module.
}

// override_apex is used to create an apex module based on another apex module by overriding some of
// its properties.
func OverrideApexFactory() android.Module {
	m := &OverrideApex{}

	m.AddProperties(&overridableProperties{})

	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
	android.InitOverrideModule(m)
	return m
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// Vality check routines
//
// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
// certain conditions are not met.
//
// TODO(jiyong): move these checks to a separate go file.

var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)

// Ensures that min_sdk_version of the included modules are equal or less than the min_sdk_version
// of this apexBundle.
func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
	if a.testApex || a.vndkApex {
		return
	}
	// apexBundle::minSdkVersion reports its own errors.
	minSdkVersion := a.minSdkVersion(ctx)
	android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
}

// Returns apex's min_sdk_version string value, honoring overrides
func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
	// Only override the minSdkVersion value on Apexes which already specify
	// a min_sdk_version (it's optional for non-updatable apexes), and that its
	// min_sdk_version value is lower than the one to override with.
	minApiLevel := android.MinSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
	if minApiLevel.IsNone() {
		return ""
	}

	overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
	overrideApiLevel := android.MinSdkVersionFromValue(ctx, overrideMinSdkValue)
	if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
		minApiLevel = overrideApiLevel
	}

	return minApiLevel.String()
}

// Returns apex's min_sdk_version SdkSpec, honoring overrides
func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	return a.minSdkVersion(ctx)
}

// Returns apex's min_sdk_version ApiLevel, honoring overrides
func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
	return android.MinSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
}

// Ensures that a lib providing stub isn't statically linked
func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
	// Practically, we only care about regular APEXes on the device.
	if a.testApex || a.vndkApex {
		return
	}

	abInfo, _ := android.ModuleProvider(ctx, android.ApexBundleInfoProvider)

	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
		if ccm, ok := to.(*cc.Module); ok {
			apexName := ctx.ModuleName()
			fromName := ctx.OtherModuleName(from)
			toName := ctx.OtherModuleName(to)

			// If `to` is not actually in the same APEX as `from` then it does not need
			// apex_available and neither do any of its dependencies.
			//
			// It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
			if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
				// As soon as the dependency graph crosses the APEX boundary, don't go further.
				return false
			}

			// The dynamic linker and crash_dump tool in the runtime APEX is the only
			// exception to this rule. It can't make the static dependencies dynamic
			// because it can't do the dynamic linking for itself.
			// Same rule should be applied to linkerconfig, because it should be executed
			// only with static linked libraries before linker is available with ld.config.txt
			if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
				return false
			}

			isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName)
			if isStubLibraryFromOtherApex && !externalDep {
				ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
					"It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
			}

		}
		return true
	})
}

// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
	if a.Updatable() {
		if a.minSdkVersionValue(ctx) == "" {
			ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
		}
		if a.UsePlatformApis() {
			ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
		}
		if proptools.Bool(a.properties.Use_vndk_as_stable) {
			ctx.PropertyErrorf("use_vndk_as_stable", "updatable APEXes can't use external VNDK libs")
		}
		if a.FutureUpdatable() {
			ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
		}
		a.checkJavaStableSdkVersion(ctx)
		a.checkClasspathFragments(ctx)
	}
}

// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
	ctx.VisitDirectDeps(func(module android.Module) {
		if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
			info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider)
			if !info.ClasspathFragmentProtoGenerated {
				ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
			}
		}
	})
}

// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
	// Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
	// java's checkLinkType guarantees correct usage for transitive deps
	ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
		tag := ctx.OtherModuleDependencyTag(module)
		switch tag {
		case javaLibTag, androidAppTag:
			if m, ok := module.(interface {
				CheckStableSdkVersion(ctx android.BaseModuleContext) error
			}); ok {
				if err := m.CheckStableSdkVersion(ctx); err != nil {
					ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
				}
			}
		}
	})
}

// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
	// Let's be practical. Availability for test, host, and the VNDK apex isn't important
	if a.testApex || a.vndkApex {
		return
	}

	// Because APEXes targeting other than system/system_ext partitions can't set
	// apex_available, we skip checks for these APEXes
	if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
		return
	}

	// Coverage build adds additional dependencies for the coverage-only runtime libraries.
	// Requiring them and their transitive depencies with apex_available is not right
	// because they just add noise.
	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
		return
	}

	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
		// As soon as the dependency graph crosses the APEX boundary, don't go further.
		if externalDep {
			return false
		}

		apexName := ctx.ModuleName()
		for _, props := range ctx.Module().GetProperties() {
			if apexProps, ok := props.(*apexBundleProperties); ok {
				if apexProps.Apex_available_name != nil {
					apexName = *apexProps.Apex_available_name
				}
			}
		}
		fromName := ctx.OtherModuleName(from)
		toName := ctx.OtherModuleName(to)

		// If `to` is not actually in the same APEX as `from` then it does not need
		// apex_available and neither do any of its dependencies.
		//
		// It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
		if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
			// As soon as the dependency graph crosses the APEX boundary, don't go
			// further.
			return false
		}

		if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
			return true
		}
		ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
			"\n\nDependency path:%s\n\n"+
			"Consider adding %q to 'apex_available' property of %q",
			fromName, toName, ctx.GetPathString(true), apexName, toName)
		// Visit this module's dependencies to check and report any issues with their availability.
		return true
	})
}

// checkStaticExecutable ensures that executables in an APEX are not static.
func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
	ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
		if ctx.OtherModuleDependencyTag(module) != executableTag {
			return
		}

		if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
			apex := a.ApexVariationName()
			exec := ctx.OtherModuleName(module)
			if isStaticExecutableAllowed(apex, exec) {
				return
			}
			ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
		}
	})
}

// A small list of exceptions where static executables are allowed in APEXes.
func isStaticExecutableAllowed(apex string, exec string) bool {
	m := map[string][]string{
		"com.android.runtime": {
			"linker",
			"linkerconfig",
		},
	}
	execNames, ok := m[apex]
	return ok && android.InList(exec, execNames)
}

// Collect information for opening IDE project files in java/jdeps.go.
func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
	dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
	dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
	dpInfo.Deps = append(dpInfo.Deps, a.properties.Systemserverclasspath_fragments...)
}

var (
	apexAvailBaseline        = makeApexAvailableBaseline()
	inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
)

func baselineApexAvailable(apex, moduleName string) bool {
	key := apex
	moduleName = normalizeModuleName(moduleName)

	if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
		return true
	}

	key = android.AvailableToAnyApex
	if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
		return true
	}

	return false
}

func normalizeModuleName(moduleName string) string {
	// Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
	// system. Trim the prefix for the check since they are confusing
	moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
	if strings.HasPrefix(moduleName, "libclang_rt.") {
		// This module has many arch variants that depend on the product being built.
		// We don't want to list them all
		moduleName = "libclang_rt"
	}
	if strings.HasPrefix(moduleName, "androidx.") {
		// TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
		moduleName = "androidx"
	}
	return moduleName
}

// Transform the map of apex -> modules to module -> apexes.
func invertApexBaseline(m map[string][]string) map[string][]string {
	r := make(map[string][]string)
	for apex, modules := range m {
		for _, module := range modules {
			r[module] = append(r[module], apex)
		}
	}
	return r
}

// Retrieve the baseline of apexes to which the supplied module belongs.
func BaselineApexAvailable(moduleName string) []string {
	return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
}

// This is a map from apex to modules, which overrides the apex_available setting for that
// particular module to make it available for the apex regardless of its setting.
// TODO(b/147364041): remove this
func makeApexAvailableBaseline() map[string][]string {
	// The "Module separator"s below are employed to minimize merge conflicts.
	m := make(map[string][]string)
	//
	// Module separator
	//
	m["com.android.runtime"] = []string{
		"libz",
	}
	return m
}

func init() {
	android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
	android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
}

func createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
	rules := make([]android.Rule, 0, len(bcpPermittedPackages))
	for jar, permittedPackages := range bcpPermittedPackages {
		permittedPackagesRule := android.NeverAllow().
			With("name", jar).
			WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
			Because(jar +
				" bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
				". Please consider the following alternatives:\n" +
				"    1. If the offending code is from a statically linked library, consider " +
				"removing that dependency and using an alternative already in the " +
				"bootclasspath, or perhaps a shared library." +
				"    2. Move the offending code into an allowed package.\n" +
				"    3. Jarjar the offending code. Please be mindful of the potential system " +
				"health implications of bundling that code, particularly if the offending jar " +
				"is part of the bootclasspath.")

		rules = append(rules, permittedPackagesRule)
	}
	return rules
}

// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
// Adding code to the bootclasspath in new packages will cause issues on module update.
func qBcpPackages() map[string][]string {
	return map[string][]string{
		"conscrypt": {
			"android.net.ssl",
			"com.android.org.conscrypt",
		},
		"updatable-media": {
			"android.media",
		},
	}
}

// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
// Adding code to the bootclasspath in new packages will cause issues on module update.
func rBcpPackages() map[string][]string {
	return map[string][]string{
		"framework-mediaprovider": {
			"android.provider",
		},
		"framework-permission": {
			"android.permission",
			"android.app.role",
			"com.android.permission",
			"com.android.role",
		},
		"framework-sdkextensions": {
			"android.os.ext",
		},
		"framework-statsd": {
			"android.app",
			"android.os",
			"android.util",
			"com.android.internal.statsd",
			"com.android.server.stats",
		},
		"framework-wifi": {
			"com.android.server.wifi",
			"com.android.wifi.x",
			"android.hardware.wifi",
			"android.net.wifi",
		},
		"framework-tethering": {
			"android.net",
		},
	}
}

func (a *apexBundle) IsTestApex() bool {
	return a.testApex
}

func (a *apexBundle) useVndkAsStable(ctx android.BaseModuleContext) bool {
	// VNDK cannot be linked if it is deprecated
	if ctx.Config().IsVndkDeprecated() {
		return false
	}

	return proptools.Bool(a.properties.Use_vndk_as_stable)
}
