xref: /aosp_15_r20/build/soong/apex/apex.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2018 The Android Open Source Project
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Worker// package apex implements build rules for creating the APEX files which are container for
16*333d2b36SAndroid Build Coastguard Worker// lower-level system components. See https://source.android.com/devices/tech/ota/apex
17*333d2b36SAndroid Build Coastguard Workerpackage apex
18*333d2b36SAndroid Build Coastguard Worker
19*333d2b36SAndroid Build Coastguard Workerimport (
20*333d2b36SAndroid Build Coastguard Worker	"fmt"
21*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
22*333d2b36SAndroid Build Coastguard Worker	"regexp"
23*333d2b36SAndroid Build Coastguard Worker	"slices"
24*333d2b36SAndroid Build Coastguard Worker	"sort"
25*333d2b36SAndroid Build Coastguard Worker	"strings"
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
28*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/depset"
29*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
30*333d2b36SAndroid Build Coastguard Worker
31*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
32*333d2b36SAndroid Build Coastguard Worker	"android/soong/bpf"
33*333d2b36SAndroid Build Coastguard Worker	"android/soong/cc"
34*333d2b36SAndroid Build Coastguard Worker	"android/soong/dexpreopt"
35*333d2b36SAndroid Build Coastguard Worker	prebuilt_etc "android/soong/etc"
36*333d2b36SAndroid Build Coastguard Worker	"android/soong/filesystem"
37*333d2b36SAndroid Build Coastguard Worker	"android/soong/java"
38*333d2b36SAndroid Build Coastguard Worker	"android/soong/rust"
39*333d2b36SAndroid Build Coastguard Worker	"android/soong/sh"
40*333d2b36SAndroid Build Coastguard Worker)
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Workerfunc init() {
43*333d2b36SAndroid Build Coastguard Worker	registerApexBuildComponents(android.InitRegistrationContext)
44*333d2b36SAndroid Build Coastguard Worker}
45*333d2b36SAndroid Build Coastguard Worker
46*333d2b36SAndroid Build Coastguard Workerfunc registerApexBuildComponents(ctx android.RegistrationContext) {
47*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex", BundleFactory)
48*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex_test", TestApexBundleFactory)
49*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
50*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex_defaults", DefaultsFactory)
51*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
52*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("override_apex", OverrideApexFactory)
53*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex_set", apexSetFactory)
54*333d2b36SAndroid Build Coastguard Worker
55*333d2b36SAndroid Build Coastguard Worker	ctx.PreDepsMutators(RegisterPreDepsMutators)
56*333d2b36SAndroid Build Coastguard Worker	ctx.PostDepsMutators(RegisterPostDepsMutators)
57*333d2b36SAndroid Build Coastguard Worker}
58*333d2b36SAndroid Build Coastguard Worker
59*333d2b36SAndroid Build Coastguard Workerfunc RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
60*333d2b36SAndroid Build Coastguard Worker	ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).UsesReverseDependencies()
61*333d2b36SAndroid Build Coastguard Worker}
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Workerfunc RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
64*333d2b36SAndroid Build Coastguard Worker	ctx.TopDown("apex_info", apexInfoMutator)
65*333d2b36SAndroid Build Coastguard Worker	ctx.BottomUp("apex_unique", apexUniqueVariationsMutator)
66*333d2b36SAndroid Build Coastguard Worker	// Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
67*333d2b36SAndroid Build Coastguard Worker	// it should create a platform variant.
68*333d2b36SAndroid Build Coastguard Worker	ctx.BottomUp("mark_platform_availability", markPlatformAvailability)
69*333d2b36SAndroid Build Coastguard Worker	ctx.Transition("apex", &apexTransitionMutator{})
70*333d2b36SAndroid Build Coastguard Worker}
71*333d2b36SAndroid Build Coastguard Worker
72*333d2b36SAndroid Build Coastguard Workertype apexBundleProperties struct {
73*333d2b36SAndroid Build Coastguard Worker	// Json manifest file describing meta info of this APEX bundle. Refer to
74*333d2b36SAndroid Build Coastguard Worker	// system/apex/proto/apex_manifest.proto for the schema. Default: "apex_manifest.json"
75*333d2b36SAndroid Build Coastguard Worker	Manifest *string `android:"path"`
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Worker	// AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
78*333d2b36SAndroid Build Coastguard Worker	// a default one is automatically generated.
79*333d2b36SAndroid Build Coastguard Worker	AndroidManifest proptools.Configurable[string] `android:"path,replace_instead_of_append"`
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Worker	// Determines the file contexts file for setting the security contexts to files in this APEX
82*333d2b36SAndroid Build Coastguard Worker	// bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
83*333d2b36SAndroid Build Coastguard Worker	// /system/sepolicy/apex/<module_name>_file_contexts.
84*333d2b36SAndroid Build Coastguard Worker	File_contexts *string `android:"path"`
85*333d2b36SAndroid Build Coastguard Worker
86*333d2b36SAndroid Build Coastguard Worker	// By default, file_contexts is amended by force-labelling / and /apex_manifest.pb as system_file
87*333d2b36SAndroid Build Coastguard Worker	// to avoid mistakes. When set as true, no force-labelling.
88*333d2b36SAndroid Build Coastguard Worker	Use_file_contexts_as_is *bool
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Worker	// Path to the canned fs config file for customizing file's
91*333d2b36SAndroid Build Coastguard Worker	// uid/gid/mod/capabilities. The content of this file is appended to the
92*333d2b36SAndroid Build Coastguard Worker	// default config, so that the custom entries are preferred. The format is
93*333d2b36SAndroid Build Coastguard Worker	// /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where
94*333d2b36SAndroid Build Coastguard Worker	// path_or_glob is a path or glob pattern for a file or set of files,
95*333d2b36SAndroid Build Coastguard Worker	// uid/gid are numerial values of user ID and group ID, mode is octal value
96*333d2b36SAndroid Build Coastguard Worker	// for the file mode, and cap is hexadecimal value for the capability.
97*333d2b36SAndroid Build Coastguard Worker	Canned_fs_config proptools.Configurable[string] `android:"path,replace_instead_of_append"`
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Worker	ApexNativeDependencies
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker	Multilib apexMultilibProperties
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Worker	// List of runtime resource overlays (RROs) that are embedded inside this APEX.
104*333d2b36SAndroid Build Coastguard Worker	Rros []string
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard Worker	// List of bootclasspath fragments that are embedded inside this APEX bundle.
107*333d2b36SAndroid Build Coastguard Worker	Bootclasspath_fragments proptools.Configurable[[]string]
108*333d2b36SAndroid Build Coastguard Worker
109*333d2b36SAndroid Build Coastguard Worker	// List of systemserverclasspath fragments that are embedded inside this APEX bundle.
110*333d2b36SAndroid Build Coastguard Worker	Systemserverclasspath_fragments proptools.Configurable[[]string]
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard Worker	// List of java libraries that are embedded inside this APEX bundle.
113*333d2b36SAndroid Build Coastguard Worker	Java_libs []string
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Worker	// List of sh binaries that are embedded inside this APEX bundle.
116*333d2b36SAndroid Build Coastguard Worker	Sh_binaries []string
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Worker	// List of platform_compat_config files that are embedded inside this APEX bundle.
119*333d2b36SAndroid Build Coastguard Worker	Compat_configs []string
120*333d2b36SAndroid Build Coastguard Worker
121*333d2b36SAndroid Build Coastguard Worker	// List of filesystem images that are embedded inside this APEX bundle.
122*333d2b36SAndroid Build Coastguard Worker	Filesystems []string
123*333d2b36SAndroid Build Coastguard Worker
124*333d2b36SAndroid Build Coastguard Worker	// List of module names which we don't want to add as transitive deps. This can be used as
125*333d2b36SAndroid Build Coastguard Worker	// a workaround when the current implementation collects more than necessary. For example,
126*333d2b36SAndroid Build Coastguard Worker	// Rust binaries with prefer_rlib:true add unnecessary dependencies.
127*333d2b36SAndroid Build Coastguard Worker	Unwanted_transitive_deps []string
128*333d2b36SAndroid Build Coastguard Worker
129*333d2b36SAndroid Build Coastguard Worker	// Whether this APEX is considered updatable or not. When set to true, this will enforce
130*333d2b36SAndroid Build Coastguard Worker	// additional rules for making sure that the APEX is truly updatable. To be updatable,
131*333d2b36SAndroid Build Coastguard Worker	// min_sdk_version should be set as well. This will also disable the size optimizations like
132*333d2b36SAndroid Build Coastguard Worker	// symlinking to the system libs. Default is true.
133*333d2b36SAndroid Build Coastguard Worker	Updatable *bool
134*333d2b36SAndroid Build Coastguard Worker
135*333d2b36SAndroid Build Coastguard Worker	// Marks that this APEX is designed to be updatable in the future, although it's not
136*333d2b36SAndroid Build Coastguard Worker	// updatable yet. This is used to mimic some of the build behaviors that are applied only to
137*333d2b36SAndroid Build Coastguard Worker	// updatable APEXes. Currently, this disables the size optimization, so that the size of
138*333d2b36SAndroid Build Coastguard Worker	// APEX will not increase when the APEX is actually marked as truly updatable. Default is
139*333d2b36SAndroid Build Coastguard Worker	// false.
140*333d2b36SAndroid Build Coastguard Worker	Future_updatable *bool
141*333d2b36SAndroid Build Coastguard Worker
142*333d2b36SAndroid Build Coastguard Worker	// Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
143*333d2b36SAndroid Build Coastguard Worker	// false`. Default is false.
144*333d2b36SAndroid Build Coastguard Worker	Platform_apis *bool
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard Worker	// Whether this APEX is installable to one of the partitions like system, vendor, etc.
147*333d2b36SAndroid Build Coastguard Worker	// Default: true.
148*333d2b36SAndroid Build Coastguard Worker	Installable *bool
149*333d2b36SAndroid Build Coastguard Worker
150*333d2b36SAndroid Build Coastguard Worker	// The type of filesystem to use. Either 'ext4', 'f2fs' or 'erofs'. Default 'ext4'.
151*333d2b36SAndroid Build Coastguard Worker	Payload_fs_type *string
152*333d2b36SAndroid Build Coastguard Worker
153*333d2b36SAndroid Build Coastguard Worker	// For telling the APEX to ignore special handling for system libraries such as bionic.
154*333d2b36SAndroid Build Coastguard Worker	// Default is false.
155*333d2b36SAndroid Build Coastguard Worker	Ignore_system_library_special_case *bool
156*333d2b36SAndroid Build Coastguard Worker
157*333d2b36SAndroid Build Coastguard Worker	// Whenever apex_payload.img of the APEX should not be dm-verity signed. Should be only
158*333d2b36SAndroid Build Coastguard Worker	// used in tests.
159*333d2b36SAndroid Build Coastguard Worker	Test_only_unsigned_payload *bool
160*333d2b36SAndroid Build Coastguard Worker
161*333d2b36SAndroid Build Coastguard Worker	// Whenever apex should be compressed, regardless of product flag used. Should be only
162*333d2b36SAndroid Build Coastguard Worker	// used in tests.
163*333d2b36SAndroid Build Coastguard Worker	Test_only_force_compression *bool
164*333d2b36SAndroid Build Coastguard Worker
165*333d2b36SAndroid Build Coastguard Worker	// Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
166*333d2b36SAndroid Build Coastguard Worker	// with the tool to sign payload contents.
167*333d2b36SAndroid Build Coastguard Worker	Custom_sign_tool *string
168*333d2b36SAndroid Build Coastguard Worker
169*333d2b36SAndroid Build Coastguard Worker	// Whether this is a dynamic common lib apex, if so the native shared libs will be placed
170*333d2b36SAndroid Build Coastguard Worker	// in a special way that include the digest of the lib file under /lib(64)?
171*333d2b36SAndroid Build Coastguard Worker	Dynamic_common_lib_apex *bool
172*333d2b36SAndroid Build Coastguard Worker
173*333d2b36SAndroid Build Coastguard Worker	// Canonical name of this APEX bundle. Used to determine the path to the
174*333d2b36SAndroid Build Coastguard Worker	// activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
175*333d2b36SAndroid Build Coastguard Worker	// apex mutator variations. For override_apex modules, this is the name of the
176*333d2b36SAndroid Build Coastguard Worker	// overridden base module.
177*333d2b36SAndroid Build Coastguard Worker	ApexVariationName string `blueprint:"mutated"`
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Worker	IsCoverageVariant bool `blueprint:"mutated"`
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Worker	// List of sanitizer names that this APEX is enabled for
182*333d2b36SAndroid Build Coastguard Worker	SanitizerNames []string `blueprint:"mutated"`
183*333d2b36SAndroid Build Coastguard Worker
184*333d2b36SAndroid Build Coastguard Worker	PreventInstall bool `blueprint:"mutated"`
185*333d2b36SAndroid Build Coastguard Worker
186*333d2b36SAndroid Build Coastguard Worker	HideFromMake bool `blueprint:"mutated"`
187*333d2b36SAndroid Build Coastguard Worker
188*333d2b36SAndroid Build Coastguard Worker	// Name that dependencies can specify in their apex_available properties to refer to this module.
189*333d2b36SAndroid Build Coastguard Worker	// If not specified, this defaults to Soong module name. This must be the name of a Soong module.
190*333d2b36SAndroid Build Coastguard Worker	Apex_available_name *string
191*333d2b36SAndroid Build Coastguard Worker
192*333d2b36SAndroid Build Coastguard Worker	// Variant version of the mainline module. Must be an integer between 0-9
193*333d2b36SAndroid Build Coastguard Worker	Variant_version *string
194*333d2b36SAndroid Build Coastguard Worker}
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Workertype ApexNativeDependencies struct {
197*333d2b36SAndroid Build Coastguard Worker	// List of native libraries that are embedded inside this APEX.
198*333d2b36SAndroid Build Coastguard Worker	Native_shared_libs proptools.Configurable[[]string]
199*333d2b36SAndroid Build Coastguard Worker
200*333d2b36SAndroid Build Coastguard Worker	// List of JNI libraries that are embedded inside this APEX.
201*333d2b36SAndroid Build Coastguard Worker	Jni_libs proptools.Configurable[[]string]
202*333d2b36SAndroid Build Coastguard Worker
203*333d2b36SAndroid Build Coastguard Worker	// List of rust dyn libraries that are embedded inside this APEX.
204*333d2b36SAndroid Build Coastguard Worker	Rust_dyn_libs []string
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Worker	// List of native executables that are embedded inside this APEX.
207*333d2b36SAndroid Build Coastguard Worker	Binaries proptools.Configurable[[]string]
208*333d2b36SAndroid Build Coastguard Worker
209*333d2b36SAndroid Build Coastguard Worker	// List of native tests that are embedded inside this APEX.
210*333d2b36SAndroid Build Coastguard Worker	Tests []string
211*333d2b36SAndroid Build Coastguard Worker
212*333d2b36SAndroid Build Coastguard Worker	// List of filesystem images that are embedded inside this APEX bundle.
213*333d2b36SAndroid Build Coastguard Worker	Filesystems []string
214*333d2b36SAndroid Build Coastguard Worker
215*333d2b36SAndroid Build Coastguard Worker	// List of prebuilt_etcs that are embedded inside this APEX bundle.
216*333d2b36SAndroid Build Coastguard Worker	Prebuilts proptools.Configurable[[]string]
217*333d2b36SAndroid Build Coastguard Worker
218*333d2b36SAndroid Build Coastguard Worker	// List of native libraries to exclude from this APEX.
219*333d2b36SAndroid Build Coastguard Worker	Exclude_native_shared_libs []string
220*333d2b36SAndroid Build Coastguard Worker
221*333d2b36SAndroid Build Coastguard Worker	// List of JNI libraries to exclude from this APEX.
222*333d2b36SAndroid Build Coastguard Worker	Exclude_jni_libs []string
223*333d2b36SAndroid Build Coastguard Worker
224*333d2b36SAndroid Build Coastguard Worker	// List of rust dyn libraries to exclude from this APEX.
225*333d2b36SAndroid Build Coastguard Worker	Exclude_rust_dyn_libs []string
226*333d2b36SAndroid Build Coastguard Worker
227*333d2b36SAndroid Build Coastguard Worker	// List of native executables to exclude from this APEX.
228*333d2b36SAndroid Build Coastguard Worker	Exclude_binaries []string
229*333d2b36SAndroid Build Coastguard Worker
230*333d2b36SAndroid Build Coastguard Worker	// List of native tests to exclude from this APEX.
231*333d2b36SAndroid Build Coastguard Worker	Exclude_tests []string
232*333d2b36SAndroid Build Coastguard Worker
233*333d2b36SAndroid Build Coastguard Worker	// List of filesystem images to exclude from this APEX bundle.
234*333d2b36SAndroid Build Coastguard Worker	Exclude_filesystems []string
235*333d2b36SAndroid Build Coastguard Worker
236*333d2b36SAndroid Build Coastguard Worker	// List of prebuilt_etcs to exclude from this APEX bundle.
237*333d2b36SAndroid Build Coastguard Worker	Exclude_prebuilts []string
238*333d2b36SAndroid Build Coastguard Worker}
239*333d2b36SAndroid Build Coastguard Worker
240*333d2b36SAndroid Build Coastguard Workertype ResolvedApexNativeDependencies struct {
241*333d2b36SAndroid Build Coastguard Worker	// List of native libraries that are embedded inside this APEX.
242*333d2b36SAndroid Build Coastguard Worker	Native_shared_libs []string
243*333d2b36SAndroid Build Coastguard Worker
244*333d2b36SAndroid Build Coastguard Worker	// List of JNI libraries that are embedded inside this APEX.
245*333d2b36SAndroid Build Coastguard Worker	Jni_libs []string
246*333d2b36SAndroid Build Coastguard Worker
247*333d2b36SAndroid Build Coastguard Worker	// List of rust dyn libraries that are embedded inside this APEX.
248*333d2b36SAndroid Build Coastguard Worker	Rust_dyn_libs []string
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard Worker	// List of native executables that are embedded inside this APEX.
251*333d2b36SAndroid Build Coastguard Worker	Binaries []string
252*333d2b36SAndroid Build Coastguard Worker
253*333d2b36SAndroid Build Coastguard Worker	// List of native tests that are embedded inside this APEX.
254*333d2b36SAndroid Build Coastguard Worker	Tests []string
255*333d2b36SAndroid Build Coastguard Worker
256*333d2b36SAndroid Build Coastguard Worker	// List of filesystem images that are embedded inside this APEX bundle.
257*333d2b36SAndroid Build Coastguard Worker	Filesystems []string
258*333d2b36SAndroid Build Coastguard Worker
259*333d2b36SAndroid Build Coastguard Worker	// List of prebuilt_etcs that are embedded inside this APEX bundle.
260*333d2b36SAndroid Build Coastguard Worker	Prebuilts []string
261*333d2b36SAndroid Build Coastguard Worker
262*333d2b36SAndroid Build Coastguard Worker	// List of native libraries to exclude from this APEX.
263*333d2b36SAndroid Build Coastguard Worker	Exclude_native_shared_libs []string
264*333d2b36SAndroid Build Coastguard Worker
265*333d2b36SAndroid Build Coastguard Worker	// List of JNI libraries to exclude from this APEX.
266*333d2b36SAndroid Build Coastguard Worker	Exclude_jni_libs []string
267*333d2b36SAndroid Build Coastguard Worker
268*333d2b36SAndroid Build Coastguard Worker	// List of rust dyn libraries to exclude from this APEX.
269*333d2b36SAndroid Build Coastguard Worker	Exclude_rust_dyn_libs []string
270*333d2b36SAndroid Build Coastguard Worker
271*333d2b36SAndroid Build Coastguard Worker	// List of native executables to exclude from this APEX.
272*333d2b36SAndroid Build Coastguard Worker	Exclude_binaries []string
273*333d2b36SAndroid Build Coastguard Worker
274*333d2b36SAndroid Build Coastguard Worker	// List of native tests to exclude from this APEX.
275*333d2b36SAndroid Build Coastguard Worker	Exclude_tests []string
276*333d2b36SAndroid Build Coastguard Worker
277*333d2b36SAndroid Build Coastguard Worker	// List of filesystem images to exclude from this APEX bundle.
278*333d2b36SAndroid Build Coastguard Worker	Exclude_filesystems []string
279*333d2b36SAndroid Build Coastguard Worker
280*333d2b36SAndroid Build Coastguard Worker	// List of prebuilt_etcs to exclude from this APEX bundle.
281*333d2b36SAndroid Build Coastguard Worker	Exclude_prebuilts []string
282*333d2b36SAndroid Build Coastguard Worker}
283*333d2b36SAndroid Build Coastguard Worker
284*333d2b36SAndroid Build Coastguard Worker// Merge combines another ApexNativeDependencies into this one
285*333d2b36SAndroid Build Coastguard Workerfunc (a *ResolvedApexNativeDependencies) Merge(ctx android.BaseModuleContext, b ApexNativeDependencies) {
286*333d2b36SAndroid Build Coastguard Worker	a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs.GetOrDefault(ctx, nil)...)
287*333d2b36SAndroid Build Coastguard Worker	a.Jni_libs = append(a.Jni_libs, b.Jni_libs.GetOrDefault(ctx, nil)...)
288*333d2b36SAndroid Build Coastguard Worker	a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
289*333d2b36SAndroid Build Coastguard Worker	a.Binaries = append(a.Binaries, b.Binaries.GetOrDefault(ctx, nil)...)
290*333d2b36SAndroid Build Coastguard Worker	a.Tests = append(a.Tests, b.Tests...)
291*333d2b36SAndroid Build Coastguard Worker	a.Filesystems = append(a.Filesystems, b.Filesystems...)
292*333d2b36SAndroid Build Coastguard Worker	a.Prebuilts = append(a.Prebuilts, b.Prebuilts.GetOrDefault(ctx, nil)...)
293*333d2b36SAndroid Build Coastguard Worker
294*333d2b36SAndroid Build Coastguard Worker	a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
295*333d2b36SAndroid Build Coastguard Worker	a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
296*333d2b36SAndroid Build Coastguard Worker	a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
297*333d2b36SAndroid Build Coastguard Worker	a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
298*333d2b36SAndroid Build Coastguard Worker	a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
299*333d2b36SAndroid Build Coastguard Worker	a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
300*333d2b36SAndroid Build Coastguard Worker	a.Exclude_prebuilts = append(a.Exclude_prebuilts, b.Exclude_prebuilts...)
301*333d2b36SAndroid Build Coastguard Worker}
302*333d2b36SAndroid Build Coastguard Worker
303*333d2b36SAndroid Build Coastguard Workertype apexMultilibProperties struct {
304*333d2b36SAndroid Build Coastguard Worker	// Native dependencies whose compile_multilib is "first"
305*333d2b36SAndroid Build Coastguard Worker	First ApexNativeDependencies
306*333d2b36SAndroid Build Coastguard Worker
307*333d2b36SAndroid Build Coastguard Worker	// Native dependencies whose compile_multilib is "both"
308*333d2b36SAndroid Build Coastguard Worker	Both ApexNativeDependencies
309*333d2b36SAndroid Build Coastguard Worker
310*333d2b36SAndroid Build Coastguard Worker	// Native dependencies whose compile_multilib is "prefer32"
311*333d2b36SAndroid Build Coastguard Worker	Prefer32 ApexNativeDependencies
312*333d2b36SAndroid Build Coastguard Worker
313*333d2b36SAndroid Build Coastguard Worker	// Native dependencies whose compile_multilib is "32"
314*333d2b36SAndroid Build Coastguard Worker	Lib32 ApexNativeDependencies
315*333d2b36SAndroid Build Coastguard Worker
316*333d2b36SAndroid Build Coastguard Worker	// Native dependencies whose compile_multilib is "64"
317*333d2b36SAndroid Build Coastguard Worker	Lib64 ApexNativeDependencies
318*333d2b36SAndroid Build Coastguard Worker}
319*333d2b36SAndroid Build Coastguard Worker
320*333d2b36SAndroid Build Coastguard Workertype apexTargetBundleProperties struct {
321*333d2b36SAndroid Build Coastguard Worker	Target struct {
322*333d2b36SAndroid Build Coastguard Worker		// Multilib properties only for android.
323*333d2b36SAndroid Build Coastguard Worker		Android struct {
324*333d2b36SAndroid Build Coastguard Worker			Multilib apexMultilibProperties
325*333d2b36SAndroid Build Coastguard Worker		}
326*333d2b36SAndroid Build Coastguard Worker
327*333d2b36SAndroid Build Coastguard Worker		// Multilib properties only for host.
328*333d2b36SAndroid Build Coastguard Worker		Host struct {
329*333d2b36SAndroid Build Coastguard Worker			Multilib apexMultilibProperties
330*333d2b36SAndroid Build Coastguard Worker		}
331*333d2b36SAndroid Build Coastguard Worker
332*333d2b36SAndroid Build Coastguard Worker		// Multilib properties only for host linux_bionic.
333*333d2b36SAndroid Build Coastguard Worker		Linux_bionic struct {
334*333d2b36SAndroid Build Coastguard Worker			Multilib apexMultilibProperties
335*333d2b36SAndroid Build Coastguard Worker		}
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Worker		// Multilib properties only for host linux_glibc.
338*333d2b36SAndroid Build Coastguard Worker		Linux_glibc struct {
339*333d2b36SAndroid Build Coastguard Worker			Multilib apexMultilibProperties
340*333d2b36SAndroid Build Coastguard Worker		}
341*333d2b36SAndroid Build Coastguard Worker	}
342*333d2b36SAndroid Build Coastguard Worker}
343*333d2b36SAndroid Build Coastguard Worker
344*333d2b36SAndroid Build Coastguard Workertype apexArchBundleProperties struct {
345*333d2b36SAndroid Build Coastguard Worker	Arch struct {
346*333d2b36SAndroid Build Coastguard Worker		Arm struct {
347*333d2b36SAndroid Build Coastguard Worker			ApexNativeDependencies
348*333d2b36SAndroid Build Coastguard Worker		}
349*333d2b36SAndroid Build Coastguard Worker		Arm64 struct {
350*333d2b36SAndroid Build Coastguard Worker			ApexNativeDependencies
351*333d2b36SAndroid Build Coastguard Worker		}
352*333d2b36SAndroid Build Coastguard Worker		Riscv64 struct {
353*333d2b36SAndroid Build Coastguard Worker			ApexNativeDependencies
354*333d2b36SAndroid Build Coastguard Worker		}
355*333d2b36SAndroid Build Coastguard Worker		X86 struct {
356*333d2b36SAndroid Build Coastguard Worker			ApexNativeDependencies
357*333d2b36SAndroid Build Coastguard Worker		}
358*333d2b36SAndroid Build Coastguard Worker		X86_64 struct {
359*333d2b36SAndroid Build Coastguard Worker			ApexNativeDependencies
360*333d2b36SAndroid Build Coastguard Worker		}
361*333d2b36SAndroid Build Coastguard Worker	}
362*333d2b36SAndroid Build Coastguard Worker}
363*333d2b36SAndroid Build Coastguard Worker
364*333d2b36SAndroid Build Coastguard Worker// These properties can be used in override_apex to override the corresponding properties in the
365*333d2b36SAndroid Build Coastguard Worker// base apex.
366*333d2b36SAndroid Build Coastguard Workertype overridableProperties struct {
367*333d2b36SAndroid Build Coastguard Worker	// List of APKs that are embedded inside this APEX.
368*333d2b36SAndroid Build Coastguard Worker	Apps proptools.Configurable[[]string]
369*333d2b36SAndroid Build Coastguard Worker
370*333d2b36SAndroid Build Coastguard Worker	// List of prebuilt files that are embedded inside this APEX bundle.
371*333d2b36SAndroid Build Coastguard Worker	Prebuilts proptools.Configurable[[]string]
372*333d2b36SAndroid Build Coastguard Worker
373*333d2b36SAndroid Build Coastguard Worker	// List of BPF programs inside this APEX bundle.
374*333d2b36SAndroid Build Coastguard Worker	Bpfs []string
375*333d2b36SAndroid Build Coastguard Worker
376*333d2b36SAndroid Build Coastguard Worker	// Names of modules to be overridden. Listed modules can only be other binaries (in Make or
377*333d2b36SAndroid Build Coastguard Worker	// Soong). This does not completely prevent installation of the overridden binaries, but if
378*333d2b36SAndroid Build Coastguard Worker	// both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
379*333d2b36SAndroid Build Coastguard Worker	// be removed from PRODUCT_PACKAGES.
380*333d2b36SAndroid Build Coastguard Worker	Overrides []string
381*333d2b36SAndroid Build Coastguard Worker
382*333d2b36SAndroid Build Coastguard Worker	Multilib apexMultilibProperties
383*333d2b36SAndroid Build Coastguard Worker
384*333d2b36SAndroid Build Coastguard Worker	// Logging parent value.
385*333d2b36SAndroid Build Coastguard Worker	Logging_parent string
386*333d2b36SAndroid Build Coastguard Worker
387*333d2b36SAndroid Build Coastguard Worker	// Apex Container package name. Override value for attribute package:name in
388*333d2b36SAndroid Build Coastguard Worker	// AndroidManifest.xml
389*333d2b36SAndroid Build Coastguard Worker	Package_name proptools.Configurable[string]
390*333d2b36SAndroid Build Coastguard Worker
391*333d2b36SAndroid Build Coastguard Worker	// A txt file containing list of files that are allowed to be included in this APEX.
392*333d2b36SAndroid Build Coastguard Worker	Allowed_files *string `android:"path"`
393*333d2b36SAndroid Build Coastguard Worker
394*333d2b36SAndroid Build Coastguard Worker	// Name of the apex_key module that provides the private key to sign this APEX bundle.
395*333d2b36SAndroid Build Coastguard Worker	Key *string
396*333d2b36SAndroid Build Coastguard Worker
397*333d2b36SAndroid Build Coastguard Worker	// Specifies the certificate and the private key to sign the zip container of this APEX. If
398*333d2b36SAndroid Build Coastguard Worker	// this is "foo", foo.x509.pem and foo.pk8 under PRODUCT_DEFAULT_DEV_CERTIFICATE are used
399*333d2b36SAndroid Build Coastguard Worker	// as the certificate and the private key, respectively. If this is ":module", then the
400*333d2b36SAndroid Build Coastguard Worker	// certificate and the private key are provided from the android_app_certificate module
401*333d2b36SAndroid Build Coastguard Worker	// named "module".
402*333d2b36SAndroid Build Coastguard Worker	Certificate *string
403*333d2b36SAndroid Build Coastguard Worker
404*333d2b36SAndroid Build Coastguard Worker	// Whether this APEX can be compressed or not. Setting this property to false means this
405*333d2b36SAndroid Build Coastguard Worker	// APEX will never be compressed. When set to true, APEX will be compressed if other
406*333d2b36SAndroid Build Coastguard Worker	// conditions, e.g., target device needs to support APEX compression, are also fulfilled.
407*333d2b36SAndroid Build Coastguard Worker	// Default: false.
408*333d2b36SAndroid Build Coastguard Worker	Compressible *bool
409*333d2b36SAndroid Build Coastguard Worker
410*333d2b36SAndroid Build Coastguard Worker	// Trim against a specific Dynamic Common Lib APEX
411*333d2b36SAndroid Build Coastguard Worker	Trim_against *string
412*333d2b36SAndroid Build Coastguard Worker
413*333d2b36SAndroid Build Coastguard Worker	// The minimum SDK version that this APEX must support at minimum. This is usually set to
414*333d2b36SAndroid Build Coastguard Worker	// the SDK version that the APEX was first introduced.
415*333d2b36SAndroid Build Coastguard Worker	Min_sdk_version *string
416*333d2b36SAndroid Build Coastguard Worker}
417*333d2b36SAndroid Build Coastguard Worker
418*333d2b36SAndroid Build Coastguard Workertype apexBundle struct {
419*333d2b36SAndroid Build Coastguard Worker	// Inherited structs
420*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
421*333d2b36SAndroid Build Coastguard Worker	android.DefaultableModuleBase
422*333d2b36SAndroid Build Coastguard Worker	android.OverridableModuleBase
423*333d2b36SAndroid Build Coastguard Worker
424*333d2b36SAndroid Build Coastguard Worker	// Properties
425*333d2b36SAndroid Build Coastguard Worker	properties            apexBundleProperties
426*333d2b36SAndroid Build Coastguard Worker	targetProperties      apexTargetBundleProperties
427*333d2b36SAndroid Build Coastguard Worker	archProperties        apexArchBundleProperties
428*333d2b36SAndroid Build Coastguard Worker	overridableProperties overridableProperties
429*333d2b36SAndroid Build Coastguard Worker	vndkProperties        apexVndkProperties // only for apex_vndk modules
430*333d2b36SAndroid Build Coastguard Worker	testProperties        apexTestProperties // only for apex_test modules
431*333d2b36SAndroid Build Coastguard Worker
432*333d2b36SAndroid Build Coastguard Worker	///////////////////////////////////////////////////////////////////////////////////////////
433*333d2b36SAndroid Build Coastguard Worker	// Inputs
434*333d2b36SAndroid Build Coastguard Worker
435*333d2b36SAndroid Build Coastguard Worker	// Keys for apex_payload.img
436*333d2b36SAndroid Build Coastguard Worker	publicKeyFile  android.Path
437*333d2b36SAndroid Build Coastguard Worker	privateKeyFile android.Path
438*333d2b36SAndroid Build Coastguard Worker
439*333d2b36SAndroid Build Coastguard Worker	// Cert/priv-key for the zip container
440*333d2b36SAndroid Build Coastguard Worker	containerCertificateFile android.Path
441*333d2b36SAndroid Build Coastguard Worker	containerPrivateKeyFile  android.Path
442*333d2b36SAndroid Build Coastguard Worker
443*333d2b36SAndroid Build Coastguard Worker	// Flags for special variants of APEX
444*333d2b36SAndroid Build Coastguard Worker	testApex bool
445*333d2b36SAndroid Build Coastguard Worker	vndkApex bool
446*333d2b36SAndroid Build Coastguard Worker
447*333d2b36SAndroid Build Coastguard Worker	// File system type of apex_payload.img
448*333d2b36SAndroid Build Coastguard Worker	payloadFsType fsType
449*333d2b36SAndroid Build Coastguard Worker
450*333d2b36SAndroid Build Coastguard Worker	// Whether to create symlink to the system file instead of having a file inside the apex or
451*333d2b36SAndroid Build Coastguard Worker	// not
452*333d2b36SAndroid Build Coastguard Worker	linkToSystemLib bool
453*333d2b36SAndroid Build Coastguard Worker
454*333d2b36SAndroid Build Coastguard Worker	// List of files to be included in this APEX. This is filled in the first part of
455*333d2b36SAndroid Build Coastguard Worker	// GenerateAndroidBuildActions.
456*333d2b36SAndroid Build Coastguard Worker	filesInfo []apexFile
457*333d2b36SAndroid Build Coastguard Worker
458*333d2b36SAndroid Build Coastguard Worker	// List of files that were excluded by the unwanted_transitive_deps property.
459*333d2b36SAndroid Build Coastguard Worker	unwantedTransitiveFilesInfo []apexFile
460*333d2b36SAndroid Build Coastguard Worker
461*333d2b36SAndroid Build Coastguard Worker	// List of files that were excluded due to conflicts with other variants of the same module.
462*333d2b36SAndroid Build Coastguard Worker	duplicateTransitiveFilesInfo []apexFile
463*333d2b36SAndroid Build Coastguard Worker
464*333d2b36SAndroid Build Coastguard Worker	// List of other module names that should be installed when this APEX gets installed (LOCAL_REQUIRED_MODULES).
465*333d2b36SAndroid Build Coastguard Worker	makeModulesToInstall []string
466*333d2b36SAndroid Build Coastguard Worker
467*333d2b36SAndroid Build Coastguard Worker	///////////////////////////////////////////////////////////////////////////////////////////
468*333d2b36SAndroid Build Coastguard Worker	// Outputs (final and intermediates)
469*333d2b36SAndroid Build Coastguard Worker
470*333d2b36SAndroid Build Coastguard Worker	// Processed apex manifest in JSONson format (for Q)
471*333d2b36SAndroid Build Coastguard Worker	manifestJsonOut android.WritablePath
472*333d2b36SAndroid Build Coastguard Worker
473*333d2b36SAndroid Build Coastguard Worker	// Processed apex manifest in PB format (for R+)
474*333d2b36SAndroid Build Coastguard Worker	manifestPbOut android.WritablePath
475*333d2b36SAndroid Build Coastguard Worker
476*333d2b36SAndroid Build Coastguard Worker	// Processed file_contexts files
477*333d2b36SAndroid Build Coastguard Worker	fileContexts android.WritablePath
478*333d2b36SAndroid Build Coastguard Worker
479*333d2b36SAndroid Build Coastguard Worker	// The built APEX file. This is the main product.
480*333d2b36SAndroid Build Coastguard Worker	// Could be .apex or .capex
481*333d2b36SAndroid Build Coastguard Worker	outputFile android.WritablePath
482*333d2b36SAndroid Build Coastguard Worker
483*333d2b36SAndroid Build Coastguard Worker	// The built uncompressed .apex file.
484*333d2b36SAndroid Build Coastguard Worker	outputApexFile android.WritablePath
485*333d2b36SAndroid Build Coastguard Worker
486*333d2b36SAndroid Build Coastguard Worker	// The built APEX file in app bundle format. This file is not directly installed to the
487*333d2b36SAndroid Build Coastguard Worker	// device. For an APEX, multiple app bundles are created each of which is for a specific ABI
488*333d2b36SAndroid Build Coastguard Worker	// like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
489*333d2b36SAndroid Build Coastguard Worker	// system) to be merged into a single app bundle file that Play accepts. See
490*333d2b36SAndroid Build Coastguard Worker	// vendor/google/build/build_unbundled_mainline_module.sh for more detail.
491*333d2b36SAndroid Build Coastguard Worker	bundleModuleFile android.WritablePath
492*333d2b36SAndroid Build Coastguard Worker
493*333d2b36SAndroid Build Coastguard Worker	// Target directory to install this APEX. Usually out/target/product/<device>/<partition>/apex.
494*333d2b36SAndroid Build Coastguard Worker	installDir android.InstallPath
495*333d2b36SAndroid Build Coastguard Worker
496*333d2b36SAndroid Build Coastguard Worker	// Path where this APEX was installed.
497*333d2b36SAndroid Build Coastguard Worker	installedFile android.InstallPath
498*333d2b36SAndroid Build Coastguard Worker
499*333d2b36SAndroid Build Coastguard Worker	// fragment for this apex for apexkeys.txt
500*333d2b36SAndroid Build Coastguard Worker	apexKeysPath android.WritablePath
501*333d2b36SAndroid Build Coastguard Worker
502*333d2b36SAndroid Build Coastguard Worker	// Installed locations of symlinks for backward compatibility.
503*333d2b36SAndroid Build Coastguard Worker	compatSymlinks android.InstallPaths
504*333d2b36SAndroid Build Coastguard Worker
505*333d2b36SAndroid Build Coastguard Worker	// Text file having the list of individual files that are included in this APEX. Used for
506*333d2b36SAndroid Build Coastguard Worker	// debugging purpose.
507*333d2b36SAndroid Build Coastguard Worker	installedFilesFile android.Path
508*333d2b36SAndroid Build Coastguard Worker
509*333d2b36SAndroid Build Coastguard Worker	// List of module names that this APEX is including (to be shown via *-deps-info target).
510*333d2b36SAndroid Build Coastguard Worker	// Used for debugging purpose.
511*333d2b36SAndroid Build Coastguard Worker	android.ApexBundleDepsInfo
512*333d2b36SAndroid Build Coastguard Worker
513*333d2b36SAndroid Build Coastguard Worker	// Optional list of lint report zip files for apexes that contain java or app modules
514*333d2b36SAndroid Build Coastguard Worker	lintReports android.Paths
515*333d2b36SAndroid Build Coastguard Worker
516*333d2b36SAndroid Build Coastguard Worker	isCompressed bool
517*333d2b36SAndroid Build Coastguard Worker
518*333d2b36SAndroid Build Coastguard Worker	// Path of API coverage generate file
519*333d2b36SAndroid Build Coastguard Worker	nativeApisUsedByModuleFile   android.ModuleOutPath
520*333d2b36SAndroid Build Coastguard Worker	nativeApisBackedByModuleFile android.ModuleOutPath
521*333d2b36SAndroid Build Coastguard Worker	javaApisUsedByModuleFile     android.ModuleOutPath
522*333d2b36SAndroid Build Coastguard Worker
523*333d2b36SAndroid Build Coastguard Worker	aconfigFiles []android.Path
524*333d2b36SAndroid Build Coastguard Worker
525*333d2b36SAndroid Build Coastguard Worker	// Required modules, filled out during GenerateAndroidBuildActions and used in AndroidMk
526*333d2b36SAndroid Build Coastguard Worker	required []string
527*333d2b36SAndroid Build Coastguard Worker}
528*333d2b36SAndroid Build Coastguard Worker
529*333d2b36SAndroid Build Coastguard Worker// apexFileClass represents a type of file that can be included in APEX.
530*333d2b36SAndroid Build Coastguard Workertype apexFileClass int
531*333d2b36SAndroid Build Coastguard Worker
532*333d2b36SAndroid Build Coastguard Workerconst (
533*333d2b36SAndroid Build Coastguard Worker	app apexFileClass = iota
534*333d2b36SAndroid Build Coastguard Worker	appSet
535*333d2b36SAndroid Build Coastguard Worker	etc
536*333d2b36SAndroid Build Coastguard Worker	javaSharedLib
537*333d2b36SAndroid Build Coastguard Worker	nativeExecutable
538*333d2b36SAndroid Build Coastguard Worker	nativeSharedLib
539*333d2b36SAndroid Build Coastguard Worker	nativeTest
540*333d2b36SAndroid Build Coastguard Worker	shBinary
541*333d2b36SAndroid Build Coastguard Worker)
542*333d2b36SAndroid Build Coastguard Worker
543*333d2b36SAndroid Build Coastguard Workervar (
544*333d2b36SAndroid Build Coastguard Worker	classes = map[string]apexFileClass{
545*333d2b36SAndroid Build Coastguard Worker		"app":              app,
546*333d2b36SAndroid Build Coastguard Worker		"appSet":           appSet,
547*333d2b36SAndroid Build Coastguard Worker		"etc":              etc,
548*333d2b36SAndroid Build Coastguard Worker		"javaSharedLib":    javaSharedLib,
549*333d2b36SAndroid Build Coastguard Worker		"nativeExecutable": nativeExecutable,
550*333d2b36SAndroid Build Coastguard Worker		"nativeSharedLib":  nativeSharedLib,
551*333d2b36SAndroid Build Coastguard Worker		"nativeTest":       nativeTest,
552*333d2b36SAndroid Build Coastguard Worker		"shBinary":         shBinary,
553*333d2b36SAndroid Build Coastguard Worker	}
554*333d2b36SAndroid Build Coastguard Worker)
555*333d2b36SAndroid Build Coastguard Worker
556*333d2b36SAndroid Build Coastguard Worker// apexFile represents a file in an APEX bundle. This is created during the first half of
557*333d2b36SAndroid Build Coastguard Worker// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
558*333d2b36SAndroid Build Coastguard Worker// of the function, this is used to create commands that copies the files into a staging directory,
559*333d2b36SAndroid Build Coastguard Worker// where they are packaged into the APEX file.
560*333d2b36SAndroid Build Coastguard Workertype apexFile struct {
561*333d2b36SAndroid Build Coastguard Worker	// buildFile is put in the installDir inside the APEX.
562*333d2b36SAndroid Build Coastguard Worker	builtFile  android.Path
563*333d2b36SAndroid Build Coastguard Worker	installDir string
564*333d2b36SAndroid Build Coastguard Worker	partition  string
565*333d2b36SAndroid Build Coastguard Worker	customStem string
566*333d2b36SAndroid Build Coastguard Worker	symlinks   []string // additional symlinks
567*333d2b36SAndroid Build Coastguard Worker
568*333d2b36SAndroid Build Coastguard Worker	checkbuildTarget android.Path
569*333d2b36SAndroid Build Coastguard Worker
570*333d2b36SAndroid Build Coastguard Worker	// Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
571*333d2b36SAndroid Build Coastguard Worker	// module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
572*333d2b36SAndroid Build Coastguard Worker	// suffix>]
573*333d2b36SAndroid Build Coastguard Worker	androidMkModuleName       string             // becomes LOCAL_MODULE
574*333d2b36SAndroid Build Coastguard Worker	class                     apexFileClass      // becomes LOCAL_MODULE_CLASS
575*333d2b36SAndroid Build Coastguard Worker	moduleDir                 string             // becomes LOCAL_PATH
576*333d2b36SAndroid Build Coastguard Worker	requiredModuleNames       []string           // becomes LOCAL_REQUIRED_MODULES
577*333d2b36SAndroid Build Coastguard Worker	targetRequiredModuleNames []string           // becomes LOCAL_TARGET_REQUIRED_MODULES
578*333d2b36SAndroid Build Coastguard Worker	hostRequiredModuleNames   []string           // becomes LOCAL_HOST_REQUIRED_MODULES
579*333d2b36SAndroid Build Coastguard Worker	dataPaths                 []android.DataPath // becomes LOCAL_TEST_DATA
580*333d2b36SAndroid Build Coastguard Worker
581*333d2b36SAndroid Build Coastguard Worker	jacocoReportClassesFile android.Path     // only for javalibs and apps
582*333d2b36SAndroid Build Coastguard Worker	lintInfo                *java.LintInfo   // only for javalibs and apps
583*333d2b36SAndroid Build Coastguard Worker	certificate             java.Certificate // only for apps
584*333d2b36SAndroid Build Coastguard Worker	overriddenPackageName   string           // only for apps
585*333d2b36SAndroid Build Coastguard Worker
586*333d2b36SAndroid Build Coastguard Worker	transitiveDep bool
587*333d2b36SAndroid Build Coastguard Worker	isJniLib      bool
588*333d2b36SAndroid Build Coastguard Worker
589*333d2b36SAndroid Build Coastguard Worker	multilib string
590*333d2b36SAndroid Build Coastguard Worker
591*333d2b36SAndroid Build Coastguard Worker	// TODO(jiyong): remove this
592*333d2b36SAndroid Build Coastguard Worker	module android.Module
593*333d2b36SAndroid Build Coastguard Worker}
594*333d2b36SAndroid Build Coastguard Worker
595*333d2b36SAndroid Build Coastguard Worker// TODO(jiyong): shorten the arglist using an option struct
596*333d2b36SAndroid Build Coastguard Workerfunc newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
597*333d2b36SAndroid Build Coastguard Worker	ret := apexFile{
598*333d2b36SAndroid Build Coastguard Worker		builtFile:           builtFile,
599*333d2b36SAndroid Build Coastguard Worker		installDir:          installDir,
600*333d2b36SAndroid Build Coastguard Worker		androidMkModuleName: androidMkModuleName,
601*333d2b36SAndroid Build Coastguard Worker		class:               class,
602*333d2b36SAndroid Build Coastguard Worker		module:              module,
603*333d2b36SAndroid Build Coastguard Worker	}
604*333d2b36SAndroid Build Coastguard Worker	if module != nil {
605*333d2b36SAndroid Build Coastguard Worker		if installFilesInfo, ok := android.OtherModuleProvider(ctx, module, android.InstallFilesProvider); ok {
606*333d2b36SAndroid Build Coastguard Worker			ret.checkbuildTarget = installFilesInfo.CheckbuildTarget
607*333d2b36SAndroid Build Coastguard Worker		}
608*333d2b36SAndroid Build Coastguard Worker		ret.moduleDir = ctx.OtherModuleDir(module)
609*333d2b36SAndroid Build Coastguard Worker		ret.partition = module.PartitionTag(ctx.DeviceConfig())
610*333d2b36SAndroid Build Coastguard Worker		ret.multilib = module.Target().Arch.ArchType.Multilib
611*333d2b36SAndroid Build Coastguard Worker	}
612*333d2b36SAndroid Build Coastguard Worker	return ret
613*333d2b36SAndroid Build Coastguard Worker}
614*333d2b36SAndroid Build Coastguard Worker
615*333d2b36SAndroid Build Coastguard Workerfunc (af *apexFile) ok() bool {
616*333d2b36SAndroid Build Coastguard Worker	return af.builtFile != nil && af.builtFile.String() != ""
617*333d2b36SAndroid Build Coastguard Worker}
618*333d2b36SAndroid Build Coastguard Worker
619*333d2b36SAndroid Build Coastguard Worker// apexRelativePath returns the relative path of the given path from the install directory of this
620*333d2b36SAndroid Build Coastguard Worker// apexFile.
621*333d2b36SAndroid Build Coastguard Worker// TODO(jiyong): rename this
622*333d2b36SAndroid Build Coastguard Workerfunc (af *apexFile) apexRelativePath(path string) string {
623*333d2b36SAndroid Build Coastguard Worker	return filepath.Join(af.installDir, path)
624*333d2b36SAndroid Build Coastguard Worker}
625*333d2b36SAndroid Build Coastguard Worker
626*333d2b36SAndroid Build Coastguard Worker// path returns path of this apex file relative to the APEX root
627*333d2b36SAndroid Build Coastguard Workerfunc (af *apexFile) path() string {
628*333d2b36SAndroid Build Coastguard Worker	return af.apexRelativePath(af.stem())
629*333d2b36SAndroid Build Coastguard Worker}
630*333d2b36SAndroid Build Coastguard Worker
631*333d2b36SAndroid Build Coastguard Worker// stem returns the base filename of this apex file
632*333d2b36SAndroid Build Coastguard Workerfunc (af *apexFile) stem() string {
633*333d2b36SAndroid Build Coastguard Worker	if af.customStem != "" {
634*333d2b36SAndroid Build Coastguard Worker		return af.customStem
635*333d2b36SAndroid Build Coastguard Worker	}
636*333d2b36SAndroid Build Coastguard Worker	return af.builtFile.Base()
637*333d2b36SAndroid Build Coastguard Worker}
638*333d2b36SAndroid Build Coastguard Worker
639*333d2b36SAndroid Build Coastguard Worker// symlinkPaths returns paths of the symlinks (if any) relative to the APEX root
640*333d2b36SAndroid Build Coastguard Workerfunc (af *apexFile) symlinkPaths() []string {
641*333d2b36SAndroid Build Coastguard Worker	var ret []string
642*333d2b36SAndroid Build Coastguard Worker	for _, symlink := range af.symlinks {
643*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, af.apexRelativePath(symlink))
644*333d2b36SAndroid Build Coastguard Worker	}
645*333d2b36SAndroid Build Coastguard Worker	return ret
646*333d2b36SAndroid Build Coastguard Worker}
647*333d2b36SAndroid Build Coastguard Worker
648*333d2b36SAndroid Build Coastguard Worker// availableToPlatform tests whether this apexFile is from a module that can be installed to the
649*333d2b36SAndroid Build Coastguard Worker// platform.
650*333d2b36SAndroid Build Coastguard Workerfunc (af *apexFile) availableToPlatform() bool {
651*333d2b36SAndroid Build Coastguard Worker	if af.module == nil {
652*333d2b36SAndroid Build Coastguard Worker		return false
653*333d2b36SAndroid Build Coastguard Worker	}
654*333d2b36SAndroid Build Coastguard Worker	if am, ok := af.module.(android.ApexModule); ok {
655*333d2b36SAndroid Build Coastguard Worker		return am.AvailableFor(android.AvailableToPlatform)
656*333d2b36SAndroid Build Coastguard Worker	}
657*333d2b36SAndroid Build Coastguard Worker	return false
658*333d2b36SAndroid Build Coastguard Worker}
659*333d2b36SAndroid Build Coastguard Worker
660*333d2b36SAndroid Build Coastguard Worker////////////////////////////////////////////////////////////////////////////////////////////////////
661*333d2b36SAndroid Build Coastguard Worker// Mutators
662*333d2b36SAndroid Build Coastguard Worker//
663*333d2b36SAndroid Build Coastguard Worker// Brief description about mutators for APEX. The following three mutators are the most important
664*333d2b36SAndroid Build Coastguard Worker// ones.
665*333d2b36SAndroid Build Coastguard Worker//
666*333d2b36SAndroid Build Coastguard Worker// 1) DepsMutator: from the properties like native_shared_libs, java_libs, etc., modules are added
667*333d2b36SAndroid Build Coastguard Worker// to the (direct) dependencies of this APEX bundle.
668*333d2b36SAndroid Build Coastguard Worker//
669*333d2b36SAndroid Build Coastguard Worker// 2) apexInfoMutator: this is a post-deps mutator, so runs after DepsMutator. Its goal is to
670*333d2b36SAndroid Build Coastguard Worker// collect modules that are direct and transitive dependencies of each APEX bundle. The collected
671*333d2b36SAndroid Build Coastguard Worker// modules are marked as being included in the APEX via BuildForApex().
672*333d2b36SAndroid Build Coastguard Worker//
673*333d2b36SAndroid Build Coastguard Worker// 3) apexMutator: this is a post-deps mutator that runs after apexInfoMutator. For each module that
674*333d2b36SAndroid Build Coastguard Worker// are marked by the apexInfoMutator, apex variations are created using CreateApexVariations().
675*333d2b36SAndroid Build Coastguard Worker
676*333d2b36SAndroid Build Coastguard Workertype dependencyTag struct {
677*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
678*333d2b36SAndroid Build Coastguard Worker	name string
679*333d2b36SAndroid Build Coastguard Worker
680*333d2b36SAndroid Build Coastguard Worker	// Determines if the dependent will be part of the APEX payload. Can be false for the
681*333d2b36SAndroid Build Coastguard Worker	// dependencies to the signing key module, etc.
682*333d2b36SAndroid Build Coastguard Worker	payload bool
683*333d2b36SAndroid Build Coastguard Worker
684*333d2b36SAndroid Build Coastguard Worker	// True if the dependent can only be a source module, false if a prebuilt module is a suitable
685*333d2b36SAndroid Build Coastguard Worker	// replacement. This is needed because some prebuilt modules do not provide all the information
686*333d2b36SAndroid Build Coastguard Worker	// needed by the apex.
687*333d2b36SAndroid Build Coastguard Worker	sourceOnly bool
688*333d2b36SAndroid Build Coastguard Worker
689*333d2b36SAndroid Build Coastguard Worker	// If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
690*333d2b36SAndroid Build Coastguard Worker	// also be added as exported members of that SDK.
691*333d2b36SAndroid Build Coastguard Worker	memberType android.SdkMemberType
692*333d2b36SAndroid Build Coastguard Worker
693*333d2b36SAndroid Build Coastguard Worker	installable bool
694*333d2b36SAndroid Build Coastguard Worker}
695*333d2b36SAndroid Build Coastguard Worker
696*333d2b36SAndroid Build Coastguard Workerfunc (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
697*333d2b36SAndroid Build Coastguard Worker	return d.memberType
698*333d2b36SAndroid Build Coastguard Worker}
699*333d2b36SAndroid Build Coastguard Worker
700*333d2b36SAndroid Build Coastguard Workerfunc (d *dependencyTag) ExportMember() bool {
701*333d2b36SAndroid Build Coastguard Worker	return true
702*333d2b36SAndroid Build Coastguard Worker}
703*333d2b36SAndroid Build Coastguard Worker
704*333d2b36SAndroid Build Coastguard Workerfunc (d *dependencyTag) String() string {
705*333d2b36SAndroid Build Coastguard Worker	return fmt.Sprintf("apex.dependencyTag{%q}", d.name)
706*333d2b36SAndroid Build Coastguard Worker}
707*333d2b36SAndroid Build Coastguard Worker
708*333d2b36SAndroid Build Coastguard Workerfunc (d *dependencyTag) ReplaceSourceWithPrebuilt() bool {
709*333d2b36SAndroid Build Coastguard Worker	return !d.sourceOnly
710*333d2b36SAndroid Build Coastguard Worker}
711*333d2b36SAndroid Build Coastguard Worker
712*333d2b36SAndroid Build Coastguard Workerfunc (d *dependencyTag) InstallDepNeeded() bool {
713*333d2b36SAndroid Build Coastguard Worker	return d.installable
714*333d2b36SAndroid Build Coastguard Worker}
715*333d2b36SAndroid Build Coastguard Worker
716*333d2b36SAndroid Build Coastguard Workervar _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
717*333d2b36SAndroid Build Coastguard Workervar _ android.SdkMemberDependencyTag = &dependencyTag{}
718*333d2b36SAndroid Build Coastguard Worker
719*333d2b36SAndroid Build Coastguard Workervar (
720*333d2b36SAndroid Build Coastguard Worker	androidAppTag  = &dependencyTag{name: "androidApp", payload: true}
721*333d2b36SAndroid Build Coastguard Worker	bpfTag         = &dependencyTag{name: "bpf", payload: true}
722*333d2b36SAndroid Build Coastguard Worker	certificateTag = &dependencyTag{name: "certificate"}
723*333d2b36SAndroid Build Coastguard Worker	executableTag  = &dependencyTag{name: "executable", payload: true}
724*333d2b36SAndroid Build Coastguard Worker	fsTag          = &dependencyTag{name: "filesystem", payload: true}
725*333d2b36SAndroid Build Coastguard Worker	bcpfTag        = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
726*333d2b36SAndroid Build Coastguard Worker	// The dexpreopt artifacts of apex system server jars are installed onto system image.
727*333d2b36SAndroid Build Coastguard Worker	sscpfTag        = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType, installable: true}
728*333d2b36SAndroid Build Coastguard Worker	compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
729*333d2b36SAndroid Build Coastguard Worker	javaLibTag      = &dependencyTag{name: "javaLib", payload: true}
730*333d2b36SAndroid Build Coastguard Worker	jniLibTag       = &dependencyTag{name: "jniLib", payload: true}
731*333d2b36SAndroid Build Coastguard Worker	keyTag          = &dependencyTag{name: "key"}
732*333d2b36SAndroid Build Coastguard Worker	prebuiltTag     = &dependencyTag{name: "prebuilt", payload: true}
733*333d2b36SAndroid Build Coastguard Worker	rroTag          = &dependencyTag{name: "rro", payload: true}
734*333d2b36SAndroid Build Coastguard Worker	sharedLibTag    = &dependencyTag{name: "sharedLib", payload: true}
735*333d2b36SAndroid Build Coastguard Worker	testTag         = &dependencyTag{name: "test", payload: true}
736*333d2b36SAndroid Build Coastguard Worker	shBinaryTag     = &dependencyTag{name: "shBinary", payload: true}
737*333d2b36SAndroid Build Coastguard Worker)
738*333d2b36SAndroid Build Coastguard Worker
739*333d2b36SAndroid Build Coastguard Worker// TODO(jiyong): shorten this function signature
740*333d2b36SAndroid Build Coastguard Workerfunc addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ResolvedApexNativeDependencies, target android.Target, imageVariation string) {
741*333d2b36SAndroid Build Coastguard Worker	binVariations := target.Variations()
742*333d2b36SAndroid Build Coastguard Worker	libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
743*333d2b36SAndroid Build Coastguard Worker	rustLibVariations := append(
744*333d2b36SAndroid Build Coastguard Worker		target.Variations(), []blueprint.Variation{
745*333d2b36SAndroid Build Coastguard Worker			{Mutator: "rust_libraries", Variation: "dylib"},
746*333d2b36SAndroid Build Coastguard Worker		}...,
747*333d2b36SAndroid Build Coastguard Worker	)
748*333d2b36SAndroid Build Coastguard Worker
749*333d2b36SAndroid Build Coastguard Worker	// Append "image" variation
750*333d2b36SAndroid Build Coastguard Worker	binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
751*333d2b36SAndroid Build Coastguard Worker	libVariations = append(libVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
752*333d2b36SAndroid Build Coastguard Worker	rustLibVariations = append(rustLibVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
753*333d2b36SAndroid Build Coastguard Worker
754*333d2b36SAndroid Build Coastguard Worker	// Use *FarVariation* to be able to depend on modules having conflicting variations with
755*333d2b36SAndroid Build Coastguard Worker	// this module. This is required since arch variant of an APEX bundle is 'common' but it is
756*333d2b36SAndroid Build Coastguard Worker	// 'arm' or 'arm64' for native shared libs.
757*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(binVariations, executableTag,
758*333d2b36SAndroid Build Coastguard Worker		android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
759*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(binVariations, testTag,
760*333d2b36SAndroid Build Coastguard Worker		android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
761*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(libVariations, jniLibTag,
762*333d2b36SAndroid Build Coastguard Worker		android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
763*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
764*333d2b36SAndroid Build Coastguard Worker		android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
765*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
766*333d2b36SAndroid Build Coastguard Worker		android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
767*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(target.Variations(), fsTag,
768*333d2b36SAndroid Build Coastguard Worker		android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
769*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(target.Variations(), prebuiltTag,
770*333d2b36SAndroid Build Coastguard Worker		android.RemoveListFromList(nativeModules.Prebuilts, nativeModules.Exclude_prebuilts)...)
771*333d2b36SAndroid Build Coastguard Worker}
772*333d2b36SAndroid Build Coastguard Worker
773*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
774*333d2b36SAndroid Build Coastguard Worker	proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
775*333d2b36SAndroid Build Coastguard Worker}
776*333d2b36SAndroid Build Coastguard Worker
777*333d2b36SAndroid Build Coastguard Worker// getImageVariationPair returns a pair for the image variation name as its
778*333d2b36SAndroid Build Coastguard Worker// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
779*333d2b36SAndroid Build Coastguard Worker// suffix indicates the vndk version for vendor/product if vndk is enabled.
780*333d2b36SAndroid Build Coastguard Worker// getImageVariation can simply join the result of this function to get the
781*333d2b36SAndroid Build Coastguard Worker// image variation name.
782*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) getImageVariationPair() (string, string) {
783*333d2b36SAndroid Build Coastguard Worker	if a.vndkApex {
784*333d2b36SAndroid Build Coastguard Worker		return cc.VendorVariationPrefix, a.vndkVersion()
785*333d2b36SAndroid Build Coastguard Worker	}
786*333d2b36SAndroid Build Coastguard Worker
787*333d2b36SAndroid Build Coastguard Worker	prefix := android.CoreVariation
788*333d2b36SAndroid Build Coastguard Worker	if a.SocSpecific() || a.DeviceSpecific() {
789*333d2b36SAndroid Build Coastguard Worker		prefix = android.VendorVariation
790*333d2b36SAndroid Build Coastguard Worker	} else if a.ProductSpecific() {
791*333d2b36SAndroid Build Coastguard Worker		prefix = android.ProductVariation
792*333d2b36SAndroid Build Coastguard Worker	}
793*333d2b36SAndroid Build Coastguard Worker
794*333d2b36SAndroid Build Coastguard Worker	return prefix, ""
795*333d2b36SAndroid Build Coastguard Worker}
796*333d2b36SAndroid Build Coastguard Worker
797*333d2b36SAndroid Build Coastguard Worker// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
798*333d2b36SAndroid Build Coastguard Worker// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
799*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) getImageVariation() string {
800*333d2b36SAndroid Build Coastguard Worker	prefix, vndkVersion := a.getImageVariationPair()
801*333d2b36SAndroid Build Coastguard Worker	return prefix + vndkVersion
802*333d2b36SAndroid Build Coastguard Worker}
803*333d2b36SAndroid Build Coastguard Worker
804*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
805*333d2b36SAndroid Build Coastguard Worker	// apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
806*333d2b36SAndroid Build Coastguard Worker	// arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
807*333d2b36SAndroid Build Coastguard Worker	// each target os/architectures, appropriate dependencies are selected by their
808*333d2b36SAndroid Build Coastguard Worker	// target.<os>.multilib.<type> groups and are added as (direct) dependencies.
809*333d2b36SAndroid Build Coastguard Worker	targets := ctx.MultiTargets()
810*333d2b36SAndroid Build Coastguard Worker	imageVariation := a.getImageVariation()
811*333d2b36SAndroid Build Coastguard Worker
812*333d2b36SAndroid Build Coastguard Worker	a.combineProperties(ctx)
813*333d2b36SAndroid Build Coastguard Worker
814*333d2b36SAndroid Build Coastguard Worker	has32BitTarget := false
815*333d2b36SAndroid Build Coastguard Worker	for _, target := range targets {
816*333d2b36SAndroid Build Coastguard Worker		if target.Arch.ArchType.Multilib == "lib32" {
817*333d2b36SAndroid Build Coastguard Worker			has32BitTarget = true
818*333d2b36SAndroid Build Coastguard Worker		}
819*333d2b36SAndroid Build Coastguard Worker	}
820*333d2b36SAndroid Build Coastguard Worker	for i, target := range targets {
821*333d2b36SAndroid Build Coastguard Worker		var deps ResolvedApexNativeDependencies
822*333d2b36SAndroid Build Coastguard Worker
823*333d2b36SAndroid Build Coastguard Worker		// Add native modules targeting both ABIs. When multilib.* is omitted for
824*333d2b36SAndroid Build Coastguard Worker		// native_shared_libs/jni_libs/tests, it implies multilib.both
825*333d2b36SAndroid Build Coastguard Worker		deps.Merge(ctx, a.properties.Multilib.Both)
826*333d2b36SAndroid Build Coastguard Worker		deps.Merge(ctx, ApexNativeDependencies{
827*333d2b36SAndroid Build Coastguard Worker			Native_shared_libs: a.properties.Native_shared_libs,
828*333d2b36SAndroid Build Coastguard Worker			Rust_dyn_libs:      a.properties.Rust_dyn_libs,
829*333d2b36SAndroid Build Coastguard Worker			Tests:              a.properties.Tests,
830*333d2b36SAndroid Build Coastguard Worker			Jni_libs:           a.properties.Jni_libs,
831*333d2b36SAndroid Build Coastguard Worker		})
832*333d2b36SAndroid Build Coastguard Worker
833*333d2b36SAndroid Build Coastguard Worker		// Add native modules targeting the first ABI When multilib.* is omitted for
834*333d2b36SAndroid Build Coastguard Worker		// binaries, it implies multilib.first
835*333d2b36SAndroid Build Coastguard Worker		isPrimaryAbi := i == 0
836*333d2b36SAndroid Build Coastguard Worker		if isPrimaryAbi {
837*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.properties.Multilib.First)
838*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, ApexNativeDependencies{
839*333d2b36SAndroid Build Coastguard Worker				Native_shared_libs: proptools.NewConfigurable[[]string](nil, nil),
840*333d2b36SAndroid Build Coastguard Worker				Tests:              nil,
841*333d2b36SAndroid Build Coastguard Worker				Jni_libs:           proptools.NewConfigurable[[]string](nil, nil),
842*333d2b36SAndroid Build Coastguard Worker				Binaries:           a.properties.Binaries,
843*333d2b36SAndroid Build Coastguard Worker			})
844*333d2b36SAndroid Build Coastguard Worker		}
845*333d2b36SAndroid Build Coastguard Worker
846*333d2b36SAndroid Build Coastguard Worker		// Add native modules targeting either 32-bit or 64-bit ABI
847*333d2b36SAndroid Build Coastguard Worker		switch target.Arch.ArchType.Multilib {
848*333d2b36SAndroid Build Coastguard Worker		case "lib32":
849*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.properties.Multilib.Lib32)
850*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.properties.Multilib.Prefer32)
851*333d2b36SAndroid Build Coastguard Worker		case "lib64":
852*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.properties.Multilib.Lib64)
853*333d2b36SAndroid Build Coastguard Worker			if !has32BitTarget {
854*333d2b36SAndroid Build Coastguard Worker				deps.Merge(ctx, a.properties.Multilib.Prefer32)
855*333d2b36SAndroid Build Coastguard Worker			}
856*333d2b36SAndroid Build Coastguard Worker		}
857*333d2b36SAndroid Build Coastguard Worker
858*333d2b36SAndroid Build Coastguard Worker		// Add native modules targeting a specific arch variant
859*333d2b36SAndroid Build Coastguard Worker		switch target.Arch.ArchType {
860*333d2b36SAndroid Build Coastguard Worker		case android.Arm:
861*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.archProperties.Arch.Arm.ApexNativeDependencies)
862*333d2b36SAndroid Build Coastguard Worker		case android.Arm64:
863*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.archProperties.Arch.Arm64.ApexNativeDependencies)
864*333d2b36SAndroid Build Coastguard Worker		case android.Riscv64:
865*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
866*333d2b36SAndroid Build Coastguard Worker		case android.X86:
867*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.archProperties.Arch.X86.ApexNativeDependencies)
868*333d2b36SAndroid Build Coastguard Worker		case android.X86_64:
869*333d2b36SAndroid Build Coastguard Worker			deps.Merge(ctx, a.archProperties.Arch.X86_64.ApexNativeDependencies)
870*333d2b36SAndroid Build Coastguard Worker		default:
871*333d2b36SAndroid Build Coastguard Worker			panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
872*333d2b36SAndroid Build Coastguard Worker		}
873*333d2b36SAndroid Build Coastguard Worker
874*333d2b36SAndroid Build Coastguard Worker		addDependenciesForNativeModules(ctx, deps, target, imageVariation)
875*333d2b36SAndroid Build Coastguard Worker		if isPrimaryAbi {
876*333d2b36SAndroid Build Coastguard Worker			ctx.AddFarVariationDependencies([]blueprint.Variation{
877*333d2b36SAndroid Build Coastguard Worker				{Mutator: "os", Variation: target.OsVariation()},
878*333d2b36SAndroid Build Coastguard Worker				{Mutator: "arch", Variation: target.ArchVariation()},
879*333d2b36SAndroid Build Coastguard Worker			}, shBinaryTag, a.properties.Sh_binaries...)
880*333d2b36SAndroid Build Coastguard Worker		}
881*333d2b36SAndroid Build Coastguard Worker	}
882*333d2b36SAndroid Build Coastguard Worker
883*333d2b36SAndroid Build Coastguard Worker	// Common-arch dependencies come next
884*333d2b36SAndroid Build Coastguard Worker	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
885*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...)
886*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments.GetOrDefault(ctx, nil)...)
887*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments.GetOrDefault(ctx, nil)...)
888*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
889*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
890*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
891*333d2b36SAndroid Build Coastguard Worker}
892*333d2b36SAndroid Build Coastguard Worker
893*333d2b36SAndroid Build Coastguard Worker// DepsMutator for the overridden properties.
894*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
895*333d2b36SAndroid Build Coastguard Worker	if a.overridableProperties.Allowed_files != nil {
896*333d2b36SAndroid Build Coastguard Worker		android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
897*333d2b36SAndroid Build Coastguard Worker	}
898*333d2b36SAndroid Build Coastguard Worker
899*333d2b36SAndroid Build Coastguard Worker	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
900*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps.GetOrDefault(ctx, nil)...)
901*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
902*333d2b36SAndroid Build Coastguard Worker	if prebuilts := a.overridableProperties.Prebuilts.GetOrDefault(ctx, nil); len(prebuilts) > 0 {
903*333d2b36SAndroid Build Coastguard Worker		// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
904*333d2b36SAndroid Build Coastguard Worker		// regardless of the TARGET_PREFER_* setting. See b/144532908
905*333d2b36SAndroid Build Coastguard Worker		arches := ctx.DeviceConfig().Arches()
906*333d2b36SAndroid Build Coastguard Worker		if len(arches) != 0 {
907*333d2b36SAndroid Build Coastguard Worker			archForPrebuiltEtc := arches[0]
908*333d2b36SAndroid Build Coastguard Worker			for _, arch := range arches {
909*333d2b36SAndroid Build Coastguard Worker				// Prefer 64-bit arch if there is any
910*333d2b36SAndroid Build Coastguard Worker				if arch.ArchType.Multilib == "lib64" {
911*333d2b36SAndroid Build Coastguard Worker					archForPrebuiltEtc = arch
912*333d2b36SAndroid Build Coastguard Worker					break
913*333d2b36SAndroid Build Coastguard Worker				}
914*333d2b36SAndroid Build Coastguard Worker			}
915*333d2b36SAndroid Build Coastguard Worker			ctx.AddFarVariationDependencies([]blueprint.Variation{
916*333d2b36SAndroid Build Coastguard Worker				{Mutator: "os", Variation: ctx.Os().String()},
917*333d2b36SAndroid Build Coastguard Worker				{Mutator: "arch", Variation: archForPrebuiltEtc.String()},
918*333d2b36SAndroid Build Coastguard Worker			}, prebuiltTag, prebuilts...)
919*333d2b36SAndroid Build Coastguard Worker		}
920*333d2b36SAndroid Build Coastguard Worker	}
921*333d2b36SAndroid Build Coastguard Worker
922*333d2b36SAndroid Build Coastguard Worker	// Dependencies for signing
923*333d2b36SAndroid Build Coastguard Worker	if String(a.overridableProperties.Key) == "" {
924*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("key", "missing")
925*333d2b36SAndroid Build Coastguard Worker		return
926*333d2b36SAndroid Build Coastguard Worker	}
927*333d2b36SAndroid Build Coastguard Worker	ctx.AddDependency(ctx.Module(), keyTag, String(a.overridableProperties.Key))
928*333d2b36SAndroid Build Coastguard Worker
929*333d2b36SAndroid Build Coastguard Worker	cert := android.SrcIsModule(a.getCertString(ctx))
930*333d2b36SAndroid Build Coastguard Worker	if cert != "" {
931*333d2b36SAndroid Build Coastguard Worker		ctx.AddDependency(ctx.Module(), certificateTag, cert)
932*333d2b36SAndroid Build Coastguard Worker		// empty cert is not an error. Cert and private keys will be directly found under
933*333d2b36SAndroid Build Coastguard Worker		// PRODUCT_DEFAULT_DEV_CERTIFICATE
934*333d2b36SAndroid Build Coastguard Worker	}
935*333d2b36SAndroid Build Coastguard Worker}
936*333d2b36SAndroid Build Coastguard Worker
937*333d2b36SAndroid Build Coastguard Workervar _ ApexInfoMutator = (*apexBundle)(nil)
938*333d2b36SAndroid Build Coastguard Worker
939*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) ApexVariationName() string {
940*333d2b36SAndroid Build Coastguard Worker	return a.properties.ApexVariationName
941*333d2b36SAndroid Build Coastguard Worker}
942*333d2b36SAndroid Build Coastguard Worker
943*333d2b36SAndroid Build Coastguard Worker// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
944*333d2b36SAndroid Build Coastguard Worker// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
945*333d2b36SAndroid Build Coastguard Worker// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
946*333d2b36SAndroid Build Coastguard Worker// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended
947*333d2b36SAndroid Build Coastguard Worker// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles.
948*333d2b36SAndroid Build Coastguard Worker//
949*333d2b36SAndroid Build Coastguard Worker// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex
950*333d2b36SAndroid Build Coastguard Worker// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list.
951*333d2b36SAndroid Build Coastguard Worker// The apexMutator uses that list to create module variants for the apexes to which it belongs.
952*333d2b36SAndroid Build Coastguard Worker// The relationship between module variants and apexes is not one-to-one as variants will be
953*333d2b36SAndroid Build Coastguard Worker// shared between compatible apexes.
954*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
955*333d2b36SAndroid Build Coastguard Worker
956*333d2b36SAndroid Build Coastguard Worker	// The VNDK APEX is special. For the APEX, the membership is described in a very different
957*333d2b36SAndroid Build Coastguard Worker	// way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK
958*333d2b36SAndroid Build Coastguard Worker	// libraries are self-identified by their vndk.enabled properties. There is no need to run
959*333d2b36SAndroid Build Coastguard Worker	// this mutator for the APEX as nothing will be collected. So, let's return fast.
960*333d2b36SAndroid Build Coastguard Worker	if a.vndkApex {
961*333d2b36SAndroid Build Coastguard Worker		return
962*333d2b36SAndroid Build Coastguard Worker	}
963*333d2b36SAndroid Build Coastguard Worker
964*333d2b36SAndroid Build Coastguard Worker	continueApexDepsWalk := func(child, parent android.Module) bool {
965*333d2b36SAndroid Build Coastguard Worker		am, ok := child.(android.ApexModule)
966*333d2b36SAndroid Build Coastguard Worker		if !ok || !am.CanHaveApexVariants() {
967*333d2b36SAndroid Build Coastguard Worker			return false
968*333d2b36SAndroid Build Coastguard Worker		}
969*333d2b36SAndroid Build Coastguard Worker		depTag := mctx.OtherModuleDependencyTag(child)
970*333d2b36SAndroid Build Coastguard Worker
971*333d2b36SAndroid Build Coastguard Worker		// Check to see if the tag always requires that the child module has an apex variant for every
972*333d2b36SAndroid Build Coastguard Worker		// apex variant of the parent module. If it does not then it is still possible for something
973*333d2b36SAndroid Build Coastguard Worker		// else, e.g. the DepIsInSameApex(...) method to decide that a variant is required.
974*333d2b36SAndroid Build Coastguard Worker		if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() {
975*333d2b36SAndroid Build Coastguard Worker			return true
976*333d2b36SAndroid Build Coastguard Worker		}
977*333d2b36SAndroid Build Coastguard Worker		if !android.IsDepInSameApex(mctx, parent, child) {
978*333d2b36SAndroid Build Coastguard Worker			return false
979*333d2b36SAndroid Build Coastguard Worker		}
980*333d2b36SAndroid Build Coastguard Worker
981*333d2b36SAndroid Build Coastguard Worker		// By default, all the transitive dependencies are collected, unless filtered out
982*333d2b36SAndroid Build Coastguard Worker		// above.
983*333d2b36SAndroid Build Coastguard Worker		return true
984*333d2b36SAndroid Build Coastguard Worker	}
985*333d2b36SAndroid Build Coastguard Worker
986*333d2b36SAndroid Build Coastguard Worker	android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{})
987*333d2b36SAndroid Build Coastguard Worker
988*333d2b36SAndroid Build Coastguard Worker	minSdkVersion := a.minSdkVersion(mctx)
989*333d2b36SAndroid Build Coastguard Worker	// When min_sdk_version is not set, the apex is built against FutureApiLevel.
990*333d2b36SAndroid Build Coastguard Worker	if minSdkVersion.IsNone() {
991*333d2b36SAndroid Build Coastguard Worker		minSdkVersion = android.FutureApiLevel
992*333d2b36SAndroid Build Coastguard Worker	}
993*333d2b36SAndroid Build Coastguard Worker
994*333d2b36SAndroid Build Coastguard Worker	// This is the main part of this mutator. Mark the collected dependencies that they need to
995*333d2b36SAndroid Build Coastguard Worker	// be built for this apexBundle.
996*333d2b36SAndroid Build Coastguard Worker
997*333d2b36SAndroid Build Coastguard Worker	apexVariationName := mctx.ModuleName() // could be com.android.foo
998*333d2b36SAndroid Build Coastguard Worker	if overridable, ok := mctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" {
999*333d2b36SAndroid Build Coastguard Worker		// use the overridden name com.mycompany.android.foo
1000*333d2b36SAndroid Build Coastguard Worker		apexVariationName = overridable.GetOverriddenBy()
1001*333d2b36SAndroid Build Coastguard Worker	}
1002*333d2b36SAndroid Build Coastguard Worker
1003*333d2b36SAndroid Build Coastguard Worker	a.properties.ApexVariationName = apexVariationName
1004*333d2b36SAndroid Build Coastguard Worker	testApexes := []string{}
1005*333d2b36SAndroid Build Coastguard Worker	if a.testApex {
1006*333d2b36SAndroid Build Coastguard Worker		testApexes = []string{apexVariationName}
1007*333d2b36SAndroid Build Coastguard Worker	}
1008*333d2b36SAndroid Build Coastguard Worker	apexInfo := android.ApexInfo{
1009*333d2b36SAndroid Build Coastguard Worker		ApexVariationName: apexVariationName,
1010*333d2b36SAndroid Build Coastguard Worker		MinSdkVersion:     minSdkVersion,
1011*333d2b36SAndroid Build Coastguard Worker		Updatable:         a.Updatable(),
1012*333d2b36SAndroid Build Coastguard Worker		UsePlatformApis:   a.UsePlatformApis(),
1013*333d2b36SAndroid Build Coastguard Worker		InApexVariants:    []string{apexVariationName},
1014*333d2b36SAndroid Build Coastguard Worker		TestApexes:        testApexes,
1015*333d2b36SAndroid Build Coastguard Worker		BaseApexName:      mctx.ModuleName(),
1016*333d2b36SAndroid Build Coastguard Worker		ApexAvailableName: proptools.String(a.properties.Apex_available_name),
1017*333d2b36SAndroid Build Coastguard Worker	}
1018*333d2b36SAndroid Build Coastguard Worker	mctx.WalkDeps(func(child, parent android.Module) bool {
1019*333d2b36SAndroid Build Coastguard Worker		if !continueApexDepsWalk(child, parent) {
1020*333d2b36SAndroid Build Coastguard Worker			return false
1021*333d2b36SAndroid Build Coastguard Worker		}
1022*333d2b36SAndroid Build Coastguard Worker		child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark!
1023*333d2b36SAndroid Build Coastguard Worker		return true
1024*333d2b36SAndroid Build Coastguard Worker	})
1025*333d2b36SAndroid Build Coastguard Worker}
1026*333d2b36SAndroid Build Coastguard Worker
1027*333d2b36SAndroid Build Coastguard Workertype ApexInfoMutator interface {
1028*333d2b36SAndroid Build Coastguard Worker	// ApexVariationName returns the name of the APEX variation to use in the apex
1029*333d2b36SAndroid Build Coastguard Worker	// mutator etc. It is the same name as ApexInfo.ApexVariationName.
1030*333d2b36SAndroid Build Coastguard Worker	ApexVariationName() string
1031*333d2b36SAndroid Build Coastguard Worker
1032*333d2b36SAndroid Build Coastguard Worker	// ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
1033*333d2b36SAndroid Build Coastguard Worker	// depended upon by an apex and which require an apex specific variant.
1034*333d2b36SAndroid Build Coastguard Worker	ApexInfoMutator(android.TopDownMutatorContext)
1035*333d2b36SAndroid Build Coastguard Worker}
1036*333d2b36SAndroid Build Coastguard Worker
1037*333d2b36SAndroid Build Coastguard Worker// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex
1038*333d2b36SAndroid Build Coastguard Worker// specific variant to modules that support the ApexInfoMutator.
1039*333d2b36SAndroid Build Coastguard Worker// It also propagates updatable=true to apps of updatable apexes
1040*333d2b36SAndroid Build Coastguard Workerfunc apexInfoMutator(mctx android.TopDownMutatorContext) {
1041*333d2b36SAndroid Build Coastguard Worker	if !mctx.Module().Enabled(mctx) {
1042*333d2b36SAndroid Build Coastguard Worker		return
1043*333d2b36SAndroid Build Coastguard Worker	}
1044*333d2b36SAndroid Build Coastguard Worker
1045*333d2b36SAndroid Build Coastguard Worker	if a, ok := mctx.Module().(ApexInfoMutator); ok {
1046*333d2b36SAndroid Build Coastguard Worker		a.ApexInfoMutator(mctx)
1047*333d2b36SAndroid Build Coastguard Worker	}
1048*333d2b36SAndroid Build Coastguard Worker
1049*333d2b36SAndroid Build Coastguard Worker	if am, ok := mctx.Module().(android.ApexModule); ok {
1050*333d2b36SAndroid Build Coastguard Worker		android.ApexInfoMutator(mctx, am)
1051*333d2b36SAndroid Build Coastguard Worker	}
1052*333d2b36SAndroid Build Coastguard Worker}
1053*333d2b36SAndroid Build Coastguard Worker
1054*333d2b36SAndroid Build Coastguard Worker// TODO: b/215736885 Whittle the denylist
1055*333d2b36SAndroid Build Coastguard Worker// Transitive deps of certain mainline modules baseline NewApi errors
1056*333d2b36SAndroid Build Coastguard Worker// Skip these mainline modules for now
1057*333d2b36SAndroid Build Coastguard Workervar (
1058*333d2b36SAndroid Build Coastguard Worker	skipStrictUpdatabilityLintAllowlist = []string{
1059*333d2b36SAndroid Build Coastguard Worker		// go/keep-sorted start
1060*333d2b36SAndroid Build Coastguard Worker		"PackageManagerTestApex",
1061*333d2b36SAndroid Build Coastguard Worker		"com.android.adservices",
1062*333d2b36SAndroid Build Coastguard Worker		"com.android.appsearch",
1063*333d2b36SAndroid Build Coastguard Worker		"com.android.art",
1064*333d2b36SAndroid Build Coastguard Worker		"com.android.art.debug",
1065*333d2b36SAndroid Build Coastguard Worker		"com.android.btservices",
1066*333d2b36SAndroid Build Coastguard Worker		"com.android.cellbroadcast",
1067*333d2b36SAndroid Build Coastguard Worker		"com.android.configinfrastructure",
1068*333d2b36SAndroid Build Coastguard Worker		"com.android.conscrypt",
1069*333d2b36SAndroid Build Coastguard Worker		"com.android.extservices",
1070*333d2b36SAndroid Build Coastguard Worker		"com.android.extservices_tplus",
1071*333d2b36SAndroid Build Coastguard Worker		"com.android.healthfitness",
1072*333d2b36SAndroid Build Coastguard Worker		"com.android.ipsec",
1073*333d2b36SAndroid Build Coastguard Worker		"com.android.media",
1074*333d2b36SAndroid Build Coastguard Worker		"com.android.mediaprovider",
1075*333d2b36SAndroid Build Coastguard Worker		"com.android.ondevicepersonalization",
1076*333d2b36SAndroid Build Coastguard Worker		"com.android.os.statsd",
1077*333d2b36SAndroid Build Coastguard Worker		"com.android.permission",
1078*333d2b36SAndroid Build Coastguard Worker		"com.android.profiling",
1079*333d2b36SAndroid Build Coastguard Worker		"com.android.rkpd",
1080*333d2b36SAndroid Build Coastguard Worker		"com.android.scheduling",
1081*333d2b36SAndroid Build Coastguard Worker		"com.android.tethering",
1082*333d2b36SAndroid Build Coastguard Worker		"com.android.uwb",
1083*333d2b36SAndroid Build Coastguard Worker		"com.android.wifi",
1084*333d2b36SAndroid Build Coastguard Worker		"test_com.android.art",
1085*333d2b36SAndroid Build Coastguard Worker		"test_com.android.cellbroadcast",
1086*333d2b36SAndroid Build Coastguard Worker		"test_com.android.conscrypt",
1087*333d2b36SAndroid Build Coastguard Worker		"test_com.android.extservices",
1088*333d2b36SAndroid Build Coastguard Worker		"test_com.android.ipsec",
1089*333d2b36SAndroid Build Coastguard Worker		"test_com.android.media",
1090*333d2b36SAndroid Build Coastguard Worker		"test_com.android.mediaprovider",
1091*333d2b36SAndroid Build Coastguard Worker		"test_com.android.os.statsd",
1092*333d2b36SAndroid Build Coastguard Worker		"test_com.android.permission",
1093*333d2b36SAndroid Build Coastguard Worker		"test_com.android.wifi",
1094*333d2b36SAndroid Build Coastguard Worker		"test_imgdiag_com.android.art",
1095*333d2b36SAndroid Build Coastguard Worker		"test_jitzygote_com.android.art",
1096*333d2b36SAndroid Build Coastguard Worker		// go/keep-sorted end
1097*333d2b36SAndroid Build Coastguard Worker	}
1098*333d2b36SAndroid Build Coastguard Worker)
1099*333d2b36SAndroid Build Coastguard Worker
1100*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) checkStrictUpdatabilityLinting(mctx android.ModuleContext) bool {
1101*333d2b36SAndroid Build Coastguard Worker	// The allowlist contains the base apex name, so use that instead of the ApexVariationName
1102*333d2b36SAndroid Build Coastguard Worker	return a.Updatable() && !android.InList(mctx.ModuleName(), skipStrictUpdatabilityLintAllowlist)
1103*333d2b36SAndroid Build Coastguard Worker}
1104*333d2b36SAndroid Build Coastguard Worker
1105*333d2b36SAndroid Build Coastguard Worker// apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
1106*333d2b36SAndroid Build Coastguard Worker// unique apex variations for this module. See android/apex.go for more about unique apex variant.
1107*333d2b36SAndroid Build Coastguard Worker// TODO(jiyong): move this to android/apex.go?
1108*333d2b36SAndroid Build Coastguard Workerfunc apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
1109*333d2b36SAndroid Build Coastguard Worker	if !mctx.Module().Enabled(mctx) {
1110*333d2b36SAndroid Build Coastguard Worker		return
1111*333d2b36SAndroid Build Coastguard Worker	}
1112*333d2b36SAndroid Build Coastguard Worker	if am, ok := mctx.Module().(android.ApexModule); ok {
1113*333d2b36SAndroid Build Coastguard Worker		android.UpdateUniqueApexVariationsForDeps(mctx, am)
1114*333d2b36SAndroid Build Coastguard Worker	}
1115*333d2b36SAndroid Build Coastguard Worker}
1116*333d2b36SAndroid Build Coastguard Worker
1117*333d2b36SAndroid Build Coastguard Worker// markPlatformAvailability marks whether or not a module can be available to platform. A module
1118*333d2b36SAndroid Build Coastguard Worker// cannot be available to platform if 1) it is explicitly marked as not available (i.e.
1119*333d2b36SAndroid Build Coastguard Worker// "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't
1120*333d2b36SAndroid Build Coastguard Worker// be) available to platform
1121*333d2b36SAndroid Build Coastguard Worker// TODO(jiyong): move this to android/apex.go?
1122*333d2b36SAndroid Build Coastguard Workerfunc markPlatformAvailability(mctx android.BottomUpMutatorContext) {
1123*333d2b36SAndroid Build Coastguard Worker	// Recovery is not considered as platform
1124*333d2b36SAndroid Build Coastguard Worker	if mctx.Module().InstallInRecovery() {
1125*333d2b36SAndroid Build Coastguard Worker		return
1126*333d2b36SAndroid Build Coastguard Worker	}
1127*333d2b36SAndroid Build Coastguard Worker
1128*333d2b36SAndroid Build Coastguard Worker	am, ok := mctx.Module().(android.ApexModule)
1129*333d2b36SAndroid Build Coastguard Worker	if !ok {
1130*333d2b36SAndroid Build Coastguard Worker		return
1131*333d2b36SAndroid Build Coastguard Worker	}
1132*333d2b36SAndroid Build Coastguard Worker
1133*333d2b36SAndroid Build Coastguard Worker	availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
1134*333d2b36SAndroid Build Coastguard Worker
1135*333d2b36SAndroid Build Coastguard Worker	// If any of the dep is not available to platform, this module is also considered as being
1136*333d2b36SAndroid Build Coastguard Worker	// not available to platform even if it has "//apex_available:platform"
1137*333d2b36SAndroid Build Coastguard Worker	mctx.VisitDirectDeps(func(child android.Module) {
1138*333d2b36SAndroid Build Coastguard Worker		if !android.IsDepInSameApex(mctx, am, child) {
1139*333d2b36SAndroid Build Coastguard Worker			// if the dependency crosses apex boundary, don't consider it
1140*333d2b36SAndroid Build Coastguard Worker			return
1141*333d2b36SAndroid Build Coastguard Worker		}
1142*333d2b36SAndroid Build Coastguard Worker		if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
1143*333d2b36SAndroid Build Coastguard Worker			availableToPlatform = false
1144*333d2b36SAndroid Build Coastguard Worker			// TODO(b/154889534) trigger an error when 'am' has
1145*333d2b36SAndroid Build Coastguard Worker			// "//apex_available:platform"
1146*333d2b36SAndroid Build Coastguard Worker		}
1147*333d2b36SAndroid Build Coastguard Worker	})
1148*333d2b36SAndroid Build Coastguard Worker
1149*333d2b36SAndroid Build Coastguard Worker	// Exception 1: check to see if the module always requires it.
1150*333d2b36SAndroid Build Coastguard Worker	if am.AlwaysRequiresPlatformApexVariant() {
1151*333d2b36SAndroid Build Coastguard Worker		availableToPlatform = true
1152*333d2b36SAndroid Build Coastguard Worker	}
1153*333d2b36SAndroid Build Coastguard Worker
1154*333d2b36SAndroid Build Coastguard Worker	// Exception 2: bootstrap bionic libraries are also always available to platform
1155*333d2b36SAndroid Build Coastguard Worker	if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
1156*333d2b36SAndroid Build Coastguard Worker		availableToPlatform = true
1157*333d2b36SAndroid Build Coastguard Worker	}
1158*333d2b36SAndroid Build Coastguard Worker
1159*333d2b36SAndroid Build Coastguard Worker	if !availableToPlatform {
1160*333d2b36SAndroid Build Coastguard Worker		am.SetNotAvailableForPlatform()
1161*333d2b36SAndroid Build Coastguard Worker	}
1162*333d2b36SAndroid Build Coastguard Worker}
1163*333d2b36SAndroid Build Coastguard Worker
1164*333d2b36SAndroid Build Coastguard Workertype apexTransitionMutator struct{}
1165*333d2b36SAndroid Build Coastguard Worker
1166*333d2b36SAndroid Build Coastguard Workerfunc (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string {
1167*333d2b36SAndroid Build Coastguard Worker	// apexBundle itself is mutated so that it and its dependencies have the same apex variant.
1168*333d2b36SAndroid Build Coastguard Worker	if ai, ok := ctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
1169*333d2b36SAndroid Build Coastguard Worker		if overridable, ok := ctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" {
1170*333d2b36SAndroid Build Coastguard Worker			return []string{overridable.GetOverriddenBy()}
1171*333d2b36SAndroid Build Coastguard Worker		}
1172*333d2b36SAndroid Build Coastguard Worker		return []string{ai.ApexVariationName()}
1173*333d2b36SAndroid Build Coastguard Worker	} else if _, ok := ctx.Module().(*OverrideApex); ok {
1174*333d2b36SAndroid Build Coastguard Worker		return []string{ctx.ModuleName()}
1175*333d2b36SAndroid Build Coastguard Worker	}
1176*333d2b36SAndroid Build Coastguard Worker	return []string{""}
1177*333d2b36SAndroid Build Coastguard Worker}
1178*333d2b36SAndroid Build Coastguard Worker
1179*333d2b36SAndroid Build Coastguard Workerfunc (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
1180*333d2b36SAndroid Build Coastguard Worker	return sourceVariation
1181*333d2b36SAndroid Build Coastguard Worker}
1182*333d2b36SAndroid Build Coastguard Worker
1183*333d2b36SAndroid Build Coastguard Workerfunc (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
1184*333d2b36SAndroid Build Coastguard Worker	if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
1185*333d2b36SAndroid Build Coastguard Worker		return android.IncomingApexTransition(ctx, incomingVariation)
1186*333d2b36SAndroid Build Coastguard Worker	} else if ai, ok := ctx.Module().(ApexInfoMutator); ok {
1187*333d2b36SAndroid Build Coastguard Worker		if overridable, ok := ctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" {
1188*333d2b36SAndroid Build Coastguard Worker			return overridable.GetOverriddenBy()
1189*333d2b36SAndroid Build Coastguard Worker		}
1190*333d2b36SAndroid Build Coastguard Worker		return ai.ApexVariationName()
1191*333d2b36SAndroid Build Coastguard Worker	} else if _, ok := ctx.Module().(*OverrideApex); ok {
1192*333d2b36SAndroid Build Coastguard Worker		return ctx.Module().Name()
1193*333d2b36SAndroid Build Coastguard Worker	}
1194*333d2b36SAndroid Build Coastguard Worker
1195*333d2b36SAndroid Build Coastguard Worker	return ""
1196*333d2b36SAndroid Build Coastguard Worker}
1197*333d2b36SAndroid Build Coastguard Worker
1198*333d2b36SAndroid Build Coastguard Workerfunc (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
1199*333d2b36SAndroid Build Coastguard Worker	if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
1200*333d2b36SAndroid Build Coastguard Worker		android.MutateApexTransition(ctx, variation)
1201*333d2b36SAndroid Build Coastguard Worker	}
1202*333d2b36SAndroid Build Coastguard Worker}
1203*333d2b36SAndroid Build Coastguard Worker
1204*333d2b36SAndroid Build Coastguard Worker// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
1205*333d2b36SAndroid Build Coastguard Worker// variant.
1206*333d2b36SAndroid Build Coastguard Workerfunc apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
1207*333d2b36SAndroid Build Coastguard Worker	if a, ok := module.(*apexBundle); ok {
1208*333d2b36SAndroid Build Coastguard Worker		// TODO(jiyong): document the reason why the VNDK APEX is an exception here.
1209*333d2b36SAndroid Build Coastguard Worker		return !a.vndkApex
1210*333d2b36SAndroid Build Coastguard Worker	}
1211*333d2b36SAndroid Build Coastguard Worker
1212*333d2b36SAndroid Build Coastguard Worker	return true
1213*333d2b36SAndroid Build Coastguard Worker}
1214*333d2b36SAndroid Build Coastguard Worker
1215*333d2b36SAndroid Build Coastguard Workerconst (
1216*333d2b36SAndroid Build Coastguard Worker	// File extensions of an APEX for different packaging methods
1217*333d2b36SAndroid Build Coastguard Worker	imageApexSuffix  = ".apex"
1218*333d2b36SAndroid Build Coastguard Worker	imageCapexSuffix = ".capex"
1219*333d2b36SAndroid Build Coastguard Worker
1220*333d2b36SAndroid Build Coastguard Worker	// variant names each of which is for a packaging method
1221*333d2b36SAndroid Build Coastguard Worker	imageApexType = "image"
1222*333d2b36SAndroid Build Coastguard Worker
1223*333d2b36SAndroid Build Coastguard Worker	ext4FsType  = "ext4"
1224*333d2b36SAndroid Build Coastguard Worker	f2fsFsType  = "f2fs"
1225*333d2b36SAndroid Build Coastguard Worker	erofsFsType = "erofs"
1226*333d2b36SAndroid Build Coastguard Worker)
1227*333d2b36SAndroid Build Coastguard Worker
1228*333d2b36SAndroid Build Coastguard Workervar _ android.DepIsInSameApex = (*apexBundle)(nil)
1229*333d2b36SAndroid Build Coastguard Worker
1230*333d2b36SAndroid Build Coastguard Worker// Implements android.DepInInSameApex
1231*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
1232*333d2b36SAndroid Build Coastguard Worker	// direct deps of an APEX bundle are all part of the APEX bundle
1233*333d2b36SAndroid Build Coastguard Worker	// TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
1234*333d2b36SAndroid Build Coastguard Worker	return true
1235*333d2b36SAndroid Build Coastguard Worker}
1236*333d2b36SAndroid Build Coastguard Worker
1237*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) Exportable() bool {
1238*333d2b36SAndroid Build Coastguard Worker	return true
1239*333d2b36SAndroid Build Coastguard Worker}
1240*333d2b36SAndroid Build Coastguard Worker
1241*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) TaggedOutputs() map[string]android.Paths {
1242*333d2b36SAndroid Build Coastguard Worker	ret := make(map[string]android.Paths)
1243*333d2b36SAndroid Build Coastguard Worker	ret["apex"] = android.Paths{a.outputFile}
1244*333d2b36SAndroid Build Coastguard Worker	return ret
1245*333d2b36SAndroid Build Coastguard Worker}
1246*333d2b36SAndroid Build Coastguard Worker
1247*333d2b36SAndroid Build Coastguard Workervar _ cc.Coverage = (*apexBundle)(nil)
1248*333d2b36SAndroid Build Coastguard Worker
1249*333d2b36SAndroid Build Coastguard Worker// Implements cc.Coverage
1250*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
1251*333d2b36SAndroid Build Coastguard Worker	return ctx.DeviceConfig().NativeCoverageEnabled()
1252*333d2b36SAndroid Build Coastguard Worker}
1253*333d2b36SAndroid Build Coastguard Worker
1254*333d2b36SAndroid Build Coastguard Worker// Implements cc.Coverage
1255*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) SetPreventInstall() {
1256*333d2b36SAndroid Build Coastguard Worker	a.properties.PreventInstall = true
1257*333d2b36SAndroid Build Coastguard Worker}
1258*333d2b36SAndroid Build Coastguard Worker
1259*333d2b36SAndroid Build Coastguard Worker// Implements cc.Coverage
1260*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) HideFromMake() {
1261*333d2b36SAndroid Build Coastguard Worker	a.properties.HideFromMake = true
1262*333d2b36SAndroid Build Coastguard Worker	// This HideFromMake is shadowing the ModuleBase one, call through to it for now.
1263*333d2b36SAndroid Build Coastguard Worker	// TODO(ccross): untangle these
1264*333d2b36SAndroid Build Coastguard Worker	a.ModuleBase.HideFromMake()
1265*333d2b36SAndroid Build Coastguard Worker}
1266*333d2b36SAndroid Build Coastguard Worker
1267*333d2b36SAndroid Build Coastguard Worker// Implements cc.Coverage
1268*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1269*333d2b36SAndroid Build Coastguard Worker	a.properties.IsCoverageVariant = coverage
1270*333d2b36SAndroid Build Coastguard Worker}
1271*333d2b36SAndroid Build Coastguard Worker
1272*333d2b36SAndroid Build Coastguard Worker// Implements cc.Coverage
1273*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) EnableCoverageIfNeeded() {}
1274*333d2b36SAndroid Build Coastguard Worker
1275*333d2b36SAndroid Build Coastguard Workervar _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1276*333d2b36SAndroid Build Coastguard Worker
1277*333d2b36SAndroid Build Coastguard Worker// Implements android.ApexBundleDepsInfoIntf
1278*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) Updatable() bool {
1279*333d2b36SAndroid Build Coastguard Worker	return proptools.BoolDefault(a.properties.Updatable, true)
1280*333d2b36SAndroid Build Coastguard Worker}
1281*333d2b36SAndroid Build Coastguard Worker
1282*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) FutureUpdatable() bool {
1283*333d2b36SAndroid Build Coastguard Worker	return proptools.BoolDefault(a.properties.Future_updatable, false)
1284*333d2b36SAndroid Build Coastguard Worker}
1285*333d2b36SAndroid Build Coastguard Worker
1286*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) UsePlatformApis() bool {
1287*333d2b36SAndroid Build Coastguard Worker	return proptools.BoolDefault(a.properties.Platform_apis, false)
1288*333d2b36SAndroid Build Coastguard Worker}
1289*333d2b36SAndroid Build Coastguard Worker
1290*333d2b36SAndroid Build Coastguard Workertype apexValidationType int
1291*333d2b36SAndroid Build Coastguard Worker
1292*333d2b36SAndroid Build Coastguard Workerconst (
1293*333d2b36SAndroid Build Coastguard Worker	hostApexVerifier apexValidationType = iota
1294*333d2b36SAndroid Build Coastguard Worker	apexSepolicyTests
1295*333d2b36SAndroid Build Coastguard Worker)
1296*333d2b36SAndroid Build Coastguard Worker
1297*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) skipValidation(validationType apexValidationType) bool {
1298*333d2b36SAndroid Build Coastguard Worker	switch validationType {
1299*333d2b36SAndroid Build Coastguard Worker	case hostApexVerifier:
1300*333d2b36SAndroid Build Coastguard Worker		return proptools.Bool(a.testProperties.Skip_validations.Host_apex_verifier)
1301*333d2b36SAndroid Build Coastguard Worker	case apexSepolicyTests:
1302*333d2b36SAndroid Build Coastguard Worker		return proptools.Bool(a.testProperties.Skip_validations.Apex_sepolicy_tests)
1303*333d2b36SAndroid Build Coastguard Worker	}
1304*333d2b36SAndroid Build Coastguard Worker	panic("Unknown validation type")
1305*333d2b36SAndroid Build Coastguard Worker}
1306*333d2b36SAndroid Build Coastguard Worker
1307*333d2b36SAndroid Build Coastguard Worker// getCertString returns the name of the cert that should be used to sign this APEX. This is
1308*333d2b36SAndroid Build Coastguard Worker// basically from the "certificate" property, but could be overridden by the device config.
1309*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
1310*333d2b36SAndroid Build Coastguard Worker	moduleName := ctx.ModuleName()
1311*333d2b36SAndroid Build Coastguard Worker	// VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the
1312*333d2b36SAndroid Build Coastguard Worker	// OVERRIDE_* list, we check with the pseudo module name to see if its certificate is
1313*333d2b36SAndroid Build Coastguard Worker	// overridden.
1314*333d2b36SAndroid Build Coastguard Worker	if a.vndkApex {
1315*333d2b36SAndroid Build Coastguard Worker		moduleName = vndkApexName
1316*333d2b36SAndroid Build Coastguard Worker	}
1317*333d2b36SAndroid Build Coastguard Worker	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
1318*333d2b36SAndroid Build Coastguard Worker	if overridden {
1319*333d2b36SAndroid Build Coastguard Worker		return ":" + certificate
1320*333d2b36SAndroid Build Coastguard Worker	}
1321*333d2b36SAndroid Build Coastguard Worker	return String(a.overridableProperties.Certificate)
1322*333d2b36SAndroid Build Coastguard Worker}
1323*333d2b36SAndroid Build Coastguard Worker
1324*333d2b36SAndroid Build Coastguard Worker// See the installable property
1325*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) installable() bool {
1326*333d2b36SAndroid Build Coastguard Worker	return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
1327*333d2b36SAndroid Build Coastguard Worker}
1328*333d2b36SAndroid Build Coastguard Worker
1329*333d2b36SAndroid Build Coastguard Worker// See the test_only_unsigned_payload property
1330*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1331*333d2b36SAndroid Build Coastguard Worker	return proptools.Bool(a.properties.Test_only_unsigned_payload)
1332*333d2b36SAndroid Build Coastguard Worker}
1333*333d2b36SAndroid Build Coastguard Worker
1334*333d2b36SAndroid Build Coastguard Worker// See the test_only_force_compression property
1335*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) testOnlyShouldForceCompression() bool {
1336*333d2b36SAndroid Build Coastguard Worker	return proptools.Bool(a.properties.Test_only_force_compression)
1337*333d2b36SAndroid Build Coastguard Worker}
1338*333d2b36SAndroid Build Coastguard Worker
1339*333d2b36SAndroid Build Coastguard Worker// See the dynamic_common_lib_apex property
1340*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) dynamic_common_lib_apex() bool {
1341*333d2b36SAndroid Build Coastguard Worker	return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false)
1342*333d2b36SAndroid Build Coastguard Worker}
1343*333d2b36SAndroid Build Coastguard Worker
1344*333d2b36SAndroid Build Coastguard Worker// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
1345*333d2b36SAndroid Build Coastguard Worker// members) can be sanitized, either forcibly, or by the global configuration. For some of the
1346*333d2b36SAndroid Build Coastguard Worker// sanitizers, extra dependencies can be forcibly added as well.
1347*333d2b36SAndroid Build Coastguard Worker
1348*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) EnableSanitizer(sanitizerName string) {
1349*333d2b36SAndroid Build Coastguard Worker	if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1350*333d2b36SAndroid Build Coastguard Worker		a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1351*333d2b36SAndroid Build Coastguard Worker	}
1352*333d2b36SAndroid Build Coastguard Worker}
1353*333d2b36SAndroid Build Coastguard Worker
1354*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName string) bool {
1355*333d2b36SAndroid Build Coastguard Worker	if android.InList(sanitizerName, a.properties.SanitizerNames) {
1356*333d2b36SAndroid Build Coastguard Worker		return true
1357*333d2b36SAndroid Build Coastguard Worker	}
1358*333d2b36SAndroid Build Coastguard Worker
1359*333d2b36SAndroid Build Coastguard Worker	// Then follow the global setting
1360*333d2b36SAndroid Build Coastguard Worker	var globalSanitizerNames []string
1361*333d2b36SAndroid Build Coastguard Worker	arches := config.SanitizeDeviceArch()
1362*333d2b36SAndroid Build Coastguard Worker	if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
1363*333d2b36SAndroid Build Coastguard Worker		globalSanitizerNames = config.SanitizeDevice()
1364*333d2b36SAndroid Build Coastguard Worker	}
1365*333d2b36SAndroid Build Coastguard Worker	return android.InList(sanitizerName, globalSanitizerNames)
1366*333d2b36SAndroid Build Coastguard Worker}
1367*333d2b36SAndroid Build Coastguard Worker
1368*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
1369*333d2b36SAndroid Build Coastguard Worker	// TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
1370*333d2b36SAndroid Build Coastguard Worker	// Keep only the mechanism here.
1371*333d2b36SAndroid Build Coastguard Worker	if sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
1372*333d2b36SAndroid Build Coastguard Worker		imageVariation := a.getImageVariation()
1373*333d2b36SAndroid Build Coastguard Worker		for _, target := range ctx.MultiTargets() {
1374*333d2b36SAndroid Build Coastguard Worker			if target.Arch.ArchType.Multilib == "lib64" {
1375*333d2b36SAndroid Build Coastguard Worker				addDependenciesForNativeModules(ctx, ResolvedApexNativeDependencies{
1376*333d2b36SAndroid Build Coastguard Worker					Native_shared_libs: []string{"libclang_rt.hwasan"},
1377*333d2b36SAndroid Build Coastguard Worker					Tests:              nil,
1378*333d2b36SAndroid Build Coastguard Worker					Jni_libs:           nil,
1379*333d2b36SAndroid Build Coastguard Worker				}, target, imageVariation)
1380*333d2b36SAndroid Build Coastguard Worker				break
1381*333d2b36SAndroid Build Coastguard Worker			}
1382*333d2b36SAndroid Build Coastguard Worker		}
1383*333d2b36SAndroid Build Coastguard Worker	}
1384*333d2b36SAndroid Build Coastguard Worker}
1385*333d2b36SAndroid Build Coastguard Worker
1386*333d2b36SAndroid Build Coastguard Worker// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
1387*333d2b36SAndroid Build Coastguard Worker// returned apexFile saves information about the Soong module that will be used for creating the
1388*333d2b36SAndroid Build Coastguard Worker// build rules.
1389*333d2b36SAndroid Build Coastguard Workerfunc apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
1390*333d2b36SAndroid Build Coastguard Worker	// Decide the APEX-local directory by the multilib of the library In the future, we may
1391*333d2b36SAndroid Build Coastguard Worker	// query this to the module.
1392*333d2b36SAndroid Build Coastguard Worker	// TODO(jiyong): use the new PackagingSpec
1393*333d2b36SAndroid Build Coastguard Worker	var dirInApex string
1394*333d2b36SAndroid Build Coastguard Worker	switch ccMod.Arch().ArchType.Multilib {
1395*333d2b36SAndroid Build Coastguard Worker	case "lib32":
1396*333d2b36SAndroid Build Coastguard Worker		dirInApex = "lib"
1397*333d2b36SAndroid Build Coastguard Worker	case "lib64":
1398*333d2b36SAndroid Build Coastguard Worker		dirInApex = "lib64"
1399*333d2b36SAndroid Build Coastguard Worker	}
1400*333d2b36SAndroid Build Coastguard Worker	if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
1401*333d2b36SAndroid Build Coastguard Worker		dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
1402*333d2b36SAndroid Build Coastguard Worker	}
1403*333d2b36SAndroid Build Coastguard Worker	if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
1404*333d2b36SAndroid Build Coastguard Worker		// Special case for Bionic libs and other libs installed with them. This is to
1405*333d2b36SAndroid Build Coastguard Worker		// prevent those libs from being included in the search path
1406*333d2b36SAndroid Build Coastguard Worker		// /apex/com.android.runtime/${LIB}. This exclusion is required because those libs
1407*333d2b36SAndroid Build Coastguard Worker		// in the Runtime APEX are available via the legacy paths in /system/lib/. By the
1408*333d2b36SAndroid Build Coastguard Worker		// init process, the libs in the APEX are bind-mounted to the legacy paths and thus
1409*333d2b36SAndroid Build Coastguard Worker		// will be loaded into the default linker namespace (aka "platform" namespace). If
1410*333d2b36SAndroid Build Coastguard Worker		// the libs are directly in /apex/com.android.runtime/${LIB} then the same libs will
1411*333d2b36SAndroid Build Coastguard Worker		// be loaded again into the runtime linker namespace, which will result in double
1412*333d2b36SAndroid Build Coastguard Worker		// loading of them, which isn't supported.
1413*333d2b36SAndroid Build Coastguard Worker		dirInApex = filepath.Join(dirInApex, "bionic")
1414*333d2b36SAndroid Build Coastguard Worker	}
1415*333d2b36SAndroid Build Coastguard Worker	// This needs to go after the runtime APEX handling because otherwise we would get
1416*333d2b36SAndroid Build Coastguard Worker	// weird paths like lib64/rel_install_path/bionic rather than
1417*333d2b36SAndroid Build Coastguard Worker	// lib64/bionic/rel_install_path.
1418*333d2b36SAndroid Build Coastguard Worker	dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
1419*333d2b36SAndroid Build Coastguard Worker
1420*333d2b36SAndroid Build Coastguard Worker	fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
1421*333d2b36SAndroid Build Coastguard Worker	androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1422*333d2b36SAndroid Build Coastguard Worker	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
1423*333d2b36SAndroid Build Coastguard Worker}
1424*333d2b36SAndroid Build Coastguard Worker
1425*333d2b36SAndroid Build Coastguard Workerfunc apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
1426*333d2b36SAndroid Build Coastguard Worker	dirInApex := "bin"
1427*333d2b36SAndroid Build Coastguard Worker	if cc.Target().NativeBridge == android.NativeBridgeEnabled {
1428*333d2b36SAndroid Build Coastguard Worker		dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
1429*333d2b36SAndroid Build Coastguard Worker	}
1430*333d2b36SAndroid Build Coastguard Worker	dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
1431*333d2b36SAndroid Build Coastguard Worker	fileToCopy := android.OutputFileForModule(ctx, cc, "")
1432*333d2b36SAndroid Build Coastguard Worker	androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1433*333d2b36SAndroid Build Coastguard Worker	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
1434*333d2b36SAndroid Build Coastguard Worker	af.symlinks = cc.Symlinks()
1435*333d2b36SAndroid Build Coastguard Worker	af.dataPaths = cc.DataPaths()
1436*333d2b36SAndroid Build Coastguard Worker	return af
1437*333d2b36SAndroid Build Coastguard Worker}
1438*333d2b36SAndroid Build Coastguard Worker
1439*333d2b36SAndroid Build Coastguard Workerfunc apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1440*333d2b36SAndroid Build Coastguard Worker	dirInApex := "bin"
1441*333d2b36SAndroid Build Coastguard Worker	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1442*333d2b36SAndroid Build Coastguard Worker		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1443*333d2b36SAndroid Build Coastguard Worker	}
1444*333d2b36SAndroid Build Coastguard Worker	dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
1445*333d2b36SAndroid Build Coastguard Worker	fileToCopy := android.OutputFileForModule(ctx, rustm, "")
1446*333d2b36SAndroid Build Coastguard Worker	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1447*333d2b36SAndroid Build Coastguard Worker	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
1448*333d2b36SAndroid Build Coastguard Worker	return af
1449*333d2b36SAndroid Build Coastguard Worker}
1450*333d2b36SAndroid Build Coastguard Worker
1451*333d2b36SAndroid Build Coastguard Workerfunc apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
1452*333d2b36SAndroid Build Coastguard Worker	// Decide the APEX-local directory by the multilib of the library
1453*333d2b36SAndroid Build Coastguard Worker	// In the future, we may query this to the module.
1454*333d2b36SAndroid Build Coastguard Worker	var dirInApex string
1455*333d2b36SAndroid Build Coastguard Worker	switch rustm.Arch().ArchType.Multilib {
1456*333d2b36SAndroid Build Coastguard Worker	case "lib32":
1457*333d2b36SAndroid Build Coastguard Worker		dirInApex = "lib"
1458*333d2b36SAndroid Build Coastguard Worker	case "lib64":
1459*333d2b36SAndroid Build Coastguard Worker		dirInApex = "lib64"
1460*333d2b36SAndroid Build Coastguard Worker	}
1461*333d2b36SAndroid Build Coastguard Worker	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
1462*333d2b36SAndroid Build Coastguard Worker		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
1463*333d2b36SAndroid Build Coastguard Worker	}
1464*333d2b36SAndroid Build Coastguard Worker	dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
1465*333d2b36SAndroid Build Coastguard Worker	fileToCopy := android.OutputFileForModule(ctx, rustm, "")
1466*333d2b36SAndroid Build Coastguard Worker	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
1467*333d2b36SAndroid Build Coastguard Worker	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
1468*333d2b36SAndroid Build Coastguard Worker}
1469*333d2b36SAndroid Build Coastguard Worker
1470*333d2b36SAndroid Build Coastguard Workerfunc apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
1471*333d2b36SAndroid Build Coastguard Worker	dirInApex := filepath.Join("bin", sh.SubDir())
1472*333d2b36SAndroid Build Coastguard Worker	if sh.Target().NativeBridge == android.NativeBridgeEnabled {
1473*333d2b36SAndroid Build Coastguard Worker		dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
1474*333d2b36SAndroid Build Coastguard Worker	}
1475*333d2b36SAndroid Build Coastguard Worker	fileToCopy := sh.OutputFile()
1476*333d2b36SAndroid Build Coastguard Worker	af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
1477*333d2b36SAndroid Build Coastguard Worker	af.symlinks = sh.Symlinks()
1478*333d2b36SAndroid Build Coastguard Worker	return af
1479*333d2b36SAndroid Build Coastguard Worker}
1480*333d2b36SAndroid Build Coastguard Worker
1481*333d2b36SAndroid Build Coastguard Workerfunc apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, outputFile android.Path) apexFile {
1482*333d2b36SAndroid Build Coastguard Worker	dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
1483*333d2b36SAndroid Build Coastguard Worker	makeModuleName := strings.ReplaceAll(filepath.Join(dirInApex, outputFile.Base()), "/", "_")
1484*333d2b36SAndroid Build Coastguard Worker	return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, prebuilt)
1485*333d2b36SAndroid Build Coastguard Worker}
1486*333d2b36SAndroid Build Coastguard Worker
1487*333d2b36SAndroid Build Coastguard Workerfunc apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1488*333d2b36SAndroid Build Coastguard Worker	dirInApex := filepath.Join("etc", config.SubDir())
1489*333d2b36SAndroid Build Coastguard Worker	fileToCopy := config.CompatConfig()
1490*333d2b36SAndroid Build Coastguard Worker	return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1491*333d2b36SAndroid Build Coastguard Worker}
1492*333d2b36SAndroid Build Coastguard Worker
1493*333d2b36SAndroid Build Coastguard Worker// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
1494*333d2b36SAndroid Build Coastguard Worker// way.
1495*333d2b36SAndroid Build Coastguard Workertype javaModule interface {
1496*333d2b36SAndroid Build Coastguard Worker	android.Module
1497*333d2b36SAndroid Build Coastguard Worker	BaseModuleName() string
1498*333d2b36SAndroid Build Coastguard Worker	DexJarBuildPath(ctx android.ModuleErrorfContext) java.OptionalDexJarPath
1499*333d2b36SAndroid Build Coastguard Worker	JacocoReportClassesFile() android.Path
1500*333d2b36SAndroid Build Coastguard Worker	Stem() string
1501*333d2b36SAndroid Build Coastguard Worker}
1502*333d2b36SAndroid Build Coastguard Worker
1503*333d2b36SAndroid Build Coastguard Workervar _ javaModule = (*java.Library)(nil)
1504*333d2b36SAndroid Build Coastguard Workervar _ javaModule = (*java.Import)(nil)
1505*333d2b36SAndroid Build Coastguard Workervar _ javaModule = (*java.SdkLibrary)(nil)
1506*333d2b36SAndroid Build Coastguard Workervar _ javaModule = (*java.DexImport)(nil)
1507*333d2b36SAndroid Build Coastguard Workervar _ javaModule = (*java.SdkLibraryImport)(nil)
1508*333d2b36SAndroid Build Coastguard Worker
1509*333d2b36SAndroid Build Coastguard Worker// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
1510*333d2b36SAndroid Build Coastguard Workerfunc apexFileForJavaModule(ctx android.ModuleContext, module javaModule) apexFile {
1511*333d2b36SAndroid Build Coastguard Worker	return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath(ctx).PathOrNil())
1512*333d2b36SAndroid Build Coastguard Worker}
1513*333d2b36SAndroid Build Coastguard Worker
1514*333d2b36SAndroid Build Coastguard Worker// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
1515*333d2b36SAndroid Build Coastguard Workerfunc apexFileForJavaModuleWithFile(ctx android.ModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
1516*333d2b36SAndroid Build Coastguard Worker	dirInApex := "javalib"
1517*333d2b36SAndroid Build Coastguard Worker	af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
1518*333d2b36SAndroid Build Coastguard Worker	af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1519*333d2b36SAndroid Build Coastguard Worker	if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok {
1520*333d2b36SAndroid Build Coastguard Worker		af.lintInfo = lintInfo
1521*333d2b36SAndroid Build Coastguard Worker	}
1522*333d2b36SAndroid Build Coastguard Worker	af.customStem = module.Stem() + ".jar"
1523*333d2b36SAndroid Build Coastguard Worker	// TODO: b/338641779 - Remove special casing of sdkLibrary once bcpf and sscpf depends
1524*333d2b36SAndroid Build Coastguard Worker	// on the implementation library
1525*333d2b36SAndroid Build Coastguard Worker	if sdkLib, ok := module.(*java.SdkLibrary); ok {
1526*333d2b36SAndroid Build Coastguard Worker		for _, install := range sdkLib.BuiltInstalledForApex() {
1527*333d2b36SAndroid Build Coastguard Worker			af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1528*333d2b36SAndroid Build Coastguard Worker		}
1529*333d2b36SAndroid Build Coastguard Worker	} else if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1530*333d2b36SAndroid Build Coastguard Worker		for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
1531*333d2b36SAndroid Build Coastguard Worker			af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
1532*333d2b36SAndroid Build Coastguard Worker		}
1533*333d2b36SAndroid Build Coastguard Worker	}
1534*333d2b36SAndroid Build Coastguard Worker	return af
1535*333d2b36SAndroid Build Coastguard Worker}
1536*333d2b36SAndroid Build Coastguard Worker
1537*333d2b36SAndroid Build Coastguard Workerfunc apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile {
1538*333d2b36SAndroid Build Coastguard Worker	if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
1539*333d2b36SAndroid Build Coastguard Worker		if profilePathOnHost := dexpreopter.OutputProfilePathOnHost(); profilePathOnHost != nil {
1540*333d2b36SAndroid Build Coastguard Worker			dirInApex := "javalib"
1541*333d2b36SAndroid Build Coastguard Worker			af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil)
1542*333d2b36SAndroid Build Coastguard Worker			af.customStem = module.Stem() + ".jar.prof"
1543*333d2b36SAndroid Build Coastguard Worker			return &af
1544*333d2b36SAndroid Build Coastguard Worker		}
1545*333d2b36SAndroid Build Coastguard Worker	}
1546*333d2b36SAndroid Build Coastguard Worker	return nil
1547*333d2b36SAndroid Build Coastguard Worker}
1548*333d2b36SAndroid Build Coastguard Worker
1549*333d2b36SAndroid Build Coastguard Worker// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
1550*333d2b36SAndroid Build Coastguard Worker// the same way.
1551*333d2b36SAndroid Build Coastguard Workertype androidApp interface {
1552*333d2b36SAndroid Build Coastguard Worker	android.Module
1553*333d2b36SAndroid Build Coastguard Worker	Privileged() bool
1554*333d2b36SAndroid Build Coastguard Worker	InstallApkName() string
1555*333d2b36SAndroid Build Coastguard Worker	OutputFile() android.Path
1556*333d2b36SAndroid Build Coastguard Worker	JacocoReportClassesFile() android.Path
1557*333d2b36SAndroid Build Coastguard Worker	Certificate() java.Certificate
1558*333d2b36SAndroid Build Coastguard Worker	BaseModuleName() string
1559*333d2b36SAndroid Build Coastguard Worker	PrivAppAllowlist() android.OptionalPath
1560*333d2b36SAndroid Build Coastguard Worker}
1561*333d2b36SAndroid Build Coastguard Worker
1562*333d2b36SAndroid Build Coastguard Workervar _ androidApp = (*java.AndroidApp)(nil)
1563*333d2b36SAndroid Build Coastguard Workervar _ androidApp = (*java.AndroidAppImport)(nil)
1564*333d2b36SAndroid Build Coastguard Worker
1565*333d2b36SAndroid Build Coastguard Workerfunc sanitizedBuildIdForPath(ctx android.BaseModuleContext) string {
1566*333d2b36SAndroid Build Coastguard Worker	buildId := ctx.Config().BuildId()
1567*333d2b36SAndroid Build Coastguard Worker
1568*333d2b36SAndroid Build Coastguard Worker	// The build ID is used as a suffix for a filename, so ensure that
1569*333d2b36SAndroid Build Coastguard Worker	// the set of characters being used are sanitized.
1570*333d2b36SAndroid Build Coastguard Worker	// - any word character: [a-zA-Z0-9_]
1571*333d2b36SAndroid Build Coastguard Worker	// - dots: .
1572*333d2b36SAndroid Build Coastguard Worker	// - dashes: -
1573*333d2b36SAndroid Build Coastguard Worker	validRegex := regexp.MustCompile(`^[\w\.\-\_]+$`)
1574*333d2b36SAndroid Build Coastguard Worker	if !validRegex.MatchString(buildId) {
1575*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("Unable to use build id %s as filename suffix, valid characters are [a-z A-Z 0-9 _ . -].", buildId)
1576*333d2b36SAndroid Build Coastguard Worker	}
1577*333d2b36SAndroid Build Coastguard Worker	return buildId
1578*333d2b36SAndroid Build Coastguard Worker}
1579*333d2b36SAndroid Build Coastguard Worker
1580*333d2b36SAndroid Build Coastguard Workerfunc apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []apexFile {
1581*333d2b36SAndroid Build Coastguard Worker	appDir := "app"
1582*333d2b36SAndroid Build Coastguard Worker	if aapp.Privileged() {
1583*333d2b36SAndroid Build Coastguard Worker		appDir = "priv-app"
1584*333d2b36SAndroid Build Coastguard Worker	}
1585*333d2b36SAndroid Build Coastguard Worker
1586*333d2b36SAndroid Build Coastguard Worker	// TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
1587*333d2b36SAndroid Build Coastguard Worker	// so that PackageManager correctly invalidates the existing installed apk
1588*333d2b36SAndroid Build Coastguard Worker	// in favour of the new APK-in-APEX.  See bugs for more information.
1589*333d2b36SAndroid Build Coastguard Worker	dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx))
1590*333d2b36SAndroid Build Coastguard Worker	fileToCopy := aapp.OutputFile()
1591*333d2b36SAndroid Build Coastguard Worker
1592*333d2b36SAndroid Build Coastguard Worker	af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
1593*333d2b36SAndroid Build Coastguard Worker	af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
1594*333d2b36SAndroid Build Coastguard Worker	if lintInfo, ok := android.OtherModuleProvider(ctx, aapp, java.LintProvider); ok {
1595*333d2b36SAndroid Build Coastguard Worker		af.lintInfo = lintInfo
1596*333d2b36SAndroid Build Coastguard Worker	}
1597*333d2b36SAndroid Build Coastguard Worker	af.certificate = aapp.Certificate()
1598*333d2b36SAndroid Build Coastguard Worker
1599*333d2b36SAndroid Build Coastguard Worker	if app, ok := aapp.(interface {
1600*333d2b36SAndroid Build Coastguard Worker		OverriddenManifestPackageName() string
1601*333d2b36SAndroid Build Coastguard Worker	}); ok {
1602*333d2b36SAndroid Build Coastguard Worker		af.overriddenPackageName = app.OverriddenManifestPackageName()
1603*333d2b36SAndroid Build Coastguard Worker	}
1604*333d2b36SAndroid Build Coastguard Worker
1605*333d2b36SAndroid Build Coastguard Worker	apexFiles := []apexFile{}
1606*333d2b36SAndroid Build Coastguard Worker
1607*333d2b36SAndroid Build Coastguard Worker	if allowlist := aapp.PrivAppAllowlist(); allowlist.Valid() {
1608*333d2b36SAndroid Build Coastguard Worker		dirInApex := filepath.Join("etc", "permissions")
1609*333d2b36SAndroid Build Coastguard Worker		privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"_privapp", dirInApex, etc, aapp)
1610*333d2b36SAndroid Build Coastguard Worker		apexFiles = append(apexFiles, privAppAllowlist)
1611*333d2b36SAndroid Build Coastguard Worker	}
1612*333d2b36SAndroid Build Coastguard Worker
1613*333d2b36SAndroid Build Coastguard Worker	apexFiles = append(apexFiles, af)
1614*333d2b36SAndroid Build Coastguard Worker
1615*333d2b36SAndroid Build Coastguard Worker	return apexFiles
1616*333d2b36SAndroid Build Coastguard Worker}
1617*333d2b36SAndroid Build Coastguard Worker
1618*333d2b36SAndroid Build Coastguard Workerfunc apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1619*333d2b36SAndroid Build Coastguard Worker	rroDir := "overlay"
1620*333d2b36SAndroid Build Coastguard Worker	dirInApex := filepath.Join(rroDir, rro.Theme())
1621*333d2b36SAndroid Build Coastguard Worker	fileToCopy := rro.OutputFile()
1622*333d2b36SAndroid Build Coastguard Worker	af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1623*333d2b36SAndroid Build Coastguard Worker	af.certificate = rro.Certificate()
1624*333d2b36SAndroid Build Coastguard Worker
1625*333d2b36SAndroid Build Coastguard Worker	if a, ok := rro.(interface {
1626*333d2b36SAndroid Build Coastguard Worker		OverriddenManifestPackageName() string
1627*333d2b36SAndroid Build Coastguard Worker	}); ok {
1628*333d2b36SAndroid Build Coastguard Worker		af.overriddenPackageName = a.OverriddenManifestPackageName()
1629*333d2b36SAndroid Build Coastguard Worker	}
1630*333d2b36SAndroid Build Coastguard Worker	return af
1631*333d2b36SAndroid Build Coastguard Worker}
1632*333d2b36SAndroid Build Coastguard Worker
1633*333d2b36SAndroid Build Coastguard Workerfunc apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile {
1634*333d2b36SAndroid Build Coastguard Worker	dirInApex := filepath.Join("etc", "bpf", apex_sub_dir)
1635*333d2b36SAndroid Build Coastguard Worker	return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram)
1636*333d2b36SAndroid Build Coastguard Worker}
1637*333d2b36SAndroid Build Coastguard Worker
1638*333d2b36SAndroid Build Coastguard Workerfunc apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile {
1639*333d2b36SAndroid Build Coastguard Worker	dirInApex := filepath.Join("etc", "fs")
1640*333d2b36SAndroid Build Coastguard Worker	return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs)
1641*333d2b36SAndroid Build Coastguard Worker}
1642*333d2b36SAndroid Build Coastguard Worker
1643*333d2b36SAndroid Build Coastguard Worker// WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the
1644*333d2b36SAndroid Build Coastguard Worker// visited module, the `do` callback is executed. Returning true in the callback continues the visit
1645*333d2b36SAndroid Build Coastguard Worker// to the child modules. Returning false makes the visit to continue in the sibling or the parent
1646*333d2b36SAndroid Build Coastguard Worker// modules. This is used in check* functions below.
1647*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
1648*333d2b36SAndroid Build Coastguard Worker	ctx.WalkDeps(func(child, parent android.Module) bool {
1649*333d2b36SAndroid Build Coastguard Worker		am, ok := child.(android.ApexModule)
1650*333d2b36SAndroid Build Coastguard Worker		if !ok || !am.CanHaveApexVariants() {
1651*333d2b36SAndroid Build Coastguard Worker			return false
1652*333d2b36SAndroid Build Coastguard Worker		}
1653*333d2b36SAndroid Build Coastguard Worker
1654*333d2b36SAndroid Build Coastguard Worker		// Filter-out unwanted depedendencies
1655*333d2b36SAndroid Build Coastguard Worker		depTag := ctx.OtherModuleDependencyTag(child)
1656*333d2b36SAndroid Build Coastguard Worker		if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1657*333d2b36SAndroid Build Coastguard Worker			return false
1658*333d2b36SAndroid Build Coastguard Worker		}
1659*333d2b36SAndroid Build Coastguard Worker		if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
1660*333d2b36SAndroid Build Coastguard Worker			return false
1661*333d2b36SAndroid Build Coastguard Worker		}
1662*333d2b36SAndroid Build Coastguard Worker		if depTag == android.RequiredDepTag {
1663*333d2b36SAndroid Build Coastguard Worker			return false
1664*333d2b36SAndroid Build Coastguard Worker		}
1665*333d2b36SAndroid Build Coastguard Worker
1666*333d2b36SAndroid Build Coastguard Worker		ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
1667*333d2b36SAndroid Build Coastguard Worker		externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
1668*333d2b36SAndroid Build Coastguard Worker
1669*333d2b36SAndroid Build Coastguard Worker		// Visit actually
1670*333d2b36SAndroid Build Coastguard Worker		return do(ctx, parent, am, externalDep)
1671*333d2b36SAndroid Build Coastguard Worker	})
1672*333d2b36SAndroid Build Coastguard Worker}
1673*333d2b36SAndroid Build Coastguard Worker
1674*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) WalkPayloadDepsProxy(ctx android.BaseModuleContext,
1675*333d2b36SAndroid Build Coastguard Worker	do func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool) {
1676*333d2b36SAndroid Build Coastguard Worker	ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
1677*333d2b36SAndroid Build Coastguard Worker		if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey).CanHaveApexVariants {
1678*333d2b36SAndroid Build Coastguard Worker			return false
1679*333d2b36SAndroid Build Coastguard Worker		}
1680*333d2b36SAndroid Build Coastguard Worker		// Filter-out unwanted depedendencies
1681*333d2b36SAndroid Build Coastguard Worker		depTag := ctx.OtherModuleDependencyTag(child)
1682*333d2b36SAndroid Build Coastguard Worker		if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1683*333d2b36SAndroid Build Coastguard Worker			return false
1684*333d2b36SAndroid Build Coastguard Worker		}
1685*333d2b36SAndroid Build Coastguard Worker		if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
1686*333d2b36SAndroid Build Coastguard Worker			return false
1687*333d2b36SAndroid Build Coastguard Worker		}
1688*333d2b36SAndroid Build Coastguard Worker		if depTag == android.RequiredDepTag {
1689*333d2b36SAndroid Build Coastguard Worker			return false
1690*333d2b36SAndroid Build Coastguard Worker		}
1691*333d2b36SAndroid Build Coastguard Worker
1692*333d2b36SAndroid Build Coastguard Worker		ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
1693*333d2b36SAndroid Build Coastguard Worker		externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
1694*333d2b36SAndroid Build Coastguard Worker
1695*333d2b36SAndroid Build Coastguard Worker		// Visit actually
1696*333d2b36SAndroid Build Coastguard Worker		return do(ctx, parent, child, externalDep)
1697*333d2b36SAndroid Build Coastguard Worker	})
1698*333d2b36SAndroid Build Coastguard Worker}
1699*333d2b36SAndroid Build Coastguard Worker
1700*333d2b36SAndroid Build Coastguard Worker// filesystem type of the apex_payload.img inside the APEX. Currently, ext4 and f2fs are supported.
1701*333d2b36SAndroid Build Coastguard Workertype fsType int
1702*333d2b36SAndroid Build Coastguard Worker
1703*333d2b36SAndroid Build Coastguard Workerconst (
1704*333d2b36SAndroid Build Coastguard Worker	ext4 fsType = iota
1705*333d2b36SAndroid Build Coastguard Worker	f2fs
1706*333d2b36SAndroid Build Coastguard Worker	erofs
1707*333d2b36SAndroid Build Coastguard Worker)
1708*333d2b36SAndroid Build Coastguard Worker
1709*333d2b36SAndroid Build Coastguard Workerfunc (f fsType) string() string {
1710*333d2b36SAndroid Build Coastguard Worker	switch f {
1711*333d2b36SAndroid Build Coastguard Worker	case ext4:
1712*333d2b36SAndroid Build Coastguard Worker		return ext4FsType
1713*333d2b36SAndroid Build Coastguard Worker	case f2fs:
1714*333d2b36SAndroid Build Coastguard Worker		return f2fsFsType
1715*333d2b36SAndroid Build Coastguard Worker	case erofs:
1716*333d2b36SAndroid Build Coastguard Worker		return erofsFsType
1717*333d2b36SAndroid Build Coastguard Worker	default:
1718*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("unknown APEX payload type %d", f))
1719*333d2b36SAndroid Build Coastguard Worker	}
1720*333d2b36SAndroid Build Coastguard Worker}
1721*333d2b36SAndroid Build Coastguard Worker
1722*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) setCompression(ctx android.ModuleContext) {
1723*333d2b36SAndroid Build Coastguard Worker	if a.testOnlyShouldForceCompression() {
1724*333d2b36SAndroid Build Coastguard Worker		a.isCompressed = true
1725*333d2b36SAndroid Build Coastguard Worker	} else {
1726*333d2b36SAndroid Build Coastguard Worker		a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
1727*333d2b36SAndroid Build Coastguard Worker	}
1728*333d2b36SAndroid Build Coastguard Worker}
1729*333d2b36SAndroid Build Coastguard Worker
1730*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
1731*333d2b36SAndroid Build Coastguard Worker	// Optimization. If we are building bundled APEX, for the files that are gathered due to the
1732*333d2b36SAndroid Build Coastguard Worker	// transitive dependencies, don't place them inside the APEX, but place a symlink pointing
1733*333d2b36SAndroid Build Coastguard Worker	// the same library in the system partition, thus effectively sharing the same libraries
1734*333d2b36SAndroid Build Coastguard Worker	// across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
1735*333d2b36SAndroid Build Coastguard Worker	// in the APEX.
1736*333d2b36SAndroid Build Coastguard Worker	a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
1737*333d2b36SAndroid Build Coastguard Worker
1738*333d2b36SAndroid Build Coastguard Worker	// APEXes targeting other than system/system_ext partitions use vendor/product variants.
1739*333d2b36SAndroid Build Coastguard Worker	// So we can't link them to /system/lib libs which are core variants.
1740*333d2b36SAndroid Build Coastguard Worker	if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1741*333d2b36SAndroid Build Coastguard Worker		a.linkToSystemLib = false
1742*333d2b36SAndroid Build Coastguard Worker	}
1743*333d2b36SAndroid Build Coastguard Worker
1744*333d2b36SAndroid Build Coastguard Worker	forced := ctx.Config().ForceApexSymlinkOptimization()
1745*333d2b36SAndroid Build Coastguard Worker	updatable := a.Updatable() || a.FutureUpdatable()
1746*333d2b36SAndroid Build Coastguard Worker
1747*333d2b36SAndroid Build Coastguard Worker	// We don't need the optimization for updatable APEXes, as it might give false signal
1748*333d2b36SAndroid Build Coastguard Worker	// to the system health when the APEXes are still bundled (b/149805758).
1749*333d2b36SAndroid Build Coastguard Worker	if !forced && updatable {
1750*333d2b36SAndroid Build Coastguard Worker		a.linkToSystemLib = false
1751*333d2b36SAndroid Build Coastguard Worker	}
1752*333d2b36SAndroid Build Coastguard Worker}
1753*333d2b36SAndroid Build Coastguard Worker
1754*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
1755*333d2b36SAndroid Build Coastguard Worker	defaultFsType := ctx.Config().DefaultApexPayloadType()
1756*333d2b36SAndroid Build Coastguard Worker	switch proptools.StringDefault(a.properties.Payload_fs_type, defaultFsType) {
1757*333d2b36SAndroid Build Coastguard Worker	case ext4FsType:
1758*333d2b36SAndroid Build Coastguard Worker		a.payloadFsType = ext4
1759*333d2b36SAndroid Build Coastguard Worker	case f2fsFsType:
1760*333d2b36SAndroid Build Coastguard Worker		a.payloadFsType = f2fs
1761*333d2b36SAndroid Build Coastguard Worker	case erofsFsType:
1762*333d2b36SAndroid Build Coastguard Worker		a.payloadFsType = erofs
1763*333d2b36SAndroid Build Coastguard Worker	default:
1764*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
1765*333d2b36SAndroid Build Coastguard Worker	}
1766*333d2b36SAndroid Build Coastguard Worker}
1767*333d2b36SAndroid Build Coastguard Worker
1768*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) isCompressable() bool {
1769*333d2b36SAndroid Build Coastguard Worker	if a.testApex {
1770*333d2b36SAndroid Build Coastguard Worker		return false
1771*333d2b36SAndroid Build Coastguard Worker	}
1772*333d2b36SAndroid Build Coastguard Worker	if a.payloadFsType == erofs {
1773*333d2b36SAndroid Build Coastguard Worker		return false
1774*333d2b36SAndroid Build Coastguard Worker	}
1775*333d2b36SAndroid Build Coastguard Worker	return proptools.Bool(a.overridableProperties.Compressible)
1776*333d2b36SAndroid Build Coastguard Worker}
1777*333d2b36SAndroid Build Coastguard Worker
1778*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool {
1779*333d2b36SAndroid Build Coastguard Worker	a.checkApexAvailability(ctx)
1780*333d2b36SAndroid Build Coastguard Worker	a.checkUpdatable(ctx)
1781*333d2b36SAndroid Build Coastguard Worker	a.CheckMinSdkVersion(ctx)
1782*333d2b36SAndroid Build Coastguard Worker	a.checkStaticLinkingToStubLibraries(ctx)
1783*333d2b36SAndroid Build Coastguard Worker	a.checkStaticExecutables(ctx)
1784*333d2b36SAndroid Build Coastguard Worker	a.enforceAppUpdatability(ctx)
1785*333d2b36SAndroid Build Coastguard Worker	if len(a.properties.Tests) > 0 && !a.testApex {
1786*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
1787*333d2b36SAndroid Build Coastguard Worker		return false
1788*333d2b36SAndroid Build Coastguard Worker	}
1789*333d2b36SAndroid Build Coastguard Worker	return true
1790*333d2b36SAndroid Build Coastguard Worker}
1791*333d2b36SAndroid Build Coastguard Worker
1792*333d2b36SAndroid Build Coastguard Workertype visitorContext struct {
1793*333d2b36SAndroid Build Coastguard Worker	// all the files that will be included in this APEX
1794*333d2b36SAndroid Build Coastguard Worker	filesInfo []apexFile
1795*333d2b36SAndroid Build Coastguard Worker
1796*333d2b36SAndroid Build Coastguard Worker	// native lib dependencies
1797*333d2b36SAndroid Build Coastguard Worker	provideNativeLibs []string
1798*333d2b36SAndroid Build Coastguard Worker	requireNativeLibs []string
1799*333d2b36SAndroid Build Coastguard Worker
1800*333d2b36SAndroid Build Coastguard Worker	handleSpecialLibs bool
1801*333d2b36SAndroid Build Coastguard Worker
1802*333d2b36SAndroid Build Coastguard Worker	// if true, raise error on duplicate apexFile
1803*333d2b36SAndroid Build Coastguard Worker	checkDuplicate bool
1804*333d2b36SAndroid Build Coastguard Worker
1805*333d2b36SAndroid Build Coastguard Worker	// visitor skips these from this list of module names
1806*333d2b36SAndroid Build Coastguard Worker	unwantedTransitiveDeps []string
1807*333d2b36SAndroid Build Coastguard Worker
1808*333d2b36SAndroid Build Coastguard Worker	// unwantedTransitiveFilesInfo contains files that would have been in the apex
1809*333d2b36SAndroid Build Coastguard Worker	// except that they were listed in unwantedTransitiveDeps.
1810*333d2b36SAndroid Build Coastguard Worker	unwantedTransitiveFilesInfo []apexFile
1811*333d2b36SAndroid Build Coastguard Worker
1812*333d2b36SAndroid Build Coastguard Worker	// duplicateTransitiveFilesInfo contains files that would ahve been in the apex
1813*333d2b36SAndroid Build Coastguard Worker	// except that another variant of the same module was already in the apex.
1814*333d2b36SAndroid Build Coastguard Worker	duplicateTransitiveFilesInfo []apexFile
1815*333d2b36SAndroid Build Coastguard Worker}
1816*333d2b36SAndroid Build Coastguard Worker
1817*333d2b36SAndroid Build Coastguard Workerfunc (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
1818*333d2b36SAndroid Build Coastguard Worker	encountered := make(map[string]apexFile)
1819*333d2b36SAndroid Build Coastguard Worker	for _, f := range vctx.filesInfo {
1820*333d2b36SAndroid Build Coastguard Worker		// Skips unwanted transitive deps. This happens, for example, with Rust binaries with prefer_rlib:true.
1821*333d2b36SAndroid Build Coastguard Worker		// TODO(b/295593640)
1822*333d2b36SAndroid Build Coastguard Worker		// Needs additional verification for the resulting APEX to ensure that skipped artifacts don't make problems.
1823*333d2b36SAndroid Build Coastguard Worker		// For example, DT_NEEDED modules should be found within the APEX unless they are marked in `requiredNativeLibs`.
1824*333d2b36SAndroid Build Coastguard Worker		if f.transitiveDep && f.module != nil && android.InList(mctx.OtherModuleName(f.module), vctx.unwantedTransitiveDeps) {
1825*333d2b36SAndroid Build Coastguard Worker			vctx.unwantedTransitiveFilesInfo = append(vctx.unwantedTransitiveFilesInfo, f)
1826*333d2b36SAndroid Build Coastguard Worker			continue
1827*333d2b36SAndroid Build Coastguard Worker		}
1828*333d2b36SAndroid Build Coastguard Worker		dest := filepath.Join(f.installDir, f.builtFile.Base())
1829*333d2b36SAndroid Build Coastguard Worker		if e, ok := encountered[dest]; !ok {
1830*333d2b36SAndroid Build Coastguard Worker			encountered[dest] = f
1831*333d2b36SAndroid Build Coastguard Worker		} else {
1832*333d2b36SAndroid Build Coastguard Worker			if vctx.checkDuplicate && f.builtFile.String() != e.builtFile.String() {
1833*333d2b36SAndroid Build Coastguard Worker				mctx.ModuleErrorf("apex file %v is provided by two different files %v and %v",
1834*333d2b36SAndroid Build Coastguard Worker					dest, e.builtFile, f.builtFile)
1835*333d2b36SAndroid Build Coastguard Worker				return
1836*333d2b36SAndroid Build Coastguard Worker			} else {
1837*333d2b36SAndroid Build Coastguard Worker				vctx.duplicateTransitiveFilesInfo = append(vctx.duplicateTransitiveFilesInfo, f)
1838*333d2b36SAndroid Build Coastguard Worker			}
1839*333d2b36SAndroid Build Coastguard Worker			// If a module is directly included and also transitively depended on
1840*333d2b36SAndroid Build Coastguard Worker			// consider it as directly included.
1841*333d2b36SAndroid Build Coastguard Worker			e.transitiveDep = e.transitiveDep && f.transitiveDep
1842*333d2b36SAndroid Build Coastguard Worker			// If a module is added as both a JNI library and a regular shared library, consider it as a
1843*333d2b36SAndroid Build Coastguard Worker			// JNI library.
1844*333d2b36SAndroid Build Coastguard Worker			e.isJniLib = e.isJniLib || f.isJniLib
1845*333d2b36SAndroid Build Coastguard Worker			encountered[dest] = e
1846*333d2b36SAndroid Build Coastguard Worker		}
1847*333d2b36SAndroid Build Coastguard Worker	}
1848*333d2b36SAndroid Build Coastguard Worker	vctx.filesInfo = vctx.filesInfo[:0]
1849*333d2b36SAndroid Build Coastguard Worker	for _, v := range encountered {
1850*333d2b36SAndroid Build Coastguard Worker		vctx.filesInfo = append(vctx.filesInfo, v)
1851*333d2b36SAndroid Build Coastguard Worker	}
1852*333d2b36SAndroid Build Coastguard Worker
1853*333d2b36SAndroid Build Coastguard Worker	sort.Slice(vctx.filesInfo, func(i, j int) bool {
1854*333d2b36SAndroid Build Coastguard Worker		// Sort by destination path so as to ensure consistent ordering even if the source of the files
1855*333d2b36SAndroid Build Coastguard Worker		// changes.
1856*333d2b36SAndroid Build Coastguard Worker		return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
1857*333d2b36SAndroid Build Coastguard Worker	})
1858*333d2b36SAndroid Build Coastguard Worker}
1859*333d2b36SAndroid Build Coastguard Worker
1860*333d2b36SAndroid Build Coastguard Worker// enforcePartitionTagOnApexSystemServerJar checks that the partition tags of an apex system server jar  matches
1861*333d2b36SAndroid Build Coastguard Worker// the partition tags of the top-level apex.
1862*333d2b36SAndroid Build Coastguard Worker// e.g. if the top-level apex sets system_ext_specific to true, the javalib must set this property to true as well.
1863*333d2b36SAndroid Build Coastguard Worker// This check ensures that the dexpreopt artifacts of the apex system server jar is installed in the same partition
1864*333d2b36SAndroid Build Coastguard Worker// as the apex.
1865*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) enforcePartitionTagOnApexSystemServerJar(ctx android.ModuleContext) {
1866*333d2b36SAndroid Build Coastguard Worker	global := dexpreopt.GetGlobalConfig(ctx)
1867*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxyWithTag(sscpfTag, func(child android.ModuleProxy) {
1868*333d2b36SAndroid Build Coastguard Worker		info, ok := android.OtherModuleProvider(ctx, child, java.LibraryNameToPartitionInfoProvider)
1869*333d2b36SAndroid Build Coastguard Worker		if !ok {
1870*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("Could not find partition info of apex system server jars.")
1871*333d2b36SAndroid Build Coastguard Worker		}
1872*333d2b36SAndroid Build Coastguard Worker		apexPartition := ctx.Module().PartitionTag(ctx.DeviceConfig())
1873*333d2b36SAndroid Build Coastguard Worker		for javalib, javalibPartition := range info.LibraryNameToPartition {
1874*333d2b36SAndroid Build Coastguard Worker			if !global.AllApexSystemServerJars(ctx).ContainsJar(javalib) {
1875*333d2b36SAndroid Build Coastguard Worker				continue // not an apex system server jar
1876*333d2b36SAndroid Build Coastguard Worker			}
1877*333d2b36SAndroid Build Coastguard Worker			if apexPartition != javalibPartition {
1878*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf(`
1879*333d2b36SAndroid Build Coastguard Worker%s is an apex systemserver jar, but its partition does not match the partition of its containing apex. Expected %s, Got %s`,
1880*333d2b36SAndroid Build Coastguard Worker					javalib, apexPartition, javalibPartition)
1881*333d2b36SAndroid Build Coastguard Worker			}
1882*333d2b36SAndroid Build Coastguard Worker		}
1883*333d2b36SAndroid Build Coastguard Worker	})
1884*333d2b36SAndroid Build Coastguard Worker}
1885*333d2b36SAndroid Build Coastguard Worker
1886*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent android.Module) bool {
1887*333d2b36SAndroid Build Coastguard Worker	depTag := ctx.OtherModuleDependencyTag(child)
1888*333d2b36SAndroid Build Coastguard Worker	if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
1889*333d2b36SAndroid Build Coastguard Worker		return false
1890*333d2b36SAndroid Build Coastguard Worker	}
1891*333d2b36SAndroid Build Coastguard Worker	if !child.Enabled(ctx) {
1892*333d2b36SAndroid Build Coastguard Worker		return false
1893*333d2b36SAndroid Build Coastguard Worker	}
1894*333d2b36SAndroid Build Coastguard Worker	depName := ctx.OtherModuleName(child)
1895*333d2b36SAndroid Build Coastguard Worker	if _, isDirectDep := parent.(*apexBundle); isDirectDep {
1896*333d2b36SAndroid Build Coastguard Worker		switch depTag {
1897*333d2b36SAndroid Build Coastguard Worker		case sharedLibTag, jniLibTag:
1898*333d2b36SAndroid Build Coastguard Worker			isJniLib := depTag == jniLibTag
1899*333d2b36SAndroid Build Coastguard Worker			propertyName := "native_shared_libs"
1900*333d2b36SAndroid Build Coastguard Worker			if isJniLib {
1901*333d2b36SAndroid Build Coastguard Worker				propertyName = "jni_libs"
1902*333d2b36SAndroid Build Coastguard Worker			}
1903*333d2b36SAndroid Build Coastguard Worker			switch ch := child.(type) {
1904*333d2b36SAndroid Build Coastguard Worker			case *cc.Module:
1905*333d2b36SAndroid Build Coastguard Worker				if ch.IsStubs() {
1906*333d2b36SAndroid Build Coastguard Worker					ctx.PropertyErrorf(propertyName, "%q is a stub. Remove it from the list.", depName)
1907*333d2b36SAndroid Build Coastguard Worker				}
1908*333d2b36SAndroid Build Coastguard Worker				fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
1909*333d2b36SAndroid Build Coastguard Worker				fi.isJniLib = isJniLib
1910*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, fi)
1911*333d2b36SAndroid Build Coastguard Worker				// Collect the list of stub-providing libs except:
1912*333d2b36SAndroid Build Coastguard Worker				// - VNDK libs are only for vendors
1913*333d2b36SAndroid Build Coastguard Worker				// - bootstrap bionic libs are treated as provided by system
1914*333d2b36SAndroid Build Coastguard Worker				if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
1915*333d2b36SAndroid Build Coastguard Worker					vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
1916*333d2b36SAndroid Build Coastguard Worker				}
1917*333d2b36SAndroid Build Coastguard Worker				return true // track transitive dependencies
1918*333d2b36SAndroid Build Coastguard Worker			case *rust.Module:
1919*333d2b36SAndroid Build Coastguard Worker				fi := apexFileForRustLibrary(ctx, ch)
1920*333d2b36SAndroid Build Coastguard Worker				fi.isJniLib = isJniLib
1921*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, fi)
1922*333d2b36SAndroid Build Coastguard Worker				return true // track transitive dependencies
1923*333d2b36SAndroid Build Coastguard Worker			default:
1924*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
1925*333d2b36SAndroid Build Coastguard Worker			}
1926*333d2b36SAndroid Build Coastguard Worker		case executableTag:
1927*333d2b36SAndroid Build Coastguard Worker			switch ch := child.(type) {
1928*333d2b36SAndroid Build Coastguard Worker			case *cc.Module:
1929*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
1930*333d2b36SAndroid Build Coastguard Worker				return true // track transitive dependencies
1931*333d2b36SAndroid Build Coastguard Worker			case *rust.Module:
1932*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
1933*333d2b36SAndroid Build Coastguard Worker				return true // track transitive dependencies
1934*333d2b36SAndroid Build Coastguard Worker			default:
1935*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("binaries",
1936*333d2b36SAndroid Build Coastguard Worker					"%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
1937*333d2b36SAndroid Build Coastguard Worker			}
1938*333d2b36SAndroid Build Coastguard Worker		case shBinaryTag:
1939*333d2b36SAndroid Build Coastguard Worker			if csh, ok := child.(*sh.ShBinary); ok {
1940*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
1941*333d2b36SAndroid Build Coastguard Worker			} else {
1942*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
1943*333d2b36SAndroid Build Coastguard Worker			}
1944*333d2b36SAndroid Build Coastguard Worker		case bcpfTag:
1945*333d2b36SAndroid Build Coastguard Worker			_, ok := child.(*java.BootclasspathFragmentModule)
1946*333d2b36SAndroid Build Coastguard Worker			if !ok {
1947*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
1948*333d2b36SAndroid Build Coastguard Worker				return false
1949*333d2b36SAndroid Build Coastguard Worker			}
1950*333d2b36SAndroid Build Coastguard Worker
1951*333d2b36SAndroid Build Coastguard Worker			vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
1952*333d2b36SAndroid Build Coastguard Worker			return true
1953*333d2b36SAndroid Build Coastguard Worker		case sscpfTag:
1954*333d2b36SAndroid Build Coastguard Worker			if _, ok := child.(*java.SystemServerClasspathModule); !ok {
1955*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("systemserverclasspath_fragments",
1956*333d2b36SAndroid Build Coastguard Worker					"%q is not a systemserverclasspath_fragment module", depName)
1957*333d2b36SAndroid Build Coastguard Worker				return false
1958*333d2b36SAndroid Build Coastguard Worker			}
1959*333d2b36SAndroid Build Coastguard Worker			if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
1960*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, *af)
1961*333d2b36SAndroid Build Coastguard Worker			}
1962*333d2b36SAndroid Build Coastguard Worker			return true
1963*333d2b36SAndroid Build Coastguard Worker		case javaLibTag:
1964*333d2b36SAndroid Build Coastguard Worker			switch child.(type) {
1965*333d2b36SAndroid Build Coastguard Worker			case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
1966*333d2b36SAndroid Build Coastguard Worker				af := apexFileForJavaModule(ctx, child.(javaModule))
1967*333d2b36SAndroid Build Coastguard Worker				if !af.ok() {
1968*333d2b36SAndroid Build Coastguard Worker					ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
1969*333d2b36SAndroid Build Coastguard Worker					return false
1970*333d2b36SAndroid Build Coastguard Worker				}
1971*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, af)
1972*333d2b36SAndroid Build Coastguard Worker				return true // track transitive dependencies
1973*333d2b36SAndroid Build Coastguard Worker			default:
1974*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
1975*333d2b36SAndroid Build Coastguard Worker			}
1976*333d2b36SAndroid Build Coastguard Worker		case androidAppTag:
1977*333d2b36SAndroid Build Coastguard Worker			switch ap := child.(type) {
1978*333d2b36SAndroid Build Coastguard Worker			case *java.AndroidApp:
1979*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
1980*333d2b36SAndroid Build Coastguard Worker				return true // track transitive dependencies
1981*333d2b36SAndroid Build Coastguard Worker			case *java.AndroidAppImport:
1982*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
1983*333d2b36SAndroid Build Coastguard Worker			case *java.AndroidTestHelperApp:
1984*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
1985*333d2b36SAndroid Build Coastguard Worker			case *java.AndroidAppSet:
1986*333d2b36SAndroid Build Coastguard Worker				appDir := "app"
1987*333d2b36SAndroid Build Coastguard Worker				if ap.Privileged() {
1988*333d2b36SAndroid Build Coastguard Worker					appDir = "priv-app"
1989*333d2b36SAndroid Build Coastguard Worker				}
1990*333d2b36SAndroid Build Coastguard Worker				// TODO(b/224589412, b/226559955): Ensure that the dirname is
1991*333d2b36SAndroid Build Coastguard Worker				// suffixed so that PackageManager correctly invalidates the
1992*333d2b36SAndroid Build Coastguard Worker				// existing installed apk in favour of the new APK-in-APEX.
1993*333d2b36SAndroid Build Coastguard Worker				// See bugs for more information.
1994*333d2b36SAndroid Build Coastguard Worker				appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
1995*333d2b36SAndroid Build Coastguard Worker				af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
1996*333d2b36SAndroid Build Coastguard Worker				af.certificate = java.PresignedCertificate
1997*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, af)
1998*333d2b36SAndroid Build Coastguard Worker			default:
1999*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2000*333d2b36SAndroid Build Coastguard Worker			}
2001*333d2b36SAndroid Build Coastguard Worker		case rroTag:
2002*333d2b36SAndroid Build Coastguard Worker			if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2003*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2004*333d2b36SAndroid Build Coastguard Worker			} else {
2005*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2006*333d2b36SAndroid Build Coastguard Worker			}
2007*333d2b36SAndroid Build Coastguard Worker		case bpfTag:
2008*333d2b36SAndroid Build Coastguard Worker			if bpfProgram, ok := child.(bpf.BpfModule); ok {
2009*333d2b36SAndroid Build Coastguard Worker				filesToCopy := android.OutputFilesForModule(ctx, bpfProgram, "")
2010*333d2b36SAndroid Build Coastguard Worker				apex_sub_dir := bpfProgram.SubDir()
2011*333d2b36SAndroid Build Coastguard Worker				for _, bpfFile := range filesToCopy {
2012*333d2b36SAndroid Build Coastguard Worker					vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
2013*333d2b36SAndroid Build Coastguard Worker				}
2014*333d2b36SAndroid Build Coastguard Worker			} else {
2015*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
2016*333d2b36SAndroid Build Coastguard Worker			}
2017*333d2b36SAndroid Build Coastguard Worker		case fsTag:
2018*333d2b36SAndroid Build Coastguard Worker			if fs, ok := child.(filesystem.Filesystem); ok {
2019*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
2020*333d2b36SAndroid Build Coastguard Worker			} else {
2021*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
2022*333d2b36SAndroid Build Coastguard Worker			}
2023*333d2b36SAndroid Build Coastguard Worker		case prebuiltTag:
2024*333d2b36SAndroid Build Coastguard Worker			if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2025*333d2b36SAndroid Build Coastguard Worker				filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "")
2026*333d2b36SAndroid Build Coastguard Worker				for _, etcFile := range filesToCopy {
2027*333d2b36SAndroid Build Coastguard Worker					vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
2028*333d2b36SAndroid Build Coastguard Worker				}
2029*333d2b36SAndroid Build Coastguard Worker			} else {
2030*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
2031*333d2b36SAndroid Build Coastguard Worker			}
2032*333d2b36SAndroid Build Coastguard Worker		case compatConfigTag:
2033*333d2b36SAndroid Build Coastguard Worker			if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
2034*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
2035*333d2b36SAndroid Build Coastguard Worker			} else {
2036*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
2037*333d2b36SAndroid Build Coastguard Worker			}
2038*333d2b36SAndroid Build Coastguard Worker		case testTag:
2039*333d2b36SAndroid Build Coastguard Worker			if ccTest, ok := child.(*cc.Module); ok {
2040*333d2b36SAndroid Build Coastguard Worker				af := apexFileForExecutable(ctx, ccTest)
2041*333d2b36SAndroid Build Coastguard Worker				af.class = nativeTest
2042*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, af)
2043*333d2b36SAndroid Build Coastguard Worker				return true // track transitive dependencies
2044*333d2b36SAndroid Build Coastguard Worker			} else {
2045*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2046*333d2b36SAndroid Build Coastguard Worker			}
2047*333d2b36SAndroid Build Coastguard Worker		case keyTag:
2048*333d2b36SAndroid Build Coastguard Worker			if key, ok := child.(*apexKey); ok {
2049*333d2b36SAndroid Build Coastguard Worker				a.privateKeyFile = key.privateKeyFile
2050*333d2b36SAndroid Build Coastguard Worker				a.publicKeyFile = key.publicKeyFile
2051*333d2b36SAndroid Build Coastguard Worker			} else {
2052*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2053*333d2b36SAndroid Build Coastguard Worker			}
2054*333d2b36SAndroid Build Coastguard Worker		case certificateTag:
2055*333d2b36SAndroid Build Coastguard Worker			if dep, ok := child.(*java.AndroidAppCertificate); ok {
2056*333d2b36SAndroid Build Coastguard Worker				a.containerCertificateFile = dep.Certificate.Pem
2057*333d2b36SAndroid Build Coastguard Worker				a.containerPrivateKeyFile = dep.Certificate.Key
2058*333d2b36SAndroid Build Coastguard Worker			} else {
2059*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2060*333d2b36SAndroid Build Coastguard Worker			}
2061*333d2b36SAndroid Build Coastguard Worker		}
2062*333d2b36SAndroid Build Coastguard Worker		return false
2063*333d2b36SAndroid Build Coastguard Worker	}
2064*333d2b36SAndroid Build Coastguard Worker
2065*333d2b36SAndroid Build Coastguard Worker	if a.vndkApex {
2066*333d2b36SAndroid Build Coastguard Worker		return false
2067*333d2b36SAndroid Build Coastguard Worker	}
2068*333d2b36SAndroid Build Coastguard Worker
2069*333d2b36SAndroid Build Coastguard Worker	// indirect dependencies
2070*333d2b36SAndroid Build Coastguard Worker	am, ok := child.(android.ApexModule)
2071*333d2b36SAndroid Build Coastguard Worker	if !ok {
2072*333d2b36SAndroid Build Coastguard Worker		return false
2073*333d2b36SAndroid Build Coastguard Worker	}
2074*333d2b36SAndroid Build Coastguard Worker	// We cannot use a switch statement on `depTag` here as the checked
2075*333d2b36SAndroid Build Coastguard Worker	// tags used below are private (e.g. `cc.sharedDepTag`).
2076*333d2b36SAndroid Build Coastguard Worker	if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2077*333d2b36SAndroid Build Coastguard Worker		if ch, ok := child.(*cc.Module); ok {
2078*333d2b36SAndroid Build Coastguard Worker			af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
2079*333d2b36SAndroid Build Coastguard Worker			af.transitiveDep = true
2080*333d2b36SAndroid Build Coastguard Worker
2081*333d2b36SAndroid Build Coastguard Worker			if ch.IsStubs() || ch.HasStubsVariants() {
2082*333d2b36SAndroid Build Coastguard Worker				// If the dependency is a stubs lib, don't include it in this APEX,
2083*333d2b36SAndroid Build Coastguard Worker				// but make sure that the lib is installed on the device.
2084*333d2b36SAndroid Build Coastguard Worker				// In case no APEX is having the lib, the lib is installed to the system
2085*333d2b36SAndroid Build Coastguard Worker				// partition.
2086*333d2b36SAndroid Build Coastguard Worker				//
2087*333d2b36SAndroid Build Coastguard Worker				// Always include if we are a host-apex however since those won't have any
2088*333d2b36SAndroid Build Coastguard Worker				// system libraries.
2089*333d2b36SAndroid Build Coastguard Worker				//
2090*333d2b36SAndroid Build Coastguard Worker				// Skip the dependency in unbundled builds where the device image is not
2091*333d2b36SAndroid Build Coastguard Worker				// being built.
2092*333d2b36SAndroid Build Coastguard Worker				if ch.IsStubsImplementationRequired() && !am.NotInPlatform() && !ctx.Config().UnbundledBuild() {
2093*333d2b36SAndroid Build Coastguard Worker					// we need a module name for Make
2094*333d2b36SAndroid Build Coastguard Worker					name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
2095*333d2b36SAndroid Build Coastguard Worker					if !android.InList(name, a.makeModulesToInstall) {
2096*333d2b36SAndroid Build Coastguard Worker						a.makeModulesToInstall = append(a.makeModulesToInstall, name)
2097*333d2b36SAndroid Build Coastguard Worker					}
2098*333d2b36SAndroid Build Coastguard Worker				}
2099*333d2b36SAndroid Build Coastguard Worker				vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
2100*333d2b36SAndroid Build Coastguard Worker				// Don't track further
2101*333d2b36SAndroid Build Coastguard Worker				return false
2102*333d2b36SAndroid Build Coastguard Worker			}
2103*333d2b36SAndroid Build Coastguard Worker
2104*333d2b36SAndroid Build Coastguard Worker			// If the dep is not considered to be in the same
2105*333d2b36SAndroid Build Coastguard Worker			// apex, don't add it to filesInfo so that it is not
2106*333d2b36SAndroid Build Coastguard Worker			// included in this APEX.
2107*333d2b36SAndroid Build Coastguard Worker			// TODO(jiyong): move this to at the top of the
2108*333d2b36SAndroid Build Coastguard Worker			// else-if clause for the indirect dependencies.
2109*333d2b36SAndroid Build Coastguard Worker			// Currently, that's impossible because we would
2110*333d2b36SAndroid Build Coastguard Worker			// like to record requiredNativeLibs even when
2111*333d2b36SAndroid Build Coastguard Worker			// DepIsInSameAPex is false. We also shouldn't do
2112*333d2b36SAndroid Build Coastguard Worker			// this for host.
2113*333d2b36SAndroid Build Coastguard Worker			//
2114*333d2b36SAndroid Build Coastguard Worker			// TODO(jiyong): explain why the same module is passed in twice.
2115*333d2b36SAndroid Build Coastguard Worker			// Switching the first am to parent breaks lots of tests.
2116*333d2b36SAndroid Build Coastguard Worker			if !android.IsDepInSameApex(ctx, am, am) {
2117*333d2b36SAndroid Build Coastguard Worker				return false
2118*333d2b36SAndroid Build Coastguard Worker			}
2119*333d2b36SAndroid Build Coastguard Worker
2120*333d2b36SAndroid Build Coastguard Worker			vctx.filesInfo = append(vctx.filesInfo, af)
2121*333d2b36SAndroid Build Coastguard Worker			return true // track transitive dependencies
2122*333d2b36SAndroid Build Coastguard Worker		} else if rm, ok := child.(*rust.Module); ok {
2123*333d2b36SAndroid Build Coastguard Worker			if !android.IsDepInSameApex(ctx, am, am) {
2124*333d2b36SAndroid Build Coastguard Worker				return false
2125*333d2b36SAndroid Build Coastguard Worker			}
2126*333d2b36SAndroid Build Coastguard Worker
2127*333d2b36SAndroid Build Coastguard Worker			af := apexFileForRustLibrary(ctx, rm)
2128*333d2b36SAndroid Build Coastguard Worker			af.transitiveDep = true
2129*333d2b36SAndroid Build Coastguard Worker			vctx.filesInfo = append(vctx.filesInfo, af)
2130*333d2b36SAndroid Build Coastguard Worker			return true // track transitive dependencies
2131*333d2b36SAndroid Build Coastguard Worker		}
2132*333d2b36SAndroid Build Coastguard Worker	} else if cc.IsHeaderDepTag(depTag) {
2133*333d2b36SAndroid Build Coastguard Worker		// nothing
2134*333d2b36SAndroid Build Coastguard Worker	} else if java.IsJniDepTag(depTag) {
2135*333d2b36SAndroid Build Coastguard Worker		// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2136*333d2b36SAndroid Build Coastguard Worker	} else if java.IsXmlPermissionsFileDepTag(depTag) {
2137*333d2b36SAndroid Build Coastguard Worker		if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2138*333d2b36SAndroid Build Coastguard Worker			filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "")
2139*333d2b36SAndroid Build Coastguard Worker			for _, etcFile := range filesToCopy {
2140*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
2141*333d2b36SAndroid Build Coastguard Worker			}
2142*333d2b36SAndroid Build Coastguard Worker		}
2143*333d2b36SAndroid Build Coastguard Worker	} else if rust.IsDylibDepTag(depTag) {
2144*333d2b36SAndroid Build Coastguard Worker		if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
2145*333d2b36SAndroid Build Coastguard Worker			if !android.IsDepInSameApex(ctx, am, am) {
2146*333d2b36SAndroid Build Coastguard Worker				return false
2147*333d2b36SAndroid Build Coastguard Worker			}
2148*333d2b36SAndroid Build Coastguard Worker
2149*333d2b36SAndroid Build Coastguard Worker			af := apexFileForRustLibrary(ctx, rustm)
2150*333d2b36SAndroid Build Coastguard Worker			af.transitiveDep = true
2151*333d2b36SAndroid Build Coastguard Worker			vctx.filesInfo = append(vctx.filesInfo, af)
2152*333d2b36SAndroid Build Coastguard Worker			return true // track transitive dependencies
2153*333d2b36SAndroid Build Coastguard Worker		}
2154*333d2b36SAndroid Build Coastguard Worker	} else if rust.IsRlibDepTag(depTag) {
2155*333d2b36SAndroid Build Coastguard Worker		// Rlib is statically linked, but it might have shared lib
2156*333d2b36SAndroid Build Coastguard Worker		// dependencies. Track them.
2157*333d2b36SAndroid Build Coastguard Worker		return true
2158*333d2b36SAndroid Build Coastguard Worker	} else if java.IsBootclasspathFragmentContentDepTag(depTag) {
2159*333d2b36SAndroid Build Coastguard Worker		// Add the contents of the bootclasspath fragment to the apex.
2160*333d2b36SAndroid Build Coastguard Worker		switch child.(type) {
2161*333d2b36SAndroid Build Coastguard Worker		case *java.Library, *java.SdkLibrary:
2162*333d2b36SAndroid Build Coastguard Worker			javaModule := child.(javaModule)
2163*333d2b36SAndroid Build Coastguard Worker			af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
2164*333d2b36SAndroid Build Coastguard Worker			if !af.ok() {
2165*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("bootclasspath_fragments",
2166*333d2b36SAndroid Build Coastguard Worker					"bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
2167*333d2b36SAndroid Build Coastguard Worker				return false
2168*333d2b36SAndroid Build Coastguard Worker			}
2169*333d2b36SAndroid Build Coastguard Worker			vctx.filesInfo = append(vctx.filesInfo, af)
2170*333d2b36SAndroid Build Coastguard Worker			return true // track transitive dependencies
2171*333d2b36SAndroid Build Coastguard Worker		default:
2172*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("bootclasspath_fragments",
2173*333d2b36SAndroid Build Coastguard Worker				"bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2174*333d2b36SAndroid Build Coastguard Worker		}
2175*333d2b36SAndroid Build Coastguard Worker	} else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
2176*333d2b36SAndroid Build Coastguard Worker		// Add the contents of the systemserverclasspath fragment to the apex.
2177*333d2b36SAndroid Build Coastguard Worker		switch child.(type) {
2178*333d2b36SAndroid Build Coastguard Worker		case *java.Library, *java.SdkLibrary:
2179*333d2b36SAndroid Build Coastguard Worker			af := apexFileForJavaModule(ctx, child.(javaModule))
2180*333d2b36SAndroid Build Coastguard Worker			vctx.filesInfo = append(vctx.filesInfo, af)
2181*333d2b36SAndroid Build Coastguard Worker			if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil {
2182*333d2b36SAndroid Build Coastguard Worker				vctx.filesInfo = append(vctx.filesInfo, *profileAf)
2183*333d2b36SAndroid Build Coastguard Worker			}
2184*333d2b36SAndroid Build Coastguard Worker			return true // track transitive dependencies
2185*333d2b36SAndroid Build Coastguard Worker		default:
2186*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("systemserverclasspath_fragments",
2187*333d2b36SAndroid Build Coastguard Worker				"systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
2188*333d2b36SAndroid Build Coastguard Worker		}
2189*333d2b36SAndroid Build Coastguard Worker	} else if depTag == android.DarwinUniversalVariantTag {
2190*333d2b36SAndroid Build Coastguard Worker		// nothing
2191*333d2b36SAndroid Build Coastguard Worker	} else if depTag == android.RequiredDepTag {
2192*333d2b36SAndroid Build Coastguard Worker		// nothing
2193*333d2b36SAndroid Build Coastguard Worker	} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2194*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2195*333d2b36SAndroid Build Coastguard Worker	}
2196*333d2b36SAndroid Build Coastguard Worker	return false
2197*333d2b36SAndroid Build Coastguard Worker}
2198*333d2b36SAndroid Build Coastguard Worker
2199*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
2200*333d2b36SAndroid Build Coastguard Worker	// TODO(b/263308293) remove this
2201*333d2b36SAndroid Build Coastguard Worker	if a.properties.IsCoverageVariant {
2202*333d2b36SAndroid Build Coastguard Worker		return false
2203*333d2b36SAndroid Build Coastguard Worker	}
2204*333d2b36SAndroid Build Coastguard Worker	if ctx.DeviceConfig().DeviceArch() == "" {
2205*333d2b36SAndroid Build Coastguard Worker		return false
2206*333d2b36SAndroid Build Coastguard Worker	}
2207*333d2b36SAndroid Build Coastguard Worker	return true
2208*333d2b36SAndroid Build Coastguard Worker}
2209*333d2b36SAndroid Build Coastguard Worker
2210*333d2b36SAndroid Build Coastguard Worker// Creates build rules for an APEX. It consists of the following major steps:
2211*333d2b36SAndroid Build Coastguard Worker//
2212*333d2b36SAndroid Build Coastguard Worker// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2213*333d2b36SAndroid Build Coastguard Worker// 2) traverse the dependency tree to collect apexFile structs from them.
2214*333d2b36SAndroid Build Coastguard Worker// 3) some fields in apexBundle struct are configured
2215*333d2b36SAndroid Build Coastguard Worker// 4) generate the build rules to create the APEX. This is mostly done in builder.go.
2216*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2217*333d2b36SAndroid Build Coastguard Worker	////////////////////////////////////////////////////////////////////////////////////////////
2218*333d2b36SAndroid Build Coastguard Worker	// 1) do some validity checks such as apex_available, min_sdk_version, etc.
2219*333d2b36SAndroid Build Coastguard Worker	if !a.commonBuildActions(ctx) {
2220*333d2b36SAndroid Build Coastguard Worker		return
2221*333d2b36SAndroid Build Coastguard Worker	}
2222*333d2b36SAndroid Build Coastguard Worker	////////////////////////////////////////////////////////////////////////////////////////////
2223*333d2b36SAndroid Build Coastguard Worker	// 2) traverse the dependency tree to collect apexFile structs from them.
2224*333d2b36SAndroid Build Coastguard Worker
2225*333d2b36SAndroid Build Coastguard Worker	// TODO(jiyong): do this using WalkPayloadDeps
2226*333d2b36SAndroid Build Coastguard Worker	// TODO(jiyong): make this clean!!!
2227*333d2b36SAndroid Build Coastguard Worker	vctx := visitorContext{
2228*333d2b36SAndroid Build Coastguard Worker		handleSpecialLibs:      !android.Bool(a.properties.Ignore_system_library_special_case),
2229*333d2b36SAndroid Build Coastguard Worker		checkDuplicate:         a.shouldCheckDuplicate(ctx),
2230*333d2b36SAndroid Build Coastguard Worker		unwantedTransitiveDeps: a.properties.Unwanted_transitive_deps,
2231*333d2b36SAndroid Build Coastguard Worker	}
2232*333d2b36SAndroid Build Coastguard Worker	ctx.WalkDeps(func(child, parent android.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
2233*333d2b36SAndroid Build Coastguard Worker	vctx.normalizeFileInfo(ctx)
2234*333d2b36SAndroid Build Coastguard Worker	if a.privateKeyFile == nil {
2235*333d2b36SAndroid Build Coastguard Worker		if ctx.Config().AllowMissingDependencies() {
2236*333d2b36SAndroid Build Coastguard Worker			// TODO(b/266099037): a better approach for slim manifests.
2237*333d2b36SAndroid Build Coastguard Worker			ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
2238*333d2b36SAndroid Build Coastguard Worker			// Create placeholder paths for later stages that expect to see those paths,
2239*333d2b36SAndroid Build Coastguard Worker			// though they won't be used.
2240*333d2b36SAndroid Build Coastguard Worker			var unusedPath = android.PathForModuleOut(ctx, "nonexistentprivatekey")
2241*333d2b36SAndroid Build Coastguard Worker			ctx.Build(pctx, android.BuildParams{
2242*333d2b36SAndroid Build Coastguard Worker				Rule:   android.ErrorRule,
2243*333d2b36SAndroid Build Coastguard Worker				Output: unusedPath,
2244*333d2b36SAndroid Build Coastguard Worker				Args: map[string]string{
2245*333d2b36SAndroid Build Coastguard Worker					"error": "Private key not available",
2246*333d2b36SAndroid Build Coastguard Worker				},
2247*333d2b36SAndroid Build Coastguard Worker			})
2248*333d2b36SAndroid Build Coastguard Worker			a.privateKeyFile = unusedPath
2249*333d2b36SAndroid Build Coastguard Worker		} else {
2250*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
2251*333d2b36SAndroid Build Coastguard Worker			return
2252*333d2b36SAndroid Build Coastguard Worker		}
2253*333d2b36SAndroid Build Coastguard Worker	}
2254*333d2b36SAndroid Build Coastguard Worker
2255*333d2b36SAndroid Build Coastguard Worker	if a.publicKeyFile == nil {
2256*333d2b36SAndroid Build Coastguard Worker		if ctx.Config().AllowMissingDependencies() {
2257*333d2b36SAndroid Build Coastguard Worker			// TODO(b/266099037): a better approach for slim manifests.
2258*333d2b36SAndroid Build Coastguard Worker			ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)})
2259*333d2b36SAndroid Build Coastguard Worker			// Create placeholder paths for later stages that expect to see those paths,
2260*333d2b36SAndroid Build Coastguard Worker			// though they won't be used.
2261*333d2b36SAndroid Build Coastguard Worker			var unusedPath = android.PathForModuleOut(ctx, "nonexistentpublickey")
2262*333d2b36SAndroid Build Coastguard Worker			ctx.Build(pctx, android.BuildParams{
2263*333d2b36SAndroid Build Coastguard Worker				Rule:   android.ErrorRule,
2264*333d2b36SAndroid Build Coastguard Worker				Output: unusedPath,
2265*333d2b36SAndroid Build Coastguard Worker				Args: map[string]string{
2266*333d2b36SAndroid Build Coastguard Worker					"error": "Public key not available",
2267*333d2b36SAndroid Build Coastguard Worker				},
2268*333d2b36SAndroid Build Coastguard Worker			})
2269*333d2b36SAndroid Build Coastguard Worker			a.publicKeyFile = unusedPath
2270*333d2b36SAndroid Build Coastguard Worker		} else {
2271*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("key", "public_key for %q could not be found", String(a.overridableProperties.Key))
2272*333d2b36SAndroid Build Coastguard Worker			return
2273*333d2b36SAndroid Build Coastguard Worker		}
2274*333d2b36SAndroid Build Coastguard Worker	}
2275*333d2b36SAndroid Build Coastguard Worker
2276*333d2b36SAndroid Build Coastguard Worker	////////////////////////////////////////////////////////////////////////////////////////////
2277*333d2b36SAndroid Build Coastguard Worker	// 3) some fields in apexBundle struct are configured
2278*333d2b36SAndroid Build Coastguard Worker	a.installDir = android.PathForModuleInstall(ctx, "apex")
2279*333d2b36SAndroid Build Coastguard Worker	a.filesInfo = vctx.filesInfo
2280*333d2b36SAndroid Build Coastguard Worker	a.unwantedTransitiveFilesInfo = vctx.unwantedTransitiveFilesInfo
2281*333d2b36SAndroid Build Coastguard Worker	a.duplicateTransitiveFilesInfo = vctx.duplicateTransitiveFilesInfo
2282*333d2b36SAndroid Build Coastguard Worker
2283*333d2b36SAndroid Build Coastguard Worker	a.setPayloadFsType(ctx)
2284*333d2b36SAndroid Build Coastguard Worker	a.setSystemLibLink(ctx)
2285*333d2b36SAndroid Build Coastguard Worker	a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
2286*333d2b36SAndroid Build Coastguard Worker
2287*333d2b36SAndroid Build Coastguard Worker	////////////////////////////////////////////////////////////////////////////////////////////
2288*333d2b36SAndroid Build Coastguard Worker	// 3.a) some artifacts are generated from the collected files
2289*333d2b36SAndroid Build Coastguard Worker	a.filesInfo = append(a.filesInfo, a.buildAconfigFiles(ctx)...)
2290*333d2b36SAndroid Build Coastguard Worker
2291*333d2b36SAndroid Build Coastguard Worker	////////////////////////////////////////////////////////////////////////////////////////////
2292*333d2b36SAndroid Build Coastguard Worker	// 4) generate the build rules to create the APEX. This is done in builder.go.
2293*333d2b36SAndroid Build Coastguard Worker	a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
2294*333d2b36SAndroid Build Coastguard Worker	a.buildApex(ctx)
2295*333d2b36SAndroid Build Coastguard Worker	a.buildApexDependencyInfo(ctx)
2296*333d2b36SAndroid Build Coastguard Worker	a.buildLintReports(ctx)
2297*333d2b36SAndroid Build Coastguard Worker
2298*333d2b36SAndroid Build Coastguard Worker	// Set a provider for dexpreopt of bootjars
2299*333d2b36SAndroid Build Coastguard Worker	a.provideApexExportsInfo(ctx)
2300*333d2b36SAndroid Build Coastguard Worker
2301*333d2b36SAndroid Build Coastguard Worker	a.providePrebuiltInfo(ctx)
2302*333d2b36SAndroid Build Coastguard Worker
2303*333d2b36SAndroid Build Coastguard Worker	a.required = a.RequiredModuleNames(ctx)
2304*333d2b36SAndroid Build Coastguard Worker	a.required = append(a.required, a.VintfFragmentModuleNames(ctx)...)
2305*333d2b36SAndroid Build Coastguard Worker
2306*333d2b36SAndroid Build Coastguard Worker	a.setOutputFiles(ctx)
2307*333d2b36SAndroid Build Coastguard Worker	a.enforcePartitionTagOnApexSystemServerJar(ctx)
2308*333d2b36SAndroid Build Coastguard Worker
2309*333d2b36SAndroid Build Coastguard Worker	a.verifyNativeImplementationLibs(ctx)
2310*333d2b36SAndroid Build Coastguard Worker}
2311*333d2b36SAndroid Build Coastguard Worker
2312*333d2b36SAndroid Build Coastguard Worker// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
2313*333d2b36SAndroid Build Coastguard Worker// with information about whether source or prebuilt of an apex was used during the build.
2314*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) providePrebuiltInfo(ctx android.ModuleContext) {
2315*333d2b36SAndroid Build Coastguard Worker	info := android.PrebuiltInfo{
2316*333d2b36SAndroid Build Coastguard Worker		Name:        a.Name(),
2317*333d2b36SAndroid Build Coastguard Worker		Is_prebuilt: false,
2318*333d2b36SAndroid Build Coastguard Worker	}
2319*333d2b36SAndroid Build Coastguard Worker	android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
2320*333d2b36SAndroid Build Coastguard Worker}
2321*333d2b36SAndroid Build Coastguard Worker
2322*333d2b36SAndroid Build Coastguard Worker// Set a provider containing information about the jars and .prof provided by the apex
2323*333d2b36SAndroid Build Coastguard Worker// Apexes built from source retrieve this information by visiting `bootclasspath_fragments`
2324*333d2b36SAndroid Build Coastguard Worker// Used by dex_bootjars to generate the boot image
2325*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) provideApexExportsInfo(ctx android.ModuleContext) {
2326*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxyWithTag(bcpfTag, func(child android.ModuleProxy) {
2327*333d2b36SAndroid Build Coastguard Worker		if info, ok := android.OtherModuleProvider(ctx, child, java.BootclasspathFragmentApexContentInfoProvider); ok {
2328*333d2b36SAndroid Build Coastguard Worker			exports := android.ApexExportsInfo{
2329*333d2b36SAndroid Build Coastguard Worker				ApexName:                      a.ApexVariationName(),
2330*333d2b36SAndroid Build Coastguard Worker				ProfilePathOnHost:             info.ProfilePathOnHost(),
2331*333d2b36SAndroid Build Coastguard Worker				LibraryNameToDexJarPathOnHost: info.DexBootJarPathMap(),
2332*333d2b36SAndroid Build Coastguard Worker			}
2333*333d2b36SAndroid Build Coastguard Worker			android.SetProvider(ctx, android.ApexExportsInfoProvider, exports)
2334*333d2b36SAndroid Build Coastguard Worker		}
2335*333d2b36SAndroid Build Coastguard Worker	})
2336*333d2b36SAndroid Build Coastguard Worker}
2337*333d2b36SAndroid Build Coastguard Worker
2338*333d2b36SAndroid Build Coastguard Worker// Set output files to outputFiles property, which is later used to set the
2339*333d2b36SAndroid Build Coastguard Worker// OutputFilesProvider
2340*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) setOutputFiles(ctx android.ModuleContext) {
2341*333d2b36SAndroid Build Coastguard Worker	// default dist path
2342*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(android.Paths{a.outputFile}, "")
2343*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(android.Paths{a.outputFile}, android.DefaultDistTag)
2344*333d2b36SAndroid Build Coastguard Worker	// uncompressed one
2345*333d2b36SAndroid Build Coastguard Worker	if a.outputApexFile != nil {
2346*333d2b36SAndroid Build Coastguard Worker		ctx.SetOutputFiles(android.Paths{a.outputApexFile}, imageApexSuffix)
2347*333d2b36SAndroid Build Coastguard Worker	}
2348*333d2b36SAndroid Build Coastguard Worker}
2349*333d2b36SAndroid Build Coastguard Worker
2350*333d2b36SAndroid Build Coastguard Worker// enforceAppUpdatability propagates updatable=true to apps of updatable apexes
2351*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) enforceAppUpdatability(mctx android.ModuleContext) {
2352*333d2b36SAndroid Build Coastguard Worker	if !a.Enabled(mctx) {
2353*333d2b36SAndroid Build Coastguard Worker		return
2354*333d2b36SAndroid Build Coastguard Worker	}
2355*333d2b36SAndroid Build Coastguard Worker	if a.Updatable() {
2356*333d2b36SAndroid Build Coastguard Worker		// checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults
2357*333d2b36SAndroid Build Coastguard Worker		mctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
2358*333d2b36SAndroid Build Coastguard Worker			if appInfo, ok := android.OtherModuleProvider(mctx, module, java.AppInfoProvider); ok {
2359*333d2b36SAndroid Build Coastguard Worker				// ignore android_test_app
2360*333d2b36SAndroid Build Coastguard Worker				if !appInfo.TestHelperApp && !appInfo.Updatable {
2361*333d2b36SAndroid Build Coastguard Worker					mctx.ModuleErrorf("app dependency %s must have updatable: true", mctx.OtherModuleName(module))
2362*333d2b36SAndroid Build Coastguard Worker				}
2363*333d2b36SAndroid Build Coastguard Worker			}
2364*333d2b36SAndroid Build Coastguard Worker		})
2365*333d2b36SAndroid Build Coastguard Worker	}
2366*333d2b36SAndroid Build Coastguard Worker}
2367*333d2b36SAndroid Build Coastguard Worker
2368*333d2b36SAndroid Build Coastguard Worker// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
2369*333d2b36SAndroid Build Coastguard Worker// the bootclasspath_fragment contributes to the apex.
2370*333d2b36SAndroid Build Coastguard Workerfunc apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
2371*333d2b36SAndroid Build Coastguard Worker	bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, module, java.BootclasspathFragmentApexContentInfoProvider)
2372*333d2b36SAndroid Build Coastguard Worker	var filesToAdd []apexFile
2373*333d2b36SAndroid Build Coastguard Worker
2374*333d2b36SAndroid Build Coastguard Worker	// Add classpaths.proto config.
2375*333d2b36SAndroid Build Coastguard Worker	if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
2376*333d2b36SAndroid Build Coastguard Worker		filesToAdd = append(filesToAdd, *af)
2377*333d2b36SAndroid Build Coastguard Worker	}
2378*333d2b36SAndroid Build Coastguard Worker
2379*333d2b36SAndroid Build Coastguard Worker	pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
2380*333d2b36SAndroid Build Coastguard Worker	if pathInApex != "" {
2381*333d2b36SAndroid Build Coastguard Worker		pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
2382*333d2b36SAndroid Build Coastguard Worker		tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
2383*333d2b36SAndroid Build Coastguard Worker
2384*333d2b36SAndroid Build Coastguard Worker		if pathOnHost != nil {
2385*333d2b36SAndroid Build Coastguard Worker			// We need to copy the profile to a temporary path with the right filename because the apexer
2386*333d2b36SAndroid Build Coastguard Worker			// will take the filename as is.
2387*333d2b36SAndroid Build Coastguard Worker			ctx.Build(pctx, android.BuildParams{
2388*333d2b36SAndroid Build Coastguard Worker				Rule:   android.Cp,
2389*333d2b36SAndroid Build Coastguard Worker				Input:  pathOnHost,
2390*333d2b36SAndroid Build Coastguard Worker				Output: tempPath,
2391*333d2b36SAndroid Build Coastguard Worker			})
2392*333d2b36SAndroid Build Coastguard Worker		} else {
2393*333d2b36SAndroid Build Coastguard Worker			// At this point, the boot image profile cannot be generated. It is probably because the boot
2394*333d2b36SAndroid Build Coastguard Worker			// image profile source file does not exist on the branch, or it is not available for the
2395*333d2b36SAndroid Build Coastguard Worker			// current build target.
2396*333d2b36SAndroid Build Coastguard Worker			// However, we cannot enforce the boot image profile to be generated because some build
2397*333d2b36SAndroid Build Coastguard Worker			// targets (such as module SDK) do not need it. It is only needed when the APEX is being
2398*333d2b36SAndroid Build Coastguard Worker			// built. Therefore, we create an error rule so that an error will occur at the ninja phase
2399*333d2b36SAndroid Build Coastguard Worker			// only if the APEX is being built.
2400*333d2b36SAndroid Build Coastguard Worker			ctx.Build(pctx, android.BuildParams{
2401*333d2b36SAndroid Build Coastguard Worker				Rule:   android.ErrorRule,
2402*333d2b36SAndroid Build Coastguard Worker				Output: tempPath,
2403*333d2b36SAndroid Build Coastguard Worker				Args: map[string]string{
2404*333d2b36SAndroid Build Coastguard Worker					"error": "Boot image profile cannot be generated",
2405*333d2b36SAndroid Build Coastguard Worker				},
2406*333d2b36SAndroid Build Coastguard Worker			})
2407*333d2b36SAndroid Build Coastguard Worker		}
2408*333d2b36SAndroid Build Coastguard Worker
2409*333d2b36SAndroid Build Coastguard Worker		androidMkModuleName := filepath.Base(pathInApex)
2410*333d2b36SAndroid Build Coastguard Worker		af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
2411*333d2b36SAndroid Build Coastguard Worker		filesToAdd = append(filesToAdd, af)
2412*333d2b36SAndroid Build Coastguard Worker	}
2413*333d2b36SAndroid Build Coastguard Worker
2414*333d2b36SAndroid Build Coastguard Worker	return filesToAdd
2415*333d2b36SAndroid Build Coastguard Worker}
2416*333d2b36SAndroid Build Coastguard Worker
2417*333d2b36SAndroid Build Coastguard Worker// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
2418*333d2b36SAndroid Build Coastguard Worker// the module contributes to the apex; or nil if the proto config was not generated.
2419*333d2b36SAndroid Build Coastguard Workerfunc apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
2420*333d2b36SAndroid Build Coastguard Worker	info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider)
2421*333d2b36SAndroid Build Coastguard Worker	if !info.ClasspathFragmentProtoGenerated {
2422*333d2b36SAndroid Build Coastguard Worker		return nil
2423*333d2b36SAndroid Build Coastguard Worker	}
2424*333d2b36SAndroid Build Coastguard Worker	classpathProtoOutput := info.ClasspathFragmentProtoOutput
2425*333d2b36SAndroid Build Coastguard Worker	af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
2426*333d2b36SAndroid Build Coastguard Worker	return &af
2427*333d2b36SAndroid Build Coastguard Worker}
2428*333d2b36SAndroid Build Coastguard Worker
2429*333d2b36SAndroid Build Coastguard Worker// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
2430*333d2b36SAndroid Build Coastguard Worker// content module, i.e. a library that is part of the bootclasspath.
2431*333d2b36SAndroid Build Coastguard Workerfunc apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
2432*333d2b36SAndroid Build Coastguard Worker	bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragmentModule, java.BootclasspathFragmentApexContentInfoProvider)
2433*333d2b36SAndroid Build Coastguard Worker
2434*333d2b36SAndroid Build Coastguard Worker	// Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
2435*333d2b36SAndroid Build Coastguard Worker	// hidden API encpding.
2436*333d2b36SAndroid Build Coastguard Worker	dexBootJar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
2437*333d2b36SAndroid Build Coastguard Worker	if err != nil {
2438*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("%s", err)
2439*333d2b36SAndroid Build Coastguard Worker	}
2440*333d2b36SAndroid Build Coastguard Worker
2441*333d2b36SAndroid Build Coastguard Worker	// Create an apexFile as for a normal java module but with the dex boot jar provided by the
2442*333d2b36SAndroid Build Coastguard Worker	// bootclasspath_fragment.
2443*333d2b36SAndroid Build Coastguard Worker	af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
2444*333d2b36SAndroid Build Coastguard Worker	return af
2445*333d2b36SAndroid Build Coastguard Worker}
2446*333d2b36SAndroid Build Coastguard Worker
2447*333d2b36SAndroid Build Coastguard Worker///////////////////////////////////////////////////////////////////////////////////////////////////
2448*333d2b36SAndroid Build Coastguard Worker// Factory functions
2449*333d2b36SAndroid Build Coastguard Worker//
2450*333d2b36SAndroid Build Coastguard Worker
2451*333d2b36SAndroid Build Coastguard Workerfunc newApexBundle() *apexBundle {
2452*333d2b36SAndroid Build Coastguard Worker	module := &apexBundle{}
2453*333d2b36SAndroid Build Coastguard Worker
2454*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
2455*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.targetProperties)
2456*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.archProperties)
2457*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.overridableProperties)
2458*333d2b36SAndroid Build Coastguard Worker
2459*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
2460*333d2b36SAndroid Build Coastguard Worker	android.InitDefaultableModule(module)
2461*333d2b36SAndroid Build Coastguard Worker	android.InitOverridableModule(module, &module.overridableProperties.Overrides)
2462*333d2b36SAndroid Build Coastguard Worker	return module
2463*333d2b36SAndroid Build Coastguard Worker}
2464*333d2b36SAndroid Build Coastguard Worker
2465*333d2b36SAndroid Build Coastguard Workertype apexTestProperties struct {
2466*333d2b36SAndroid Build Coastguard Worker	// Boolean flags for validation checks. Test APEXes can turn on/off individual checks.
2467*333d2b36SAndroid Build Coastguard Worker	Skip_validations struct {
2468*333d2b36SAndroid Build Coastguard Worker		// Skips `Apex_sepolicy_tests` check if true
2469*333d2b36SAndroid Build Coastguard Worker		Apex_sepolicy_tests *bool
2470*333d2b36SAndroid Build Coastguard Worker		// Skips `Host_apex_verifier` check if true
2471*333d2b36SAndroid Build Coastguard Worker		Host_apex_verifier *bool
2472*333d2b36SAndroid Build Coastguard Worker	}
2473*333d2b36SAndroid Build Coastguard Worker}
2474*333d2b36SAndroid Build Coastguard Worker
2475*333d2b36SAndroid Build Coastguard Worker// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2476*333d2b36SAndroid Build Coastguard Worker// certain compatibility checks such as apex_available are not done for apex_test.
2477*333d2b36SAndroid Build Coastguard Workerfunc TestApexBundleFactory() android.Module {
2478*333d2b36SAndroid Build Coastguard Worker	bundle := newApexBundle()
2479*333d2b36SAndroid Build Coastguard Worker	bundle.testApex = true
2480*333d2b36SAndroid Build Coastguard Worker	bundle.AddProperties(&bundle.testProperties)
2481*333d2b36SAndroid Build Coastguard Worker	return bundle
2482*333d2b36SAndroid Build Coastguard Worker}
2483*333d2b36SAndroid Build Coastguard Worker
2484*333d2b36SAndroid Build Coastguard Worker// apex packages other modules into an APEX file which is a packaging format for system-level
2485*333d2b36SAndroid Build Coastguard Worker// components like binaries, shared libraries, etc.
2486*333d2b36SAndroid Build Coastguard Workerfunc BundleFactory() android.Module {
2487*333d2b36SAndroid Build Coastguard Worker	return newApexBundle()
2488*333d2b36SAndroid Build Coastguard Worker}
2489*333d2b36SAndroid Build Coastguard Worker
2490*333d2b36SAndroid Build Coastguard Workertype Defaults struct {
2491*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
2492*333d2b36SAndroid Build Coastguard Worker	android.DefaultsModuleBase
2493*333d2b36SAndroid Build Coastguard Worker}
2494*333d2b36SAndroid Build Coastguard Worker
2495*333d2b36SAndroid Build Coastguard Worker// apex_defaults provides defaultable properties to other apex modules.
2496*333d2b36SAndroid Build Coastguard Workerfunc DefaultsFactory() android.Module {
2497*333d2b36SAndroid Build Coastguard Worker	module := &Defaults{}
2498*333d2b36SAndroid Build Coastguard Worker
2499*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(
2500*333d2b36SAndroid Build Coastguard Worker		&apexBundleProperties{},
2501*333d2b36SAndroid Build Coastguard Worker		&apexTargetBundleProperties{},
2502*333d2b36SAndroid Build Coastguard Worker		&apexArchBundleProperties{},
2503*333d2b36SAndroid Build Coastguard Worker		&overridableProperties{},
2504*333d2b36SAndroid Build Coastguard Worker	)
2505*333d2b36SAndroid Build Coastguard Worker
2506*333d2b36SAndroid Build Coastguard Worker	android.InitDefaultsModule(module)
2507*333d2b36SAndroid Build Coastguard Worker	return module
2508*333d2b36SAndroid Build Coastguard Worker}
2509*333d2b36SAndroid Build Coastguard Worker
2510*333d2b36SAndroid Build Coastguard Workertype OverrideApex struct {
2511*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
2512*333d2b36SAndroid Build Coastguard Worker	android.OverrideModuleBase
2513*333d2b36SAndroid Build Coastguard Worker}
2514*333d2b36SAndroid Build Coastguard Worker
2515*333d2b36SAndroid Build Coastguard Workerfunc (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
2516*333d2b36SAndroid Build Coastguard Worker	// All the overrides happen in the base module.
2517*333d2b36SAndroid Build Coastguard Worker}
2518*333d2b36SAndroid Build Coastguard Worker
2519*333d2b36SAndroid Build Coastguard Worker// override_apex is used to create an apex module based on another apex module by overriding some of
2520*333d2b36SAndroid Build Coastguard Worker// its properties.
2521*333d2b36SAndroid Build Coastguard Workerfunc OverrideApexFactory() android.Module {
2522*333d2b36SAndroid Build Coastguard Worker	m := &OverrideApex{}
2523*333d2b36SAndroid Build Coastguard Worker
2524*333d2b36SAndroid Build Coastguard Worker	m.AddProperties(&overridableProperties{})
2525*333d2b36SAndroid Build Coastguard Worker
2526*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2527*333d2b36SAndroid Build Coastguard Worker	android.InitOverrideModule(m)
2528*333d2b36SAndroid Build Coastguard Worker	return m
2529*333d2b36SAndroid Build Coastguard Worker}
2530*333d2b36SAndroid Build Coastguard Worker
2531*333d2b36SAndroid Build Coastguard Worker///////////////////////////////////////////////////////////////////////////////////////////////////
2532*333d2b36SAndroid Build Coastguard Worker// Vality check routines
2533*333d2b36SAndroid Build Coastguard Worker//
2534*333d2b36SAndroid Build Coastguard Worker// These are called in at the very beginning of GenerateAndroidBuildActions to flag an error when
2535*333d2b36SAndroid Build Coastguard Worker// certain conditions are not met.
2536*333d2b36SAndroid Build Coastguard Worker//
2537*333d2b36SAndroid Build Coastguard Worker// TODO(jiyong): move these checks to a separate go file.
2538*333d2b36SAndroid Build Coastguard Worker
2539*333d2b36SAndroid Build Coastguard Workervar _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil)
2540*333d2b36SAndroid Build Coastguard Worker
2541*333d2b36SAndroid Build Coastguard Worker// Ensures that min_sdk_version of the included modules are equal or less than the min_sdk_version
2542*333d2b36SAndroid Build Coastguard Worker// of this apexBundle.
2543*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) {
2544*333d2b36SAndroid Build Coastguard Worker	if a.testApex || a.vndkApex {
2545*333d2b36SAndroid Build Coastguard Worker		return
2546*333d2b36SAndroid Build Coastguard Worker	}
2547*333d2b36SAndroid Build Coastguard Worker	// apexBundle::minSdkVersion reports its own errors.
2548*333d2b36SAndroid Build Coastguard Worker	minSdkVersion := a.minSdkVersion(ctx)
2549*333d2b36SAndroid Build Coastguard Worker	android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
2550*333d2b36SAndroid Build Coastguard Worker}
2551*333d2b36SAndroid Build Coastguard Worker
2552*333d2b36SAndroid Build Coastguard Worker// Returns apex's min_sdk_version string value, honoring overrides
2553*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
2554*333d2b36SAndroid Build Coastguard Worker	// Only override the minSdkVersion value on Apexes which already specify
2555*333d2b36SAndroid Build Coastguard Worker	// a min_sdk_version (it's optional for non-updatable apexes), and that its
2556*333d2b36SAndroid Build Coastguard Worker	// min_sdk_version value is lower than the one to override with.
2557*333d2b36SAndroid Build Coastguard Worker	minApiLevel := android.MinSdkVersionFromValue(ctx, proptools.String(a.overridableProperties.Min_sdk_version))
2558*333d2b36SAndroid Build Coastguard Worker	if minApiLevel.IsNone() {
2559*333d2b36SAndroid Build Coastguard Worker		return ""
2560*333d2b36SAndroid Build Coastguard Worker	}
2561*333d2b36SAndroid Build Coastguard Worker
2562*333d2b36SAndroid Build Coastguard Worker	overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
2563*333d2b36SAndroid Build Coastguard Worker	overrideApiLevel := android.MinSdkVersionFromValue(ctx, overrideMinSdkValue)
2564*333d2b36SAndroid Build Coastguard Worker	if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
2565*333d2b36SAndroid Build Coastguard Worker		minApiLevel = overrideApiLevel
2566*333d2b36SAndroid Build Coastguard Worker	}
2567*333d2b36SAndroid Build Coastguard Worker
2568*333d2b36SAndroid Build Coastguard Worker	return minApiLevel.String()
2569*333d2b36SAndroid Build Coastguard Worker}
2570*333d2b36SAndroid Build Coastguard Worker
2571*333d2b36SAndroid Build Coastguard Worker// Returns apex's min_sdk_version SdkSpec, honoring overrides
2572*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
2573*333d2b36SAndroid Build Coastguard Worker	return a.minSdkVersion(ctx)
2574*333d2b36SAndroid Build Coastguard Worker}
2575*333d2b36SAndroid Build Coastguard Worker
2576*333d2b36SAndroid Build Coastguard Worker// Returns apex's min_sdk_version ApiLevel, honoring overrides
2577*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
2578*333d2b36SAndroid Build Coastguard Worker	return android.MinSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
2579*333d2b36SAndroid Build Coastguard Worker}
2580*333d2b36SAndroid Build Coastguard Worker
2581*333d2b36SAndroid Build Coastguard Worker// Ensures that a lib providing stub isn't statically linked
2582*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
2583*333d2b36SAndroid Build Coastguard Worker	// Practically, we only care about regular APEXes on the device.
2584*333d2b36SAndroid Build Coastguard Worker	if a.testApex || a.vndkApex {
2585*333d2b36SAndroid Build Coastguard Worker		return
2586*333d2b36SAndroid Build Coastguard Worker	}
2587*333d2b36SAndroid Build Coastguard Worker
2588*333d2b36SAndroid Build Coastguard Worker	librariesDirectlyInApex := make(map[string]bool)
2589*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxyWithTag(sharedLibTag, func(dep android.ModuleProxy) {
2590*333d2b36SAndroid Build Coastguard Worker		librariesDirectlyInApex[ctx.OtherModuleName(dep)] = true
2591*333d2b36SAndroid Build Coastguard Worker	})
2592*333d2b36SAndroid Build Coastguard Worker
2593*333d2b36SAndroid Build Coastguard Worker	a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
2594*333d2b36SAndroid Build Coastguard Worker		if ccInfo, ok := android.OtherModuleProvider(ctx, to, cc.CcInfoProvider); ok {
2595*333d2b36SAndroid Build Coastguard Worker			// If `to` is not actually in the same APEX as `from` then it does not need
2596*333d2b36SAndroid Build Coastguard Worker			// apex_available and neither do any of its dependencies.
2597*333d2b36SAndroid Build Coastguard Worker			if externalDep {
2598*333d2b36SAndroid Build Coastguard Worker				// As soon as the dependency graph crosses the APEX boundary, don't go further.
2599*333d2b36SAndroid Build Coastguard Worker				return false
2600*333d2b36SAndroid Build Coastguard Worker			}
2601*333d2b36SAndroid Build Coastguard Worker
2602*333d2b36SAndroid Build Coastguard Worker			apexName := ctx.ModuleName()
2603*333d2b36SAndroid Build Coastguard Worker			fromName := ctx.OtherModuleName(from)
2604*333d2b36SAndroid Build Coastguard Worker			toName := ctx.OtherModuleName(to)
2605*333d2b36SAndroid Build Coastguard Worker
2606*333d2b36SAndroid Build Coastguard Worker			// The dynamic linker and crash_dump tool in the runtime APEX is the only
2607*333d2b36SAndroid Build Coastguard Worker			// exception to this rule. It can't make the static dependencies dynamic
2608*333d2b36SAndroid Build Coastguard Worker			// because it can't do the dynamic linking for itself.
2609*333d2b36SAndroid Build Coastguard Worker			// Same rule should be applied to linkerconfig, because it should be executed
2610*333d2b36SAndroid Build Coastguard Worker			// only with static linked libraries before linker is available with ld.config.txt
2611*333d2b36SAndroid Build Coastguard Worker			if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump" || fromName == "linkerconfig") {
2612*333d2b36SAndroid Build Coastguard Worker				return false
2613*333d2b36SAndroid Build Coastguard Worker			}
2614*333d2b36SAndroid Build Coastguard Worker
2615*333d2b36SAndroid Build Coastguard Worker			isStubLibraryFromOtherApex := ccInfo.HasStubsVariants && !librariesDirectlyInApex[toName]
2616*333d2b36SAndroid Build Coastguard Worker			if isStubLibraryFromOtherApex && !externalDep {
2617*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
2618*333d2b36SAndroid Build Coastguard Worker					"It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
2619*333d2b36SAndroid Build Coastguard Worker			}
2620*333d2b36SAndroid Build Coastguard Worker		}
2621*333d2b36SAndroid Build Coastguard Worker		return true
2622*333d2b36SAndroid Build Coastguard Worker	})
2623*333d2b36SAndroid Build Coastguard Worker}
2624*333d2b36SAndroid Build Coastguard Worker
2625*333d2b36SAndroid Build Coastguard Worker// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
2626*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
2627*333d2b36SAndroid Build Coastguard Worker	if a.Updatable() {
2628*333d2b36SAndroid Build Coastguard Worker		if a.minSdkVersionValue(ctx) == "" {
2629*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
2630*333d2b36SAndroid Build Coastguard Worker		}
2631*333d2b36SAndroid Build Coastguard Worker		if a.minSdkVersion(ctx).IsCurrent() {
2632*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("updatable", "updatable APEXes should not set min_sdk_version to current. Please use a finalized API level or a recognized in-development codename")
2633*333d2b36SAndroid Build Coastguard Worker		}
2634*333d2b36SAndroid Build Coastguard Worker		if a.UsePlatformApis() {
2635*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
2636*333d2b36SAndroid Build Coastguard Worker		}
2637*333d2b36SAndroid Build Coastguard Worker		if a.FutureUpdatable() {
2638*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`")
2639*333d2b36SAndroid Build Coastguard Worker		}
2640*333d2b36SAndroid Build Coastguard Worker		a.checkJavaStableSdkVersion(ctx)
2641*333d2b36SAndroid Build Coastguard Worker		a.checkClasspathFragments(ctx)
2642*333d2b36SAndroid Build Coastguard Worker	}
2643*333d2b36SAndroid Build Coastguard Worker}
2644*333d2b36SAndroid Build Coastguard Worker
2645*333d2b36SAndroid Build Coastguard Worker// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
2646*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
2647*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
2648*333d2b36SAndroid Build Coastguard Worker		if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
2649*333d2b36SAndroid Build Coastguard Worker			info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider)
2650*333d2b36SAndroid Build Coastguard Worker			if !info.ClasspathFragmentProtoGenerated {
2651*333d2b36SAndroid Build Coastguard Worker				ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
2652*333d2b36SAndroid Build Coastguard Worker			}
2653*333d2b36SAndroid Build Coastguard Worker		}
2654*333d2b36SAndroid Build Coastguard Worker	})
2655*333d2b36SAndroid Build Coastguard Worker}
2656*333d2b36SAndroid Build Coastguard Worker
2657*333d2b36SAndroid Build Coastguard Worker// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
2658*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
2659*333d2b36SAndroid Build Coastguard Worker	// Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
2660*333d2b36SAndroid Build Coastguard Worker	// java's checkLinkType guarantees correct usage for transitive deps
2661*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
2662*333d2b36SAndroid Build Coastguard Worker		tag := ctx.OtherModuleDependencyTag(module)
2663*333d2b36SAndroid Build Coastguard Worker		switch tag {
2664*333d2b36SAndroid Build Coastguard Worker		case javaLibTag, androidAppTag:
2665*333d2b36SAndroid Build Coastguard Worker			if err := java.CheckStableSdkVersion(ctx, module); err != nil {
2666*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2667*333d2b36SAndroid Build Coastguard Worker			}
2668*333d2b36SAndroid Build Coastguard Worker		}
2669*333d2b36SAndroid Build Coastguard Worker	})
2670*333d2b36SAndroid Build Coastguard Worker}
2671*333d2b36SAndroid Build Coastguard Worker
2672*333d2b36SAndroid Build Coastguard Worker// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
2673*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
2674*333d2b36SAndroid Build Coastguard Worker	// Let's be practical. Availability for test, host, and the VNDK apex isn't important
2675*333d2b36SAndroid Build Coastguard Worker	if a.testApex || a.vndkApex {
2676*333d2b36SAndroid Build Coastguard Worker		return
2677*333d2b36SAndroid Build Coastguard Worker	}
2678*333d2b36SAndroid Build Coastguard Worker
2679*333d2b36SAndroid Build Coastguard Worker	// Because APEXes targeting other than system/system_ext partitions can't set
2680*333d2b36SAndroid Build Coastguard Worker	// apex_available, we skip checks for these APEXes
2681*333d2b36SAndroid Build Coastguard Worker	if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2682*333d2b36SAndroid Build Coastguard Worker		return
2683*333d2b36SAndroid Build Coastguard Worker	}
2684*333d2b36SAndroid Build Coastguard Worker
2685*333d2b36SAndroid Build Coastguard Worker	// Temporarily bypass /product APEXes with a specific prefix.
2686*333d2b36SAndroid Build Coastguard Worker	// TODO: b/352818241 - Remove this after APEX availability is enforced for /product APEXes.
2687*333d2b36SAndroid Build Coastguard Worker	if a.ProductSpecific() && strings.HasPrefix(a.ApexVariationName(), "com.sdv.") {
2688*333d2b36SAndroid Build Coastguard Worker		return
2689*333d2b36SAndroid Build Coastguard Worker	}
2690*333d2b36SAndroid Build Coastguard Worker
2691*333d2b36SAndroid Build Coastguard Worker	// Coverage build adds additional dependencies for the coverage-only runtime libraries.
2692*333d2b36SAndroid Build Coastguard Worker	// Requiring them and their transitive depencies with apex_available is not right
2693*333d2b36SAndroid Build Coastguard Worker	// because they just add noise.
2694*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
2695*333d2b36SAndroid Build Coastguard Worker		return
2696*333d2b36SAndroid Build Coastguard Worker	}
2697*333d2b36SAndroid Build Coastguard Worker
2698*333d2b36SAndroid Build Coastguard Worker	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
2699*333d2b36SAndroid Build Coastguard Worker		// As soon as the dependency graph crosses the APEX boundary, don't go further.
2700*333d2b36SAndroid Build Coastguard Worker		if externalDep {
2701*333d2b36SAndroid Build Coastguard Worker			return false
2702*333d2b36SAndroid Build Coastguard Worker		}
2703*333d2b36SAndroid Build Coastguard Worker
2704*333d2b36SAndroid Build Coastguard Worker		apexName := ctx.ModuleName()
2705*333d2b36SAndroid Build Coastguard Worker		for _, props := range ctx.Module().GetProperties() {
2706*333d2b36SAndroid Build Coastguard Worker			if apexProps, ok := props.(*apexBundleProperties); ok {
2707*333d2b36SAndroid Build Coastguard Worker				if apexProps.Apex_available_name != nil {
2708*333d2b36SAndroid Build Coastguard Worker					apexName = *apexProps.Apex_available_name
2709*333d2b36SAndroid Build Coastguard Worker				}
2710*333d2b36SAndroid Build Coastguard Worker			}
2711*333d2b36SAndroid Build Coastguard Worker		}
2712*333d2b36SAndroid Build Coastguard Worker		fromName := ctx.OtherModuleName(from)
2713*333d2b36SAndroid Build Coastguard Worker		toName := ctx.OtherModuleName(to)
2714*333d2b36SAndroid Build Coastguard Worker
2715*333d2b36SAndroid Build Coastguard Worker		// If `to` is not actually in the same APEX as `from` then it does not need
2716*333d2b36SAndroid Build Coastguard Worker		// apex_available and neither do any of its dependencies.
2717*333d2b36SAndroid Build Coastguard Worker		//
2718*333d2b36SAndroid Build Coastguard Worker		// It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps().
2719*333d2b36SAndroid Build Coastguard Worker		if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
2720*333d2b36SAndroid Build Coastguard Worker			// As soon as the dependency graph crosses the APEX boundary, don't go
2721*333d2b36SAndroid Build Coastguard Worker			// further.
2722*333d2b36SAndroid Build Coastguard Worker			return false
2723*333d2b36SAndroid Build Coastguard Worker		}
2724*333d2b36SAndroid Build Coastguard Worker
2725*333d2b36SAndroid Build Coastguard Worker		if to.AvailableFor(apexName) {
2726*333d2b36SAndroid Build Coastguard Worker			return true
2727*333d2b36SAndroid Build Coastguard Worker		}
2728*333d2b36SAndroid Build Coastguard Worker
2729*333d2b36SAndroid Build Coastguard Worker		// Let's give some hint for apex_available
2730*333d2b36SAndroid Build Coastguard Worker		hint := fmt.Sprintf("%q", apexName)
2731*333d2b36SAndroid Build Coastguard Worker
2732*333d2b36SAndroid Build Coastguard Worker		if strings.HasPrefix(apexName, "com.") && !strings.HasPrefix(apexName, "com.android.") && strings.Count(apexName, ".") >= 2 {
2733*333d2b36SAndroid Build Coastguard Worker			// In case of a partner APEX, prefix format might be an option.
2734*333d2b36SAndroid Build Coastguard Worker			components := strings.Split(apexName, ".")
2735*333d2b36SAndroid Build Coastguard Worker			components[len(components)-1] = "*"
2736*333d2b36SAndroid Build Coastguard Worker			hint += fmt.Sprintf(" or %q", strings.Join(components, "."))
2737*333d2b36SAndroid Build Coastguard Worker		}
2738*333d2b36SAndroid Build Coastguard Worker
2739*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
2740*333d2b36SAndroid Build Coastguard Worker			"\n\nDependency path:%s\n\n"+
2741*333d2b36SAndroid Build Coastguard Worker			"Consider adding %s to 'apex_available' property of %q",
2742*333d2b36SAndroid Build Coastguard Worker			fromName, toName, ctx.GetPathString(true), hint, toName)
2743*333d2b36SAndroid Build Coastguard Worker		// Visit this module's dependencies to check and report any issues with their availability.
2744*333d2b36SAndroid Build Coastguard Worker		return true
2745*333d2b36SAndroid Build Coastguard Worker	})
2746*333d2b36SAndroid Build Coastguard Worker}
2747*333d2b36SAndroid Build Coastguard Worker
2748*333d2b36SAndroid Build Coastguard Worker// checkStaticExecutable ensures that executables in an APEX are not static.
2749*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
2750*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
2751*333d2b36SAndroid Build Coastguard Worker		if ctx.OtherModuleDependencyTag(module) != executableTag {
2752*333d2b36SAndroid Build Coastguard Worker			return
2753*333d2b36SAndroid Build Coastguard Worker		}
2754*333d2b36SAndroid Build Coastguard Worker
2755*333d2b36SAndroid Build Coastguard Worker		if android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoKey).StaticExecutable {
2756*333d2b36SAndroid Build Coastguard Worker			apex := a.ApexVariationName()
2757*333d2b36SAndroid Build Coastguard Worker			exec := ctx.OtherModuleName(module)
2758*333d2b36SAndroid Build Coastguard Worker			if isStaticExecutableAllowed(apex, exec) {
2759*333d2b36SAndroid Build Coastguard Worker				return
2760*333d2b36SAndroid Build Coastguard Worker			}
2761*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
2762*333d2b36SAndroid Build Coastguard Worker		}
2763*333d2b36SAndroid Build Coastguard Worker	})
2764*333d2b36SAndroid Build Coastguard Worker}
2765*333d2b36SAndroid Build Coastguard Worker
2766*333d2b36SAndroid Build Coastguard Worker// A small list of exceptions where static executables are allowed in APEXes.
2767*333d2b36SAndroid Build Coastguard Workerfunc isStaticExecutableAllowed(apex string, exec string) bool {
2768*333d2b36SAndroid Build Coastguard Worker	m := map[string][]string{
2769*333d2b36SAndroid Build Coastguard Worker		"com.android.runtime": {
2770*333d2b36SAndroid Build Coastguard Worker			"linker",
2771*333d2b36SAndroid Build Coastguard Worker			"linkerconfig",
2772*333d2b36SAndroid Build Coastguard Worker		},
2773*333d2b36SAndroid Build Coastguard Worker	}
2774*333d2b36SAndroid Build Coastguard Worker	execNames, ok := m[apex]
2775*333d2b36SAndroid Build Coastguard Worker	return ok && android.InList(exec, execNames)
2776*333d2b36SAndroid Build Coastguard Worker}
2777*333d2b36SAndroid Build Coastguard Worker
2778*333d2b36SAndroid Build Coastguard Worker// Collect information for opening IDE project files in java/jdeps.go.
2779*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
2780*333d2b36SAndroid Build Coastguard Worker	dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
2781*333d2b36SAndroid Build Coastguard Worker	dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments.GetOrDefault(ctx, nil)...)
2782*333d2b36SAndroid Build Coastguard Worker	dpInfo.Deps = append(dpInfo.Deps, a.properties.Systemserverclasspath_fragments.GetOrDefault(ctx, nil)...)
2783*333d2b36SAndroid Build Coastguard Worker}
2784*333d2b36SAndroid Build Coastguard Worker
2785*333d2b36SAndroid Build Coastguard Workerfunc init() {
2786*333d2b36SAndroid Build Coastguard Worker	android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
2787*333d2b36SAndroid Build Coastguard Worker	android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)
2788*333d2b36SAndroid Build Coastguard Worker}
2789*333d2b36SAndroid Build Coastguard Worker
2790*333d2b36SAndroid Build Coastguard Workerfunc createBcpPermittedPackagesRules(bcpPermittedPackages map[string][]string) []android.Rule {
2791*333d2b36SAndroid Build Coastguard Worker	rules := make([]android.Rule, 0, len(bcpPermittedPackages))
2792*333d2b36SAndroid Build Coastguard Worker	for jar, permittedPackages := range bcpPermittedPackages {
2793*333d2b36SAndroid Build Coastguard Worker		permittedPackagesRule := android.NeverAllow().
2794*333d2b36SAndroid Build Coastguard Worker			With("name", jar).
2795*333d2b36SAndroid Build Coastguard Worker			WithMatcher("permitted_packages", android.NotInList(permittedPackages)).
2796*333d2b36SAndroid Build Coastguard Worker			Because(jar +
2797*333d2b36SAndroid Build Coastguard Worker				" bootjar may only use these package prefixes: " + strings.Join(permittedPackages, ",") +
2798*333d2b36SAndroid Build Coastguard Worker				". Please consider the following alternatives:\n" +
2799*333d2b36SAndroid Build Coastguard Worker				"    1. If the offending code is from a statically linked library, consider " +
2800*333d2b36SAndroid Build Coastguard Worker				"removing that dependency and using an alternative already in the " +
2801*333d2b36SAndroid Build Coastguard Worker				"bootclasspath, or perhaps a shared library." +
2802*333d2b36SAndroid Build Coastguard Worker				"    2. Move the offending code into an allowed package.\n" +
2803*333d2b36SAndroid Build Coastguard Worker				"    3. Jarjar the offending code. Please be mindful of the potential system " +
2804*333d2b36SAndroid Build Coastguard Worker				"health implications of bundling that code, particularly if the offending jar " +
2805*333d2b36SAndroid Build Coastguard Worker				"is part of the bootclasspath.")
2806*333d2b36SAndroid Build Coastguard Worker
2807*333d2b36SAndroid Build Coastguard Worker		rules = append(rules, permittedPackagesRule)
2808*333d2b36SAndroid Build Coastguard Worker	}
2809*333d2b36SAndroid Build Coastguard Worker	return rules
2810*333d2b36SAndroid Build Coastguard Worker}
2811*333d2b36SAndroid Build Coastguard Worker
2812*333d2b36SAndroid Build Coastguard Worker// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
2813*333d2b36SAndroid Build Coastguard Worker// Adding code to the bootclasspath in new packages will cause issues on module update.
2814*333d2b36SAndroid Build Coastguard Workerfunc qBcpPackages() map[string][]string {
2815*333d2b36SAndroid Build Coastguard Worker	return map[string][]string{
2816*333d2b36SAndroid Build Coastguard Worker		"conscrypt": {
2817*333d2b36SAndroid Build Coastguard Worker			"android.net.ssl",
2818*333d2b36SAndroid Build Coastguard Worker			"com.android.org.conscrypt",
2819*333d2b36SAndroid Build Coastguard Worker		},
2820*333d2b36SAndroid Build Coastguard Worker		"updatable-media": {
2821*333d2b36SAndroid Build Coastguard Worker			"android.media",
2822*333d2b36SAndroid Build Coastguard Worker		},
2823*333d2b36SAndroid Build Coastguard Worker	}
2824*333d2b36SAndroid Build Coastguard Worker}
2825*333d2b36SAndroid Build Coastguard Worker
2826*333d2b36SAndroid Build Coastguard Worker// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
2827*333d2b36SAndroid Build Coastguard Worker// Adding code to the bootclasspath in new packages will cause issues on module update.
2828*333d2b36SAndroid Build Coastguard Workerfunc rBcpPackages() map[string][]string {
2829*333d2b36SAndroid Build Coastguard Worker	return map[string][]string{
2830*333d2b36SAndroid Build Coastguard Worker		"framework-mediaprovider": {
2831*333d2b36SAndroid Build Coastguard Worker			"android.provider",
2832*333d2b36SAndroid Build Coastguard Worker		},
2833*333d2b36SAndroid Build Coastguard Worker		"framework-permission": {
2834*333d2b36SAndroid Build Coastguard Worker			"android.permission",
2835*333d2b36SAndroid Build Coastguard Worker			"android.app.role",
2836*333d2b36SAndroid Build Coastguard Worker			"com.android.permission",
2837*333d2b36SAndroid Build Coastguard Worker			"com.android.role",
2838*333d2b36SAndroid Build Coastguard Worker		},
2839*333d2b36SAndroid Build Coastguard Worker		"framework-sdkextensions": {
2840*333d2b36SAndroid Build Coastguard Worker			"android.os.ext",
2841*333d2b36SAndroid Build Coastguard Worker		},
2842*333d2b36SAndroid Build Coastguard Worker		"framework-statsd": {
2843*333d2b36SAndroid Build Coastguard Worker			"android.app",
2844*333d2b36SAndroid Build Coastguard Worker			"android.os",
2845*333d2b36SAndroid Build Coastguard Worker			"android.util",
2846*333d2b36SAndroid Build Coastguard Worker			"com.android.internal.statsd",
2847*333d2b36SAndroid Build Coastguard Worker			"com.android.server.stats",
2848*333d2b36SAndroid Build Coastguard Worker		},
2849*333d2b36SAndroid Build Coastguard Worker		"framework-wifi": {
2850*333d2b36SAndroid Build Coastguard Worker			"com.android.server.wifi",
2851*333d2b36SAndroid Build Coastguard Worker			"com.android.wifi.x",
2852*333d2b36SAndroid Build Coastguard Worker			"android.hardware.wifi",
2853*333d2b36SAndroid Build Coastguard Worker			"android.net.wifi",
2854*333d2b36SAndroid Build Coastguard Worker		},
2855*333d2b36SAndroid Build Coastguard Worker		"framework-tethering": {
2856*333d2b36SAndroid Build Coastguard Worker			"android.net",
2857*333d2b36SAndroid Build Coastguard Worker		},
2858*333d2b36SAndroid Build Coastguard Worker	}
2859*333d2b36SAndroid Build Coastguard Worker}
2860*333d2b36SAndroid Build Coastguard Worker
2861*333d2b36SAndroid Build Coastguard Worker// verifyNativeImplementationLibs compares the list of transitive implementation libraries used to link native
2862*333d2b36SAndroid Build Coastguard Worker// libraries in the apex against the list of implementation libraries in the apex, ensuring that none of the
2863*333d2b36SAndroid Build Coastguard Worker// libraries in the apex have references to private APIs from outside the apex.
2864*333d2b36SAndroid Build Coastguard Workerfunc (a *apexBundle) verifyNativeImplementationLibs(ctx android.ModuleContext) {
2865*333d2b36SAndroid Build Coastguard Worker	var directImplementationLibs android.Paths
2866*333d2b36SAndroid Build Coastguard Worker	var transitiveImplementationLibs []depset.DepSet[android.Path]
2867*333d2b36SAndroid Build Coastguard Worker
2868*333d2b36SAndroid Build Coastguard Worker	if a.properties.IsCoverageVariant {
2869*333d2b36SAndroid Build Coastguard Worker		return
2870*333d2b36SAndroid Build Coastguard Worker	}
2871*333d2b36SAndroid Build Coastguard Worker
2872*333d2b36SAndroid Build Coastguard Worker	if a.testApex {
2873*333d2b36SAndroid Build Coastguard Worker		return
2874*333d2b36SAndroid Build Coastguard Worker	}
2875*333d2b36SAndroid Build Coastguard Worker
2876*333d2b36SAndroid Build Coastguard Worker	if a.UsePlatformApis() {
2877*333d2b36SAndroid Build Coastguard Worker		return
2878*333d2b36SAndroid Build Coastguard Worker	}
2879*333d2b36SAndroid Build Coastguard Worker
2880*333d2b36SAndroid Build Coastguard Worker	checkApexTag := func(tag blueprint.DependencyTag) bool {
2881*333d2b36SAndroid Build Coastguard Worker		switch tag {
2882*333d2b36SAndroid Build Coastguard Worker		case sharedLibTag, jniLibTag, executableTag, androidAppTag:
2883*333d2b36SAndroid Build Coastguard Worker			return true
2884*333d2b36SAndroid Build Coastguard Worker		default:
2885*333d2b36SAndroid Build Coastguard Worker			return false
2886*333d2b36SAndroid Build Coastguard Worker		}
2887*333d2b36SAndroid Build Coastguard Worker	}
2888*333d2b36SAndroid Build Coastguard Worker
2889*333d2b36SAndroid Build Coastguard Worker	checkTransitiveTag := func(tag blueprint.DependencyTag) bool {
2890*333d2b36SAndroid Build Coastguard Worker		switch {
2891*333d2b36SAndroid Build Coastguard Worker		case cc.IsSharedDepTag(tag), java.IsJniDepTag(tag), rust.IsRlibDepTag(tag), rust.IsDylibDepTag(tag), checkApexTag(tag):
2892*333d2b36SAndroid Build Coastguard Worker			return true
2893*333d2b36SAndroid Build Coastguard Worker		default:
2894*333d2b36SAndroid Build Coastguard Worker			return false
2895*333d2b36SAndroid Build Coastguard Worker		}
2896*333d2b36SAndroid Build Coastguard Worker	}
2897*333d2b36SAndroid Build Coastguard Worker
2898*333d2b36SAndroid Build Coastguard Worker	var appEmbeddedJNILibs android.Paths
2899*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
2900*333d2b36SAndroid Build Coastguard Worker		tag := ctx.OtherModuleDependencyTag(dep)
2901*333d2b36SAndroid Build Coastguard Worker		if !checkApexTag(tag) {
2902*333d2b36SAndroid Build Coastguard Worker			return
2903*333d2b36SAndroid Build Coastguard Worker		}
2904*333d2b36SAndroid Build Coastguard Worker		if tag == sharedLibTag || tag == jniLibTag {
2905*333d2b36SAndroid Build Coastguard Worker			outputFile := android.OutputFileForModule(ctx, dep, "")
2906*333d2b36SAndroid Build Coastguard Worker			directImplementationLibs = append(directImplementationLibs, outputFile)
2907*333d2b36SAndroid Build Coastguard Worker		}
2908*333d2b36SAndroid Build Coastguard Worker		if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
2909*333d2b36SAndroid Build Coastguard Worker			transitiveImplementationLibs = append(transitiveImplementationLibs, info.ImplementationDeps)
2910*333d2b36SAndroid Build Coastguard Worker		}
2911*333d2b36SAndroid Build Coastguard Worker		if info, ok := android.OtherModuleProvider(ctx, dep, java.AppInfoProvider); ok {
2912*333d2b36SAndroid Build Coastguard Worker			appEmbeddedJNILibs = append(appEmbeddedJNILibs, info.EmbeddedJNILibs...)
2913*333d2b36SAndroid Build Coastguard Worker		}
2914*333d2b36SAndroid Build Coastguard Worker	})
2915*333d2b36SAndroid Build Coastguard Worker
2916*333d2b36SAndroid Build Coastguard Worker	depSet := depset.New(depset.PREORDER, directImplementationLibs, transitiveImplementationLibs)
2917*333d2b36SAndroid Build Coastguard Worker	allImplementationLibs := depSet.ToList()
2918*333d2b36SAndroid Build Coastguard Worker
2919*333d2b36SAndroid Build Coastguard Worker	allFileInfos := slices.Concat(a.filesInfo, a.unwantedTransitiveFilesInfo, a.duplicateTransitiveFilesInfo)
2920*333d2b36SAndroid Build Coastguard Worker
2921*333d2b36SAndroid Build Coastguard Worker	for _, lib := range allImplementationLibs {
2922*333d2b36SAndroid Build Coastguard Worker		inApex := slices.ContainsFunc(allFileInfos, func(fi apexFile) bool {
2923*333d2b36SAndroid Build Coastguard Worker			return fi.builtFile == lib
2924*333d2b36SAndroid Build Coastguard Worker		})
2925*333d2b36SAndroid Build Coastguard Worker		inApkInApex := slices.Contains(appEmbeddedJNILibs, lib)
2926*333d2b36SAndroid Build Coastguard Worker
2927*333d2b36SAndroid Build Coastguard Worker		if !inApex && !inApkInApex {
2928*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("library in apex transitively linked against implementation library %q not in apex", lib)
2929*333d2b36SAndroid Build Coastguard Worker			var depPath []android.Module
2930*333d2b36SAndroid Build Coastguard Worker			ctx.WalkDeps(func(child, parent android.Module) bool {
2931*333d2b36SAndroid Build Coastguard Worker				if depPath != nil {
2932*333d2b36SAndroid Build Coastguard Worker					return false
2933*333d2b36SAndroid Build Coastguard Worker				}
2934*333d2b36SAndroid Build Coastguard Worker
2935*333d2b36SAndroid Build Coastguard Worker				tag := ctx.OtherModuleDependencyTag(child)
2936*333d2b36SAndroid Build Coastguard Worker
2937*333d2b36SAndroid Build Coastguard Worker				if parent == ctx.Module() {
2938*333d2b36SAndroid Build Coastguard Worker					if !checkApexTag(tag) {
2939*333d2b36SAndroid Build Coastguard Worker						return false
2940*333d2b36SAndroid Build Coastguard Worker					}
2941*333d2b36SAndroid Build Coastguard Worker				}
2942*333d2b36SAndroid Build Coastguard Worker
2943*333d2b36SAndroid Build Coastguard Worker				if checkTransitiveTag(tag) {
2944*333d2b36SAndroid Build Coastguard Worker					if android.OutputFileForModule(ctx, child, "") == lib {
2945*333d2b36SAndroid Build Coastguard Worker						depPath = ctx.GetWalkPath()
2946*333d2b36SAndroid Build Coastguard Worker					}
2947*333d2b36SAndroid Build Coastguard Worker					return true
2948*333d2b36SAndroid Build Coastguard Worker				}
2949*333d2b36SAndroid Build Coastguard Worker
2950*333d2b36SAndroid Build Coastguard Worker				return false
2951*333d2b36SAndroid Build Coastguard Worker			})
2952*333d2b36SAndroid Build Coastguard Worker			if depPath != nil {
2953*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("dependency path:")
2954*333d2b36SAndroid Build Coastguard Worker				for _, m := range depPath {
2955*333d2b36SAndroid Build Coastguard Worker					ctx.ModuleErrorf("   %s", ctx.OtherModuleName(m))
2956*333d2b36SAndroid Build Coastguard Worker				}
2957*333d2b36SAndroid Build Coastguard Worker				return
2958*333d2b36SAndroid Build Coastguard Worker			}
2959*333d2b36SAndroid Build Coastguard Worker		}
2960*333d2b36SAndroid Build Coastguard Worker	}
2961*333d2b36SAndroid Build Coastguard Worker}
2962