1// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package apex
16
17import (
18	"fmt"
19	"path/filepath"
20	"sort"
21	"strings"
22	"sync"
23
24	"github.com/google/blueprint"
25	"github.com/google/blueprint/bootstrap"
26	"github.com/google/blueprint/proptools"
27
28	"android/soong/android"
29	"android/soong/cc"
30	prebuilt_etc "android/soong/etc"
31	"android/soong/java"
32	"android/soong/python"
33	"android/soong/sh"
34)
35
36const (
37	imageApexSuffix = ".apex"
38	zipApexSuffix   = ".zipapex"
39	flattenedSuffix = ".flattened"
40
41	imageApexType     = "image"
42	zipApexType       = "zip"
43	flattenedApexType = "flattened"
44)
45
46type dependencyTag struct {
47	blueprint.BaseDependencyTag
48	name string
49
50	// determines if the dependent will be part of the APEX payload
51	payload bool
52}
53
54var (
55	sharedLibTag   = dependencyTag{name: "sharedLib", payload: true}
56	jniLibTag      = dependencyTag{name: "jniLib", payload: true}
57	executableTag  = dependencyTag{name: "executable", payload: true}
58	javaLibTag     = dependencyTag{name: "javaLib", payload: true}
59	prebuiltTag    = dependencyTag{name: "prebuilt", payload: true}
60	testTag        = dependencyTag{name: "test", payload: true}
61	keyTag         = dependencyTag{name: "key"}
62	certificateTag = dependencyTag{name: "certificate"}
63	usesTag        = dependencyTag{name: "uses"}
64	androidAppTag  = dependencyTag{name: "androidApp", payload: true}
65	rroTag         = dependencyTag{name: "rro", payload: true}
66
67	apexAvailBaseline = makeApexAvailableBaseline()
68
69	inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
70)
71
72// Transform the map of apex -> modules to module -> apexes.
73func invertApexBaseline(m map[string][]string) map[string][]string {
74	r := make(map[string][]string)
75	for apex, modules := range m {
76		for _, module := range modules {
77			r[module] = append(r[module], apex)
78		}
79	}
80	return r
81}
82
83// Retrieve the baseline of apexes to which the supplied module belongs.
84func BaselineApexAvailable(moduleName string) []string {
85	return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
86}
87
88// This is a map from apex to modules, which overrides the
89// apex_available setting for that particular module to make
90// it available for the apex regardless of its setting.
91// TODO(b/147364041): remove this
92func makeApexAvailableBaseline() map[string][]string {
93	// The "Module separator"s below are employed to minimize merge conflicts.
94	m := make(map[string][]string)
95	//
96	// Module separator
97	//
98	m["com.android.bluetooth.updatable"] = []string{
99		"android.hardware.audio.common@5.0",
100		"android.hardware.bluetooth.a2dp@1.0",
101		"android.hardware.bluetooth.audio@2.0",
102		"android.hardware.bluetooth@1.0",
103		"android.hardware.bluetooth@1.1",
104		"android.hardware.graphics.bufferqueue@1.0",
105		"android.hardware.graphics.bufferqueue@2.0",
106		"android.hardware.graphics.common@1.0",
107		"android.hardware.graphics.common@1.1",
108		"android.hardware.graphics.common@1.2",
109		"android.hardware.media@1.0",
110		"android.hidl.safe_union@1.0",
111		"android.hidl.token@1.0",
112		"android.hidl.token@1.0-utils",
113		"avrcp-target-service",
114		"avrcp_headers",
115		"bluetooth-protos-lite",
116		"bluetooth.mapsapi",
117		"com.android.vcard",
118		"dnsresolver_aidl_interface-V2-java",
119		"ipmemorystore-aidl-interfaces-V5-java",
120		"ipmemorystore-aidl-interfaces-java",
121		"internal_include_headers",
122		"lib-bt-packets",
123		"lib-bt-packets-avrcp",
124		"lib-bt-packets-base",
125		"libFraunhoferAAC",
126		"libaudio-a2dp-hw-utils",
127		"libaudio-hearing-aid-hw-utils",
128		"libbinder_headers",
129		"libbluetooth",
130		"libbluetooth-types",
131		"libbluetooth-types-header",
132		"libbluetooth_gd",
133		"libbluetooth_headers",
134		"libbluetooth_jni",
135		"libbt-audio-hal-interface",
136		"libbt-bta",
137		"libbt-common",
138		"libbt-hci",
139		"libbt-platform-protos-lite",
140		"libbt-protos-lite",
141		"libbt-sbc-decoder",
142		"libbt-sbc-encoder",
143		"libbt-stack",
144		"libbt-utils",
145		"libbtcore",
146		"libbtdevice",
147		"libbte",
148		"libbtif",
149		"libchrome",
150		"libevent",
151		"libfmq",
152		"libg722codec",
153		"libgui_headers",
154		"libmedia_headers",
155		"libmodpb64",
156		"libosi",
157		"libstagefright_foundation_headers",
158		"libstagefright_headers",
159		"libstatslog",
160		"libstatssocket",
161		"libtinyxml2",
162		"libudrv-uipc",
163		"libz",
164		"media_plugin_headers",
165		"net-utils-services-common",
166		"netd_aidl_interface-unstable-java",
167		"netd_event_listener_interface-java",
168		"netlink-client",
169		"networkstack-client",
170		"sap-api-java-static",
171		"services.net",
172	}
173	//
174	// Module separator
175	//
176	m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
177	//
178	// Module separator
179	//
180	m["com.android.neuralnetworks"] = []string{
181		"android.hardware.neuralnetworks@1.0",
182		"android.hardware.neuralnetworks@1.1",
183		"android.hardware.neuralnetworks@1.2",
184		"android.hardware.neuralnetworks@1.3",
185		"android.hidl.allocator@1.0",
186		"android.hidl.memory.token@1.0",
187		"android.hidl.memory@1.0",
188		"android.hidl.safe_union@1.0",
189		"libarect",
190		"libbuildversion",
191		"libmath",
192		"libprocpartition",
193		"libsync",
194	}
195	//
196	// Module separator
197	//
198	m["com.android.media"] = []string{
199		"android.frameworks.bufferhub@1.0",
200		"android.hardware.cas.native@1.0",
201		"android.hardware.cas@1.0",
202		"android.hardware.configstore-utils",
203		"android.hardware.configstore@1.0",
204		"android.hardware.configstore@1.1",
205		"android.hardware.graphics.allocator@2.0",
206		"android.hardware.graphics.allocator@3.0",
207		"android.hardware.graphics.bufferqueue@1.0",
208		"android.hardware.graphics.bufferqueue@2.0",
209		"android.hardware.graphics.common@1.0",
210		"android.hardware.graphics.common@1.1",
211		"android.hardware.graphics.common@1.2",
212		"android.hardware.graphics.mapper@2.0",
213		"android.hardware.graphics.mapper@2.1",
214		"android.hardware.graphics.mapper@3.0",
215		"android.hardware.media.omx@1.0",
216		"android.hardware.media@1.0",
217		"android.hidl.allocator@1.0",
218		"android.hidl.memory.token@1.0",
219		"android.hidl.memory@1.0",
220		"android.hidl.token@1.0",
221		"android.hidl.token@1.0-utils",
222		"bionic_libc_platform_headers",
223		"exoplayer2-extractor",
224		"exoplayer2-extractor-annotation-stubs",
225		"gl_headers",
226		"jsr305",
227		"libEGL",
228		"libEGL_blobCache",
229		"libEGL_getProcAddress",
230		"libFLAC",
231		"libFLAC-config",
232		"libFLAC-headers",
233		"libGLESv2",
234		"libaacextractor",
235		"libamrextractor",
236		"libarect",
237		"libaudio_system_headers",
238		"libaudioclient",
239		"libaudioclient_headers",
240		"libaudiofoundation",
241		"libaudiofoundation_headers",
242		"libaudiomanager",
243		"libaudiopolicy",
244		"libaudioutils",
245		"libaudioutils_fixedfft",
246		"libbinder_headers",
247		"libbluetooth-types-header",
248		"libbufferhub",
249		"libbufferhub_headers",
250		"libbufferhubqueue",
251		"libc_malloc_debug_backtrace",
252		"libcamera_client",
253		"libcamera_metadata",
254		"libdexfile_external_headers",
255		"libdexfile_support",
256		"libdvr_headers",
257		"libexpat",
258		"libfifo",
259		"libflacextractor",
260		"libgrallocusage",
261		"libgraphicsenv",
262		"libgui",
263		"libgui_headers",
264		"libhardware_headers",
265		"libinput",
266		"liblzma",
267		"libmath",
268		"libmedia",
269		"libmedia_codeclist",
270		"libmedia_headers",
271		"libmedia_helper",
272		"libmedia_helper_headers",
273		"libmedia_midiiowrapper",
274		"libmedia_omx",
275		"libmediautils",
276		"libmidiextractor",
277		"libmkvextractor",
278		"libmp3extractor",
279		"libmp4extractor",
280		"libmpeg2extractor",
281		"libnativebase_headers",
282		"libnativebridge-headers",
283		"libnativebridge_lazy",
284		"libnativeloader-headers",
285		"libnativeloader_lazy",
286		"libnativewindow_headers",
287		"libnblog",
288		"liboggextractor",
289		"libpackagelistparser",
290		"libpdx",
291		"libpdx_default_transport",
292		"libpdx_headers",
293		"libpdx_uds",
294		"libprocinfo",
295		"libsonivox",
296		"libspeexresampler",
297		"libspeexresampler",
298		"libstagefright_esds",
299		"libstagefright_flacdec",
300		"libstagefright_flacdec",
301		"libstagefright_foundation",
302		"libstagefright_foundation_headers",
303		"libstagefright_foundation_without_imemory",
304		"libstagefright_headers",
305		"libstagefright_id3",
306		"libstagefright_metadatautils",
307		"libstagefright_mpeg2extractor",
308		"libstagefright_mpeg2support",
309		"libsync",
310		"libui",
311		"libui_headers",
312		"libunwindstack",
313		"libvibrator",
314		"libvorbisidec",
315		"libwavextractor",
316		"libwebm",
317		"media_ndk_headers",
318		"media_plugin_headers",
319		"updatable-media",
320	}
321	//
322	// Module separator
323	//
324	m["com.android.media.swcodec"] = []string{
325		"android.frameworks.bufferhub@1.0",
326		"android.hardware.common-ndk_platform",
327		"android.hardware.configstore-utils",
328		"android.hardware.configstore@1.0",
329		"android.hardware.configstore@1.1",
330		"android.hardware.graphics.allocator@2.0",
331		"android.hardware.graphics.allocator@3.0",
332		"android.hardware.graphics.bufferqueue@1.0",
333		"android.hardware.graphics.bufferqueue@2.0",
334		"android.hardware.graphics.common-ndk_platform",
335		"android.hardware.graphics.common@1.0",
336		"android.hardware.graphics.common@1.1",
337		"android.hardware.graphics.common@1.2",
338		"android.hardware.graphics.mapper@2.0",
339		"android.hardware.graphics.mapper@2.1",
340		"android.hardware.graphics.mapper@3.0",
341		"android.hardware.graphics.mapper@4.0",
342		"android.hardware.media.bufferpool@2.0",
343		"android.hardware.media.c2@1.0",
344		"android.hardware.media.omx@1.0",
345		"android.hardware.media@1.0",
346		"android.hardware.media@1.0",
347		"android.hidl.memory.token@1.0",
348		"android.hidl.memory@1.0",
349		"android.hidl.safe_union@1.0",
350		"android.hidl.token@1.0",
351		"android.hidl.token@1.0-utils",
352		"libEGL",
353		"libFLAC",
354		"libFLAC-config",
355		"libFLAC-headers",
356		"libFraunhoferAAC",
357		"libLibGuiProperties",
358		"libarect",
359		"libaudio_system_headers",
360		"libaudioutils",
361		"libaudioutils",
362		"libaudioutils_fixedfft",
363		"libavcdec",
364		"libavcenc",
365		"libavservices_minijail",
366		"libavservices_minijail",
367		"libbinder_headers",
368		"libbinderthreadstateutils",
369		"libbluetooth-types-header",
370		"libbufferhub_headers",
371		"libcodec2",
372		"libcodec2_headers",
373		"libcodec2_hidl@1.0",
374		"libcodec2_hidl@1.1",
375		"libcodec2_internal",
376		"libcodec2_soft_aacdec",
377		"libcodec2_soft_aacenc",
378		"libcodec2_soft_amrnbdec",
379		"libcodec2_soft_amrnbenc",
380		"libcodec2_soft_amrwbdec",
381		"libcodec2_soft_amrwbenc",
382		"libcodec2_soft_av1dec_gav1",
383		"libcodec2_soft_avcdec",
384		"libcodec2_soft_avcenc",
385		"libcodec2_soft_common",
386		"libcodec2_soft_flacdec",
387		"libcodec2_soft_flacenc",
388		"libcodec2_soft_g711alawdec",
389		"libcodec2_soft_g711mlawdec",
390		"libcodec2_soft_gsmdec",
391		"libcodec2_soft_h263dec",
392		"libcodec2_soft_h263enc",
393		"libcodec2_soft_hevcdec",
394		"libcodec2_soft_hevcenc",
395		"libcodec2_soft_mp3dec",
396		"libcodec2_soft_mpeg2dec",
397		"libcodec2_soft_mpeg4dec",
398		"libcodec2_soft_mpeg4enc",
399		"libcodec2_soft_opusdec",
400		"libcodec2_soft_opusenc",
401		"libcodec2_soft_rawdec",
402		"libcodec2_soft_vorbisdec",
403		"libcodec2_soft_vp8dec",
404		"libcodec2_soft_vp8enc",
405		"libcodec2_soft_vp9dec",
406		"libcodec2_soft_vp9enc",
407		"libcodec2_vndk",
408		"libdexfile_support",
409		"libdvr_headers",
410		"libfmq",
411		"libfmq",
412		"libgav1",
413		"libgralloctypes",
414		"libgrallocusage",
415		"libgraphicsenv",
416		"libgsm",
417		"libgui_bufferqueue_static",
418		"libgui_headers",
419		"libhardware",
420		"libhardware_headers",
421		"libhevcdec",
422		"libhevcenc",
423		"libion",
424		"libjpeg",
425		"liblzma",
426		"libmath",
427		"libmedia_codecserviceregistrant",
428		"libmedia_headers",
429		"libmpeg2dec",
430		"libnativebase_headers",
431		"libnativebridge_lazy",
432		"libnativeloader_lazy",
433		"libnativewindow_headers",
434		"libpdx_headers",
435		"libscudo_wrapper",
436		"libsfplugin_ccodec_utils",
437		"libstagefright_amrnb_common",
438		"libstagefright_amrnbdec",
439		"libstagefright_amrnbenc",
440		"libstagefright_amrwbdec",
441		"libstagefright_amrwbenc",
442		"libstagefright_bufferpool@2.0.1",
443		"libstagefright_bufferqueue_helper",
444		"libstagefright_enc_common",
445		"libstagefright_flacdec",
446		"libstagefright_foundation",
447		"libstagefright_foundation_headers",
448		"libstagefright_headers",
449		"libstagefright_m4vh263dec",
450		"libstagefright_m4vh263enc",
451		"libstagefright_mp3dec",
452		"libsync",
453		"libui",
454		"libui_headers",
455		"libunwindstack",
456		"libvorbisidec",
457		"libvpx",
458		"libyuv",
459		"libyuv_static",
460		"media_ndk_headers",
461		"media_plugin_headers",
462		"mediaswcodec",
463	}
464	//
465	// Module separator
466	//
467	m["com.android.mediaprovider"] = []string{
468		"MediaProvider",
469		"MediaProviderGoogle",
470		"fmtlib_ndk",
471		"libbase_ndk",
472		"libfuse",
473		"libfuse_jni",
474	}
475	//
476	// Module separator
477	//
478	m["com.android.permission"] = []string{
479		"kotlin-annotations",
480		"kotlin-stdlib",
481		"kotlin-stdlib-jdk7",
482		"kotlin-stdlib-jdk8",
483		"kotlinx-coroutines-android",
484		"kotlinx-coroutines-android-nodeps",
485		"kotlinx-coroutines-core",
486		"kotlinx-coroutines-core-nodeps",
487		"permissioncontroller-statsd",
488	}
489	//
490	// Module separator
491	//
492	m["com.android.runtime"] = []string{
493		"bionic_libc_platform_headers",
494		"libarm-optimized-routines-math",
495		"libc_aeabi",
496		"libc_bionic",
497		"libc_bionic_ndk",
498		"libc_bootstrap",
499		"libc_common",
500		"libc_common_shared",
501		"libc_common_static",
502		"libc_dns",
503		"libc_dynamic_dispatch",
504		"libc_fortify",
505		"libc_freebsd",
506		"libc_freebsd_large_stack",
507		"libc_gdtoa",
508		"libc_init_dynamic",
509		"libc_init_static",
510		"libc_jemalloc_wrapper",
511		"libc_netbsd",
512		"libc_nomalloc",
513		"libc_nopthread",
514		"libc_openbsd",
515		"libc_openbsd_large_stack",
516		"libc_openbsd_ndk",
517		"libc_pthread",
518		"libc_static_dispatch",
519		"libc_syscalls",
520		"libc_tzcode",
521		"libc_unwind_static",
522		"libdebuggerd",
523		"libdebuggerd_common_headers",
524		"libdebuggerd_handler_core",
525		"libdebuggerd_handler_fallback",
526		"libdexfile_external_headers",
527		"libdexfile_support",
528		"libdexfile_support_static",
529		"libdl_static",
530		"libjemalloc5",
531		"liblinker_main",
532		"liblinker_malloc",
533		"liblz4",
534		"liblzma",
535		"libprocinfo",
536		"libpropertyinfoparser",
537		"libscudo",
538		"libstdc++",
539		"libsystemproperties",
540		"libtombstoned_client_static",
541		"libunwindstack",
542		"libz",
543		"libziparchive",
544	}
545	//
546	// Module separator
547	//
548	m["com.android.tethering"] = []string{
549		"android.hardware.tetheroffload.config-V1.0-java",
550		"android.hardware.tetheroffload.control-V1.0-java",
551		"android.hidl.base-V1.0-java",
552		"ipmemorystore-aidl-interfaces-java",
553		"libcgrouprc",
554		"libcgrouprc_format",
555		"libtetherutilsjni",
556		"libvndksupport",
557		"net-utils-framework-common",
558		"netd_aidl_interface-V3-java",
559		"netlink-client",
560		"networkstack-aidl-interfaces-java",
561		"tethering-aidl-interfaces-java",
562		"TetheringApiCurrentLib",
563	}
564	//
565	// Module separator
566	//
567	m["com.android.wifi"] = []string{
568		"PlatformProperties",
569		"android.hardware.wifi-V1.0-java",
570		"android.hardware.wifi-V1.0-java-constants",
571		"android.hardware.wifi-V1.1-java",
572		"android.hardware.wifi-V1.2-java",
573		"android.hardware.wifi-V1.3-java",
574		"android.hardware.wifi-V1.4-java",
575		"android.hardware.wifi.hostapd-V1.0-java",
576		"android.hardware.wifi.hostapd-V1.1-java",
577		"android.hardware.wifi.hostapd-V1.2-java",
578		"android.hardware.wifi.supplicant-V1.0-java",
579		"android.hardware.wifi.supplicant-V1.1-java",
580		"android.hardware.wifi.supplicant-V1.2-java",
581		"android.hardware.wifi.supplicant-V1.3-java",
582		"android.hidl.base-V1.0-java",
583		"android.hidl.manager-V1.0-java",
584		"android.hidl.manager-V1.1-java",
585		"android.hidl.manager-V1.2-java",
586		"bouncycastle-unbundled",
587		"dnsresolver_aidl_interface-V2-java",
588		"error_prone_annotations",
589		"framework-wifi-pre-jarjar",
590		"framework-wifi-util-lib",
591		"ipmemorystore-aidl-interfaces-V3-java",
592		"ipmemorystore-aidl-interfaces-java",
593		"ksoap2",
594		"libnanohttpd",
595		"libwifi-jni",
596		"net-utils-services-common",
597		"netd_aidl_interface-V2-java",
598		"netd_aidl_interface-unstable-java",
599		"netd_event_listener_interface-java",
600		"netlink-client",
601		"networkstack-client",
602		"services.net",
603		"wifi-lite-protos",
604		"wifi-nano-protos",
605		"wifi-service-pre-jarjar",
606		"wifi-service-resources",
607	}
608	//
609	// Module separator
610	//
611	m["com.android.sdkext"] = []string{
612		"fmtlib_ndk",
613		"libbase_ndk",
614		"libprotobuf-cpp-lite-ndk",
615	}
616	//
617	// Module separator
618	//
619	m["com.android.os.statsd"] = []string{
620		"libstatssocket",
621	}
622	//
623	// Module separator
624	//
625	m[android.AvailableToAnyApex] = []string{
626		// TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
627		"androidx",
628		"androidx-constraintlayout_constraintlayout",
629		"androidx-constraintlayout_constraintlayout-nodeps",
630		"androidx-constraintlayout_constraintlayout-solver",
631		"androidx-constraintlayout_constraintlayout-solver-nodeps",
632		"com.google.android.material_material",
633		"com.google.android.material_material-nodeps",
634
635		"libatomic",
636		"libclang_rt",
637		"libgcc_stripped",
638		"libprofile-clang-extras",
639		"libprofile-clang-extras_ndk",
640		"libprofile-extras",
641		"libprofile-extras_ndk",
642		"libunwind_llvm",
643	}
644	return m
645}
646
647func init() {
648	android.RegisterModuleType("apex", BundleFactory)
649	android.RegisterModuleType("apex_test", testApexBundleFactory)
650	android.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
651	android.RegisterModuleType("apex_defaults", defaultsFactory)
652	android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
653	android.RegisterModuleType("override_apex", overrideApexFactory)
654	android.RegisterModuleType("apex_set", apexSetFactory)
655
656	android.PreDepsMutators(RegisterPreDepsMutators)
657	android.PostDepsMutators(RegisterPostDepsMutators)
658
659	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
660		apexFileContextsInfos := apexFileContextsInfos(ctx.Config())
661		sort.Strings(*apexFileContextsInfos)
662		ctx.Strict("APEX_FILE_CONTEXTS_INFOS", strings.Join(*apexFileContextsInfos, " "))
663	})
664}
665
666func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
667	ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
668	ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
669}
670
671func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
672	ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
673	ctx.BottomUp("apex", apexMutator).Parallel()
674	ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
675	ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
676	ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
677}
678
679// Mark the direct and transitive dependencies of apex bundles so that they
680// can be built for the apex bundles.
681func apexDepsMutator(mctx android.TopDownMutatorContext) {
682	if !mctx.Module().Enabled() {
683		return
684	}
685	a, ok := mctx.Module().(*apexBundle)
686	if !ok || a.vndkApex {
687		return
688	}
689	apexInfo := android.ApexInfo{
690		ApexName:      mctx.ModuleName(),
691		MinSdkVersion: a.minSdkVersion(mctx),
692		Updatable:     a.Updatable(),
693	}
694
695	useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
696	excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
697	if !useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) {
698		mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
699		return
700	}
701
702	mctx.WalkDeps(func(child, parent android.Module) bool {
703		am, ok := child.(android.ApexModule)
704		if !ok || !am.CanHaveApexVariants() {
705			return false
706		}
707		if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) {
708			return false
709		}
710		if excludeVndkLibs {
711			if c, ok := child.(*cc.Module); ok && c.IsVndk() {
712				return false
713			}
714		}
715
716		depName := mctx.OtherModuleName(child)
717		// If the parent is apexBundle, this child is directly depended.
718		_, directDep := parent.(*apexBundle)
719		android.UpdateApexDependency(apexInfo, depName, directDep)
720		am.BuildForApex(apexInfo)
721		return true
722	})
723}
724
725// mark if a module cannot be available to platform. A module cannot be available
726// to platform if 1) it is explicitly marked as not available (i.e. "//apex_available:platform"
727// is absent) or 2) it depends on another module that isn't (or can't be) available to platform
728func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
729	// Host and recovery are not considered as platform
730	if mctx.Host() || mctx.Module().InstallInRecovery() {
731		return
732	}
733
734	if am, ok := mctx.Module().(android.ApexModule); ok {
735		availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
736
737		// In a rare case when a lib is marked as available only to an apex
738		// but the apex doesn't exist. This can happen in a partial manifest branch
739		// like master-art. Currently, libstatssocket in the stats APEX is causing
740		// this problem.
741		// Include the lib in platform because the module SDK that ought to provide
742		// it doesn't exist, so it would otherwise be left out completely.
743		// TODO(b/154888298) remove this by adding those libraries in module SDKS and skipping
744		// this check for libraries provided by SDKs.
745		if !availableToPlatform && !android.InAnyApex(am.Name()) {
746			availableToPlatform = true
747		}
748
749		// If any of the dep is not available to platform, this module is also considered
750		// as being not available to platform even if it has "//apex_available:platform"
751		mctx.VisitDirectDeps(func(child android.Module) {
752			if !am.DepIsInSameApex(mctx, child) {
753				// if the dependency crosses apex boundary, don't consider it
754				return
755			}
756			if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
757				availableToPlatform = false
758				// TODO(b/154889534) trigger an error when 'am' has "//apex_available:platform"
759			}
760		})
761
762		// Exception 1: stub libraries and native bridge libraries are always available to platform
763		if cc, ok := mctx.Module().(*cc.Module); ok &&
764			(cc.IsStubs() || cc.Target().NativeBridge == android.NativeBridgeEnabled) {
765			availableToPlatform = true
766		}
767
768		// Exception 2: bootstrap bionic libraries are also always available to platform
769		if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
770			availableToPlatform = true
771		}
772
773		if !availableToPlatform {
774			am.SetNotAvailableForPlatform()
775		}
776	}
777}
778
779// If a module in an APEX depends on a module from an SDK then it needs an APEX
780// specific variant created for it. Refer to sdk.sdkDepsReplaceMutator.
781func inAnySdk(module android.Module) bool {
782	if sa, ok := module.(android.SdkAware); ok {
783		return sa.IsInAnySdk()
784	}
785
786	return false
787}
788
789// Create apex variations if a module is included in APEX(s).
790func apexMutator(mctx android.BottomUpMutatorContext) {
791	if !mctx.Module().Enabled() {
792		return
793	}
794	if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
795		am.CreateApexVariations(mctx)
796	} else if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex {
797		// apex bundle itself is mutated so that it and its modules have same
798		// apex variant.
799		apexBundleName := mctx.ModuleName()
800		mctx.CreateVariations(apexBundleName)
801	} else if o, ok := mctx.Module().(*OverrideApex); ok {
802		apexBundleName := o.GetOverriddenModuleName()
803		if apexBundleName == "" {
804			mctx.ModuleErrorf("base property is not set")
805			return
806		}
807		mctx.CreateVariations(apexBundleName)
808	}
809
810}
811
812var (
813	apexFileContextsInfosKey   = android.NewOnceKey("apexFileContextsInfosKey")
814	apexFileContextsInfosMutex sync.Mutex
815)
816
817func apexFileContextsInfos(config android.Config) *[]string {
818	return config.Once(apexFileContextsInfosKey, func() interface{} {
819		return &[]string{}
820	}).(*[]string)
821}
822
823func addFlattenedFileContextsInfos(ctx android.BaseModuleContext, fileContextsInfo string) {
824	apexFileContextsInfosMutex.Lock()
825	defer apexFileContextsInfosMutex.Unlock()
826	apexFileContextsInfos := apexFileContextsInfos(ctx.Config())
827	*apexFileContextsInfos = append(*apexFileContextsInfos, fileContextsInfo)
828}
829
830func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
831	if !mctx.Module().Enabled() {
832		return
833	}
834	if ab, ok := mctx.Module().(*apexBundle); ok {
835		var variants []string
836		switch proptools.StringDefault(ab.properties.Payload_type, "image") {
837		case "image":
838			variants = append(variants, imageApexType, flattenedApexType)
839		case "zip":
840			variants = append(variants, zipApexType)
841		case "both":
842			variants = append(variants, imageApexType, zipApexType, flattenedApexType)
843		default:
844			mctx.PropertyErrorf("type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
845			return
846		}
847
848		modules := mctx.CreateLocalVariations(variants...)
849
850		for i, v := range variants {
851			switch v {
852			case imageApexType:
853				modules[i].(*apexBundle).properties.ApexType = imageApex
854			case zipApexType:
855				modules[i].(*apexBundle).properties.ApexType = zipApex
856			case flattenedApexType:
857				modules[i].(*apexBundle).properties.ApexType = flattenedApex
858				if !mctx.Config().FlattenApex() && ab.Platform() {
859					modules[i].(*apexBundle).MakeAsSystemExt()
860				}
861			}
862		}
863	} else if _, ok := mctx.Module().(*OverrideApex); ok {
864		mctx.CreateVariations(imageApexType, flattenedApexType)
865	}
866}
867
868func apexUsesMutator(mctx android.BottomUpMutatorContext) {
869	if ab, ok := mctx.Module().(*apexBundle); ok {
870		mctx.AddFarVariationDependencies(nil, usesTag, ab.properties.Uses...)
871	}
872}
873
874var (
875	useVendorAllowListKey = android.NewOnceKey("useVendorAllowList")
876)
877
878// useVendorAllowList returns the list of APEXes which are allowed to use_vendor.
879// When use_vendor is used, native modules are built with __ANDROID_VNDK__ and __ANDROID_APEX__,
880// which may cause compatibility issues. (e.g. libbinder)
881// Even though libbinder restricts its availability via 'apex_available' property and relies on
882// yet another macro __ANDROID_APEX_<NAME>__, we restrict usage of "use_vendor:" from other APEX modules
883// to avoid similar problems.
884func useVendorAllowList(config android.Config) []string {
885	return config.Once(useVendorAllowListKey, func() interface{} {
886		return []string{
887			// swcodec uses "vendor" variants for smaller size
888			"com.android.media.swcodec",
889			"test_com.android.media.swcodec",
890		}
891	}).([]string)
892}
893
894// setUseVendorAllowListForTest overrides useVendorAllowList and must be
895// called before the first call to useVendorAllowList()
896func setUseVendorAllowListForTest(config android.Config, allowList []string) {
897	config.Once(useVendorAllowListKey, func() interface{} {
898		return allowList
899	})
900}
901
902type ApexNativeDependencies struct {
903	// List of native libraries
904	Native_shared_libs []string
905
906	// List of JNI libraries
907	Jni_libs []string
908
909	// List of native executables
910	Binaries []string
911
912	// List of native tests
913	Tests []string
914}
915
916type apexMultilibProperties struct {
917	// Native dependencies whose compile_multilib is "first"
918	First ApexNativeDependencies
919
920	// Native dependencies whose compile_multilib is "both"
921	Both ApexNativeDependencies
922
923	// Native dependencies whose compile_multilib is "prefer32"
924	Prefer32 ApexNativeDependencies
925
926	// Native dependencies whose compile_multilib is "32"
927	Lib32 ApexNativeDependencies
928
929	// Native dependencies whose compile_multilib is "64"
930	Lib64 ApexNativeDependencies
931}
932
933type apexBundleProperties struct {
934	// Json manifest file describing meta info of this APEX bundle. Default:
935	// "apex_manifest.json"
936	Manifest *string `android:"path"`
937
938	// AndroidManifest.xml file used for the zip container of this APEX bundle.
939	// If unspecified, a default one is automatically generated.
940	AndroidManifest *string `android:"path"`
941
942	// Canonical name of the APEX bundle. Used to determine the path to the activated APEX on
943	// device (/apex/<apex_name>).
944	// If unspecified, defaults to the value of name.
945	Apex_name *string
946
947	// Determines the file contexts file for setting security context to each file in this APEX bundle.
948	// For platform APEXes, this should points to a file under /system/sepolicy
949	// Default: /system/sepolicy/apex/<module_name>_file_contexts.
950	File_contexts *string `android:"path"`
951
952	ApexNativeDependencies
953
954	// List of java libraries that are embedded inside this APEX bundle
955	Java_libs []string
956
957	// List of prebuilt files that are embedded inside this APEX bundle
958	Prebuilts []string
959
960	// Name of the apex_key module that provides the private key to sign APEX
961	Key *string
962
963	// The type of APEX to build. Controls what the APEX payload is. Either
964	// 'image', 'zip' or 'both'. Default: 'image'.
965	Payload_type *string
966
967	// The name of a certificate in the default certificate directory, blank to use the default product certificate,
968	// or an android_app_certificate module name in the form ":module".
969	Certificate *string
970
971	// Whether this APEX is installable to one of the partitions. Default: true.
972	Installable *bool
973
974	// For native libraries and binaries, use the vendor variant instead of the core (platform) variant.
975	// Default is false.
976	Use_vendor *bool
977
978	// For telling the apex to ignore special handling for system libraries such as bionic. Default is false.
979	Ignore_system_library_special_case *bool
980
981	Multilib apexMultilibProperties
982
983	// List of sanitizer names that this APEX is enabled for
984	SanitizerNames []string `blueprint:"mutated"`
985
986	PreventInstall bool `blueprint:"mutated"`
987
988	HideFromMake bool `blueprint:"mutated"`
989
990	// Indicates this APEX provides C++ shared libaries to other APEXes. Default: false.
991	Provide_cpp_shared_libs *bool
992
993	// List of providing APEXes' names so that this APEX can depend on provided shared libraries.
994	Uses []string
995
996	// package format of this apex variant; could be non-flattened, flattened, or zip.
997	// imageApex, zipApex or flattened
998	ApexType apexPackaging `blueprint:"mutated"`
999
1000	// List of SDKs that are used to build this APEX. A reference to an SDK should be either
1001	// `name#version` or `name` which is an alias for `name#current`. If left empty, `platform#current`
1002	// is implied. This value affects all modules included in this APEX. In other words, they are
1003	// also built with the SDKs specified here.
1004	Uses_sdks []string
1005
1006	// Whenever apex_payload.img of the APEX should include dm-verity hashtree.
1007	// Should be only used in tests#.
1008	Test_only_no_hashtree *bool
1009
1010	// Whenever apex_payload.img of the APEX should not be dm-verity signed.
1011	// Should be only used in tests#.
1012	Test_only_unsigned_payload *bool
1013
1014	IsCoverageVariant bool `blueprint:"mutated"`
1015
1016	// Whether this APEX is considered updatable or not. When set to true, this will enforce additional
1017	// rules for making sure that the APEX is truly updatable.
1018	// - To be updatable, min_sdk_version should be set as well
1019	// This will also disable the size optimizations like symlinking to the system libs.
1020	// Default is false.
1021	Updatable *bool
1022
1023	// The minimum SDK version that this apex must be compatibile with.
1024	Min_sdk_version *string
1025
1026	// If set true, VNDK libs are considered as stable libs and are not included in this apex.
1027	// Should be only used in non-system apexes (e.g. vendor: true).
1028	// Default is false.
1029	Use_vndk_as_stable *bool
1030}
1031
1032type apexTargetBundleProperties struct {
1033	Target struct {
1034		// Multilib properties only for android.
1035		Android struct {
1036			Multilib apexMultilibProperties
1037		}
1038
1039		// Multilib properties only for host.
1040		Host struct {
1041			Multilib apexMultilibProperties
1042		}
1043
1044		// Multilib properties only for host linux_bionic.
1045		Linux_bionic struct {
1046			Multilib apexMultilibProperties
1047		}
1048
1049		// Multilib properties only for host linux_glibc.
1050		Linux_glibc struct {
1051			Multilib apexMultilibProperties
1052		}
1053	}
1054}
1055
1056type overridableProperties struct {
1057	// List of APKs to package inside APEX
1058	Apps []string
1059
1060	// List of runtime resource overlays (RROs) inside APEX
1061	Rros []string
1062
1063	// Names of modules to be overridden. Listed modules can only be other binaries
1064	// (in Make or Soong).
1065	// This does not completely prevent installation of the overridden binaries, but if both
1066	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
1067	// from PRODUCT_PACKAGES.
1068	Overrides []string
1069
1070	// Logging Parent value
1071	Logging_parent string
1072
1073	// Apex Container Package Name.
1074	// Override value for attribute package:name in AndroidManifest.xml
1075	Package_name string
1076
1077	// A txt file containing list of files that are allowed to be included in this APEX.
1078	Allowed_files *string `android:"path"`
1079}
1080
1081type apexPackaging int
1082
1083const (
1084	imageApex apexPackaging = iota
1085	zipApex
1086	flattenedApex
1087)
1088
1089// The suffix for the output "file", not the module
1090func (a apexPackaging) suffix() string {
1091	switch a {
1092	case imageApex:
1093		return imageApexSuffix
1094	case zipApex:
1095		return zipApexSuffix
1096	default:
1097		panic(fmt.Errorf("unknown APEX type %d", a))
1098	}
1099}
1100
1101func (a apexPackaging) name() string {
1102	switch a {
1103	case imageApex:
1104		return imageApexType
1105	case zipApex:
1106		return zipApexType
1107	default:
1108		panic(fmt.Errorf("unknown APEX type %d", a))
1109	}
1110}
1111
1112type apexFileClass int
1113
1114const (
1115	etc apexFileClass = iota
1116	nativeSharedLib
1117	nativeExecutable
1118	shBinary
1119	pyBinary
1120	goBinary
1121	javaSharedLib
1122	nativeTest
1123	app
1124	appSet
1125)
1126
1127func (class apexFileClass) NameInMake() string {
1128	switch class {
1129	case etc:
1130		return "ETC"
1131	case nativeSharedLib:
1132		return "SHARED_LIBRARIES"
1133	case nativeExecutable, shBinary, pyBinary, goBinary:
1134		return "EXECUTABLES"
1135	case javaSharedLib:
1136		return "JAVA_LIBRARIES"
1137	case nativeTest:
1138		return "NATIVE_TESTS"
1139	case app, appSet:
1140		// b/142537672 Why isn't this APP? We want to have full control over
1141		// the paths and file names of the apk file under the flattend APEX.
1142		// If this is set to APP, then the paths and file names are modified
1143		// by the Make build system. For example, it is installed to
1144		// /system/apex/<apexname>/app/<Appname>/<apexname>.<Appname>/ instead of
1145		// /system/apex/<apexname>/app/<Appname> because the build system automatically
1146		// appends module name (which is <apexname>.<Appname> to the path.
1147		return "ETC"
1148	default:
1149		panic(fmt.Errorf("unknown class %d", class))
1150	}
1151}
1152
1153// apexFile represents a file in an APEX bundle
1154type apexFile struct {
1155	builtFile android.Path
1156	stem      string
1157	// Module name of `module` in AndroidMk. Note the generated AndroidMk module for
1158	// apexFile is named something like <AndroidMk module name>.<apex name>[<apex suffix>]
1159	androidMkModuleName string
1160	installDir          string
1161	class               apexFileClass
1162	module              android.Module
1163	// list of symlinks that will be created in installDir that point to this apexFile
1164	symlinks      []string
1165	dataPaths     []android.DataPath
1166	transitiveDep bool
1167	moduleDir     string
1168
1169	requiredModuleNames       []string
1170	targetRequiredModuleNames []string
1171	hostRequiredModuleNames   []string
1172
1173	jacocoReportClassesFile android.Path     // only for javalibs and apps
1174	lintDepSets             java.LintDepSets // only for javalibs and apps
1175	certificate             java.Certificate // only for apps
1176	overriddenPackageName   string           // only for apps
1177
1178	isJniLib bool
1179}
1180
1181func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
1182	ret := apexFile{
1183		builtFile:           builtFile,
1184		androidMkModuleName: androidMkModuleName,
1185		installDir:          installDir,
1186		class:               class,
1187		module:              module,
1188	}
1189	if module != nil {
1190		ret.moduleDir = ctx.OtherModuleDir(module)
1191		ret.requiredModuleNames = module.RequiredModuleNames()
1192		ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
1193		ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
1194	}
1195	return ret
1196}
1197
1198func (af *apexFile) Ok() bool {
1199	return af.builtFile != nil && af.builtFile.String() != ""
1200}
1201
1202func (af *apexFile) apexRelativePath(path string) string {
1203	return filepath.Join(af.installDir, path)
1204}
1205
1206// Path() returns path of this apex file relative to the APEX root
1207func (af *apexFile) Path() string {
1208	return af.apexRelativePath(af.Stem())
1209}
1210
1211func (af *apexFile) Stem() string {
1212	if af.stem != "" {
1213		return af.stem
1214	}
1215	return af.builtFile.Base()
1216}
1217
1218// SymlinkPaths() returns paths of the symlinks (if any) relative to the APEX root
1219func (af *apexFile) SymlinkPaths() []string {
1220	var ret []string
1221	for _, symlink := range af.symlinks {
1222		ret = append(ret, af.apexRelativePath(symlink))
1223	}
1224	return ret
1225}
1226
1227func (af *apexFile) AvailableToPlatform() bool {
1228	if af.module == nil {
1229		return false
1230	}
1231	if am, ok := af.module.(android.ApexModule); ok {
1232		return am.AvailableFor(android.AvailableToPlatform)
1233	}
1234	return false
1235}
1236
1237type apexBundle struct {
1238	android.ModuleBase
1239	android.DefaultableModuleBase
1240	android.OverridableModuleBase
1241	android.SdkBase
1242
1243	properties            apexBundleProperties
1244	targetProperties      apexTargetBundleProperties
1245	overridableProperties overridableProperties
1246
1247	// specific to apex_vndk modules
1248	vndkProperties apexVndkProperties
1249
1250	bundleModuleFile android.WritablePath
1251	outputFile       android.WritablePath
1252	installDir       android.InstallPath
1253
1254	prebuiltFileToDelete string
1255
1256	public_key_file  android.Path
1257	private_key_file android.Path
1258
1259	container_certificate_file android.Path
1260	container_private_key_file android.Path
1261
1262	fileContexts android.WritablePath
1263
1264	// list of files to be included in this apex
1265	filesInfo []apexFile
1266
1267	// list of module names that should be installed along with this APEX
1268	requiredDeps []string
1269
1270	// list of module names that this APEX is including (to be shown via *-deps-info target)
1271	android.ApexBundleDepsInfo
1272
1273	testApex        bool
1274	vndkApex        bool
1275	artApex         bool
1276	primaryApexType bool
1277
1278	manifestJsonOut android.WritablePath
1279	manifestPbOut   android.WritablePath
1280
1281	// list of commands to create symlinks for backward compatibility.
1282	// these commands will be attached as LOCAL_POST_INSTALL_CMD to
1283	// apex package itself(for unflattened build) or apex_manifest(for flattened build)
1284	// so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting.
1285	compatSymlinks []string
1286
1287	// Suffix of module name in Android.mk
1288	// ".flattened", ".apex", ".zipapex", or ""
1289	suffix string
1290
1291	installedFilesFile android.WritablePath
1292
1293	// Whether to create symlink to the system file instead of having a file
1294	// inside the apex or not
1295	linkToSystemLib bool
1296
1297	// Struct holding the merged notice file paths in different formats
1298	mergedNotices android.NoticeOutputs
1299
1300	// Optional list of lint report zip files for apexes that contain java or app modules
1301	lintReports android.Paths
1302}
1303
1304func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
1305	nativeModules ApexNativeDependencies,
1306	target android.Target, imageVariation string) {
1307	// Use *FarVariation* to be able to depend on modules having
1308	// conflicting variations with this module. This is required since
1309	// arch variant of an APEX bundle is 'common' but it is 'arm' or 'arm64'
1310	// for native shared libs.
1311	ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
1312		{Mutator: "image", Variation: imageVariation},
1313		{Mutator: "link", Variation: "shared"},
1314		{Mutator: "version", Variation: ""}, // "" is the non-stub variant
1315	}...), sharedLibTag, nativeModules.Native_shared_libs...)
1316
1317	ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
1318		{Mutator: "image", Variation: imageVariation},
1319		{Mutator: "link", Variation: "shared"},
1320		{Mutator: "version", Variation: ""}, // "" is the non-stub variant
1321	}...), jniLibTag, nativeModules.Jni_libs...)
1322
1323	ctx.AddFarVariationDependencies(append(target.Variations(),
1324		blueprint.Variation{Mutator: "image", Variation: imageVariation}),
1325		executableTag, nativeModules.Binaries...)
1326
1327	ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
1328		{Mutator: "image", Variation: imageVariation},
1329		{Mutator: "test_per_src", Variation: ""}, // "" is the all-tests variant
1330	}...), testTag, nativeModules.Tests...)
1331}
1332
1333func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
1334	if ctx.Os().Class == android.Device {
1335		proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
1336	} else {
1337		proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
1338		if ctx.Os().Bionic() {
1339			proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
1340		} else {
1341			proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
1342		}
1343	}
1344}
1345
1346func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
1347	if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorAllowList(ctx.Config())) {
1348		ctx.PropertyErrorf("use_vendor", "not allowed to set use_vendor: true")
1349	}
1350
1351	targets := ctx.MultiTargets()
1352	config := ctx.DeviceConfig()
1353	imageVariation := a.getImageVariation(ctx)
1354
1355	a.combineProperties(ctx)
1356
1357	has32BitTarget := false
1358	for _, target := range targets {
1359		if target.Arch.ArchType.Multilib == "lib32" {
1360			has32BitTarget = true
1361		}
1362	}
1363	for i, target := range targets {
1364		// When multilib.* is omitted for native_shared_libs/jni_libs/tests, it implies
1365		// multilib.both
1366		addDependenciesForNativeModules(ctx,
1367			ApexNativeDependencies{
1368				Native_shared_libs: a.properties.Native_shared_libs,
1369				Tests:              a.properties.Tests,
1370				Jni_libs:           a.properties.Jni_libs,
1371				Binaries:           nil,
1372			},
1373			target, imageVariation)
1374
1375		// Add native modules targetting both ABIs
1376		addDependenciesForNativeModules(ctx,
1377			a.properties.Multilib.Both,
1378			target,
1379			imageVariation)
1380
1381		isPrimaryAbi := i == 0
1382		if isPrimaryAbi {
1383			// When multilib.* is omitted for binaries, it implies
1384			// multilib.first
1385			addDependenciesForNativeModules(ctx,
1386				ApexNativeDependencies{
1387					Native_shared_libs: nil,
1388					Tests:              nil,
1389					Jni_libs:           nil,
1390					Binaries:           a.properties.Binaries,
1391				},
1392				target, imageVariation)
1393
1394			// Add native modules targetting the first ABI
1395			addDependenciesForNativeModules(ctx,
1396				a.properties.Multilib.First,
1397				target,
1398				imageVariation)
1399		}
1400
1401		switch target.Arch.ArchType.Multilib {
1402		case "lib32":
1403			// Add native modules targetting 32-bit ABI
1404			addDependenciesForNativeModules(ctx,
1405				a.properties.Multilib.Lib32,
1406				target,
1407				imageVariation)
1408
1409			addDependenciesForNativeModules(ctx,
1410				a.properties.Multilib.Prefer32,
1411				target,
1412				imageVariation)
1413		case "lib64":
1414			// Add native modules targetting 64-bit ABI
1415			addDependenciesForNativeModules(ctx,
1416				a.properties.Multilib.Lib64,
1417				target,
1418				imageVariation)
1419
1420			if !has32BitTarget {
1421				addDependenciesForNativeModules(ctx,
1422					a.properties.Multilib.Prefer32,
1423					target,
1424					imageVariation)
1425			}
1426		}
1427	}
1428
1429	// For prebuilt_etc, use the first variant (64 on 64/32bit device,
1430	// 32 on 32bit device) regardless of the TARGET_PREFER_* setting.
1431	// b/144532908
1432	archForPrebuiltEtc := config.Arches()[0]
1433	for _, arch := range config.Arches() {
1434		// Prefer 64-bit arch if there is any
1435		if arch.ArchType.Multilib == "lib64" {
1436			archForPrebuiltEtc = arch
1437			break
1438		}
1439	}
1440	ctx.AddFarVariationDependencies([]blueprint.Variation{
1441		{Mutator: "os", Variation: ctx.Os().String()},
1442		{Mutator: "arch", Variation: archForPrebuiltEtc.String()},
1443	}, prebuiltTag, a.properties.Prebuilts...)
1444
1445	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
1446		javaLibTag, a.properties.Java_libs...)
1447
1448	// With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library.
1449	if a.artApex && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
1450		ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
1451			javaLibTag, "jacocoagent")
1452	}
1453
1454	if String(a.properties.Key) == "" {
1455		ctx.ModuleErrorf("key is missing")
1456		return
1457	}
1458	ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
1459
1460	cert := android.SrcIsModule(a.getCertString(ctx))
1461	if cert != "" {
1462		ctx.AddDependency(ctx.Module(), certificateTag, cert)
1463	}
1464
1465	// TODO(jiyong): ensure that all apexes are with non-empty uses_sdks
1466	if len(a.properties.Uses_sdks) > 0 {
1467		sdkRefs := []android.SdkRef{}
1468		for _, str := range a.properties.Uses_sdks {
1469			parsed := android.ParseSdkRef(ctx, str, "uses_sdks")
1470			sdkRefs = append(sdkRefs, parsed)
1471		}
1472		a.BuildWithSdks(sdkRefs)
1473	}
1474}
1475
1476func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1477	if a.overridableProperties.Allowed_files != nil {
1478		android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
1479	}
1480	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
1481		androidAppTag, a.overridableProperties.Apps...)
1482	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
1483		rroTag, a.overridableProperties.Rros...)
1484}
1485
1486func (a *apexBundle) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1487	// direct deps of an APEX bundle are all part of the APEX bundle
1488	return true
1489}
1490
1491func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
1492	moduleName := ctx.ModuleName()
1493	// VNDK APEXes share the same certificate. To avoid adding a new VNDK version to the OVERRIDE_* list,
1494	// we check with the pseudo module name to see if its certificate is overridden.
1495	if a.vndkApex {
1496		moduleName = vndkApexName
1497	}
1498	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(moduleName)
1499	if overridden {
1500		return ":" + certificate
1501	}
1502	return String(a.properties.Certificate)
1503}
1504
1505func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
1506	switch tag {
1507	case "":
1508		return android.Paths{a.outputFile}, nil
1509	default:
1510		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1511	}
1512}
1513
1514func (a *apexBundle) installable() bool {
1515	return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
1516}
1517
1518func (a *apexBundle) testOnlyShouldSkipHashtreeGeneration() bool {
1519	return proptools.Bool(a.properties.Test_only_no_hashtree)
1520}
1521
1522func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
1523	return proptools.Bool(a.properties.Test_only_unsigned_payload)
1524}
1525
1526func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
1527	deviceConfig := ctx.DeviceConfig()
1528	if a.vndkApex {
1529		return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
1530	}
1531
1532	var prefix string
1533	var vndkVersion string
1534	if deviceConfig.VndkVersion() != "" {
1535		if proptools.Bool(a.properties.Use_vendor) {
1536			prefix = cc.VendorVariationPrefix
1537			vndkVersion = deviceConfig.PlatformVndkVersion()
1538		} else if a.SocSpecific() || a.DeviceSpecific() {
1539			prefix = cc.VendorVariationPrefix
1540			vndkVersion = deviceConfig.VndkVersion()
1541		} else if a.ProductSpecific() {
1542			prefix = cc.ProductVariationPrefix
1543			vndkVersion = deviceConfig.ProductVndkVersion()
1544		}
1545	}
1546	if vndkVersion == "current" {
1547		vndkVersion = deviceConfig.PlatformVndkVersion()
1548	}
1549	if vndkVersion != "" {
1550		return prefix + vndkVersion
1551	}
1552	return android.CoreVariation
1553}
1554
1555func (a *apexBundle) EnableSanitizer(sanitizerName string) {
1556	if !android.InList(sanitizerName, a.properties.SanitizerNames) {
1557		a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
1558	}
1559}
1560
1561func (a *apexBundle) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool {
1562	if android.InList(sanitizerName, a.properties.SanitizerNames) {
1563		return true
1564	}
1565
1566	// Then follow the global setting
1567	globalSanitizerNames := []string{}
1568	if a.Host() {
1569		globalSanitizerNames = ctx.Config().SanitizeHost()
1570	} else {
1571		arches := ctx.Config().SanitizeDeviceArch()
1572		if len(arches) == 0 || android.InList(a.Arch().ArchType.Name, arches) {
1573			globalSanitizerNames = ctx.Config().SanitizeDevice()
1574		}
1575	}
1576	return android.InList(sanitizerName, globalSanitizerNames)
1577}
1578
1579func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string) {
1580	if ctx.Device() && sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
1581		for _, target := range ctx.MultiTargets() {
1582			if target.Arch.ArchType.Multilib == "lib64" {
1583				ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
1584					{Mutator: "image", Variation: a.getImageVariation(ctx)},
1585					{Mutator: "link", Variation: "shared"},
1586					{Mutator: "version", Variation: ""}, // "" is the non-stub variant
1587				}...), sharedLibTag, "libclang_rt.hwasan-aarch64-android")
1588				break
1589			}
1590		}
1591	}
1592}
1593
1594var _ cc.Coverage = (*apexBundle)(nil)
1595
1596func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
1597	return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1598}
1599
1600func (a *apexBundle) PreventInstall() {
1601	a.properties.PreventInstall = true
1602}
1603
1604func (a *apexBundle) HideFromMake() {
1605	a.properties.HideFromMake = true
1606}
1607
1608func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
1609	a.properties.IsCoverageVariant = coverage
1610}
1611
1612func (a *apexBundle) EnableCoverageIfNeeded() {}
1613
1614// TODO(jiyong) move apexFileFor* close to the apexFile type definition
1615func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
1616	// Decide the APEX-local directory by the multilib of the library
1617	// In the future, we may query this to the module.
1618	var dirInApex string
1619	switch ccMod.Arch().ArchType.Multilib {
1620	case "lib32":
1621		dirInApex = "lib"
1622	case "lib64":
1623		dirInApex = "lib64"
1624	}
1625	if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
1626		dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
1627	}
1628	dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
1629	if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) {
1630		// Special case for Bionic libs and other libs installed with them. This is
1631		// to prevent those libs from being included in the search path
1632		// /apex/com.android.runtime/${LIB}. This exclusion is required because
1633		// those libs in the Runtime APEX are available via the legacy paths in
1634		// /system/lib/. By the init process, the libs in the APEX are bind-mounted
1635		// to the legacy paths and thus will be loaded into the default linker
1636		// namespace (aka "platform" namespace). If the libs are directly in
1637		// /apex/com.android.runtime/${LIB} then the same libs will be loaded again
1638		// into the runtime linker namespace, which will result in double loading of
1639		// them, which isn't supported.
1640		dirInApex = filepath.Join(dirInApex, "bionic")
1641	}
1642
1643	fileToCopy := ccMod.OutputFile().Path()
1644	androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
1645	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
1646}
1647
1648func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
1649	dirInApex := "bin"
1650	if cc.Target().NativeBridge == android.NativeBridgeEnabled {
1651		dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
1652	}
1653	dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
1654	fileToCopy := cc.OutputFile().Path()
1655	androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
1656	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
1657	af.symlinks = cc.Symlinks()
1658	af.dataPaths = cc.DataPaths()
1659	return af
1660}
1661
1662func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
1663	dirInApex := "bin"
1664	fileToCopy := py.HostToolPath().Path()
1665	return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
1666}
1667func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
1668	dirInApex := "bin"
1669	s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
1670	if err != nil {
1671		ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath())
1672		return apexFile{}
1673	}
1674	fileToCopy := android.PathForOutput(ctx, s)
1675	// NB: Since go binaries are static we don't need the module for anything here, which is
1676	// good since the go tool is a blueprint.Module not an android.Module like we would
1677	// normally use.
1678	return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil)
1679}
1680
1681func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
1682	dirInApex := filepath.Join("bin", sh.SubDir())
1683	fileToCopy := sh.OutputFile()
1684	af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
1685	af.symlinks = sh.Symlinks()
1686	return af
1687}
1688
1689type javaModule interface {
1690	android.Module
1691	BaseModuleName() string
1692	DexJarBuildPath() android.Path
1693	JacocoReportClassesFile() android.Path
1694	LintDepSets() java.LintDepSets
1695
1696	Stem() string
1697}
1698
1699var _ javaModule = (*java.Library)(nil)
1700var _ javaModule = (*java.SdkLibrary)(nil)
1701var _ javaModule = (*java.DexImport)(nil)
1702var _ javaModule = (*java.SdkLibraryImport)(nil)
1703
1704func apexFileForJavaLibrary(ctx android.BaseModuleContext, module javaModule) apexFile {
1705	dirInApex := "javalib"
1706	fileToCopy := module.DexJarBuildPath()
1707	af := newApexFile(ctx, fileToCopy, module.BaseModuleName(), dirInApex, javaSharedLib, module)
1708	af.jacocoReportClassesFile = module.JacocoReportClassesFile()
1709	af.lintDepSets = module.LintDepSets()
1710	af.stem = module.Stem() + ".jar"
1711	return af
1712}
1713
1714func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
1715	dirInApex := filepath.Join("etc", prebuilt.SubDir())
1716	fileToCopy := prebuilt.OutputFile()
1717	return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
1718}
1719
1720func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
1721	dirInApex := filepath.Join("etc", config.SubDir())
1722	fileToCopy := config.CompatConfig()
1723	return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
1724}
1725
1726func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp interface {
1727	android.Module
1728	Privileged() bool
1729	InstallApkName() string
1730	OutputFile() android.Path
1731	JacocoReportClassesFile() android.Path
1732	Certificate() java.Certificate
1733	BaseModuleName() string
1734}) apexFile {
1735	appDir := "app"
1736	if aapp.Privileged() {
1737		appDir = "priv-app"
1738	}
1739	dirInApex := filepath.Join(appDir, aapp.InstallApkName())
1740	fileToCopy := aapp.OutputFile()
1741	af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
1742	af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
1743	af.certificate = aapp.Certificate()
1744
1745	if app, ok := aapp.(interface {
1746		OverriddenManifestPackageName() string
1747	}); ok {
1748		af.overriddenPackageName = app.OverriddenManifestPackageName()
1749	}
1750	return af
1751}
1752
1753func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
1754	rroDir := "overlay"
1755	dirInApex := filepath.Join(rroDir, rro.Theme())
1756	fileToCopy := rro.OutputFile()
1757	af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
1758	af.certificate = rro.Certificate()
1759
1760	if a, ok := rro.(interface {
1761		OverriddenManifestPackageName() string
1762	}); ok {
1763		af.overriddenPackageName = a.OverriddenManifestPackageName()
1764	}
1765	return af
1766}
1767
1768// Context "decorator", overriding the InstallBypassMake method to always reply `true`.
1769type flattenedApexContext struct {
1770	android.ModuleContext
1771}
1772
1773func (c *flattenedApexContext) InstallBypassMake() bool {
1774	return true
1775}
1776
1777// Visit dependencies that contributes to the payload of this APEX
1778func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
1779	ctx.WalkDeps(func(child, parent android.Module) bool {
1780		am, ok := child.(android.ApexModule)
1781		if !ok || !am.CanHaveApexVariants() {
1782			return false
1783		}
1784
1785		dt := ctx.OtherModuleDependencyTag(child)
1786
1787		if _, ok := dt.(android.ExcludeFromApexContentsTag); ok {
1788			return false
1789		}
1790
1791		// Check for the direct dependencies that contribute to the payload
1792		if adt, ok := dt.(dependencyTag); ok {
1793			if adt.payload {
1794				return do(ctx, parent, am, false /* externalDep */)
1795			}
1796			// As soon as the dependency graph crosses the APEX boundary, don't go further.
1797			return false
1798		}
1799
1800		// Check for the indirect dependencies if it is considered as part of the APEX
1801		if am.ApexName() != "" {
1802			return do(ctx, parent, am, false /* externalDep */)
1803		}
1804
1805		return do(ctx, parent, am, true /* externalDep */)
1806	})
1807}
1808
1809func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) int {
1810	ver := proptools.String(a.properties.Min_sdk_version)
1811	if ver == "" {
1812		return android.FutureApiLevel
1813	}
1814	// Treat the current codenames as "current", which means future API version (10000)
1815	// Otherwise, ApiStrToNum converts codename(non-finalized) to a value from [9000...]
1816	// and would fail to build against "current".
1817	if android.InList(ver, ctx.Config().PlatformVersionActiveCodenames()) {
1818		return android.FutureApiLevel
1819	}
1820	// In "REL" branch, "current" is mapped to finalized sdk version
1821	if ctx.Config().PlatformSdkCodename() == "REL" && ver == "current" {
1822		return ctx.Config().PlatformSdkVersionInt()
1823	}
1824	// Finalized codenames are OKAY and will be converted to int
1825	intVer, err := android.ApiStrToNum(ctx, ver)
1826	if err != nil {
1827		ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
1828	}
1829	return intVer
1830}
1831
1832func (a *apexBundle) Updatable() bool {
1833	return proptools.Bool(a.properties.Updatable)
1834}
1835
1836var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
1837
1838// Ensures that the dependencies are marked as available for this APEX
1839func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
1840	// Let's be practical. Availability for test, host, and the VNDK apex isn't important
1841	if ctx.Host() || a.testApex || a.vndkApex {
1842		return
1843	}
1844
1845	// Because APEXes targeting other than system/system_ext partitions
1846	// can't set apex_available, we skip checks for these APEXes
1847	if a.SocSpecific() || a.DeviceSpecific() ||
1848		(a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
1849		return
1850	}
1851
1852	// Coverage build adds additional dependencies for the coverage-only runtime libraries.
1853	// Requiring them and their transitive depencies with apex_available is not right
1854	// because they just add noise.
1855	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
1856		return
1857	}
1858
1859	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
1860		if externalDep {
1861			// As soon as the dependency graph crosses the APEX boundary, don't go further.
1862			return false
1863		}
1864
1865		apexName := ctx.ModuleName()
1866		fromName := ctx.OtherModuleName(from)
1867		toName := ctx.OtherModuleName(to)
1868
1869		// If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither
1870		// do any of its dependencies.
1871		if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
1872			// As soon as the dependency graph crosses the APEX boundary, don't go further.
1873			return false
1874		}
1875
1876		if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
1877			return true
1878		}
1879		ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, ctx.GetPathString(true))
1880		// Visit this module's dependencies to check and report any issues with their availability.
1881		return true
1882	})
1883}
1884
1885func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
1886	if a.Updatable() {
1887		if String(a.properties.Min_sdk_version) == "" {
1888			ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
1889		}
1890
1891		a.checkJavaStableSdkVersion(ctx)
1892	}
1893}
1894
1895func (a *apexBundle) checkMinSdkVersion(ctx android.ModuleContext) {
1896	if a.testApex || a.vndkApex {
1897		return
1898	}
1899	// Meaningless to check min_sdk_version when building use_vendor modules against non-Trebleized targets
1900	if proptools.Bool(a.properties.Use_vendor) && ctx.DeviceConfig().VndkVersion() == "" {
1901		return
1902	}
1903	android.CheckMinSdkVersion(a, ctx, a.minSdkVersion(ctx))
1904}
1905
1906// Ensures that a lib providing stub isn't statically linked
1907func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) {
1908	// Practically, we only care about regular APEXes on the device.
1909	if ctx.Host() || a.testApex || a.vndkApex {
1910		return
1911	}
1912
1913	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
1914		if ccm, ok := to.(*cc.Module); ok {
1915			apexName := ctx.ModuleName()
1916			fromName := ctx.OtherModuleName(from)
1917			toName := ctx.OtherModuleName(to)
1918
1919			// If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither
1920			// do any of its dependencies.
1921			if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
1922				// As soon as the dependency graph crosses the APEX boundary, don't go further.
1923				return false
1924			}
1925
1926			// TODO(jiyong) remove this check when R is published to AOSP. Currently, libstatssocket
1927			// is capable of providing a stub variant, but is being statically linked from the bluetooth
1928			// APEX.
1929			if toName == "libstatssocket" {
1930				return false
1931			}
1932
1933			// The dynamic linker and crash_dump tool in the runtime APEX is the only exception to this rule.
1934			// It can't make the static dependencies dynamic because it can't
1935			// do the dynamic linking for itself.
1936			if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump") {
1937				return false
1938			}
1939
1940			isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !android.DirectlyInApex(apexName, toName)
1941			if isStubLibraryFromOtherApex && !externalDep {
1942				ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
1943					"It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
1944			}
1945
1946		}
1947		return true
1948	})
1949}
1950
1951func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1952	buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuildApps()
1953	switch a.properties.ApexType {
1954	case imageApex:
1955		if buildFlattenedAsDefault {
1956			a.suffix = imageApexSuffix
1957		} else {
1958			a.suffix = ""
1959			a.primaryApexType = true
1960
1961			if ctx.Config().InstallExtraFlattenedApexes() {
1962				a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
1963			}
1964		}
1965	case zipApex:
1966		if proptools.String(a.properties.Payload_type) == "zip" {
1967			a.suffix = ""
1968			a.primaryApexType = true
1969		} else {
1970			a.suffix = zipApexSuffix
1971		}
1972	case flattenedApex:
1973		if buildFlattenedAsDefault {
1974			a.suffix = ""
1975			a.primaryApexType = true
1976		} else {
1977			a.suffix = flattenedSuffix
1978		}
1979	}
1980
1981	if len(a.properties.Tests) > 0 && !a.testApex {
1982		ctx.PropertyErrorf("tests", "property not allowed in apex module type")
1983		return
1984	}
1985
1986	a.checkApexAvailability(ctx)
1987	a.checkUpdatable(ctx)
1988	a.checkMinSdkVersion(ctx)
1989	a.checkStaticLinkingToStubLibraries(ctx)
1990
1991	handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
1992
1993	// native lib dependencies
1994	var provideNativeLibs []string
1995	var requireNativeLibs []string
1996
1997	// Check if "uses" requirements are met with dependent apexBundles
1998	var providedNativeSharedLibs []string
1999	useVendor := proptools.Bool(a.properties.Use_vendor)
2000	ctx.VisitDirectDepsBlueprint(func(m blueprint.Module) {
2001		if ctx.OtherModuleDependencyTag(m) != usesTag {
2002			return
2003		}
2004		otherName := ctx.OtherModuleName(m)
2005		other, ok := m.(*apexBundle)
2006		if !ok {
2007			ctx.PropertyErrorf("uses", "%q is not a provider", otherName)
2008			return
2009		}
2010		if proptools.Bool(other.properties.Use_vendor) != useVendor {
2011			ctx.PropertyErrorf("use_vendor", "%q has different value of use_vendor", otherName)
2012			return
2013		}
2014		if !proptools.Bool(other.properties.Provide_cpp_shared_libs) {
2015			ctx.PropertyErrorf("uses", "%q does not provide native_shared_libs", otherName)
2016			return
2017		}
2018		providedNativeSharedLibs = append(providedNativeSharedLibs, other.properties.Native_shared_libs...)
2019	})
2020
2021	var filesInfo []apexFile
2022	// TODO(jiyong) do this using WalkPayloadDeps
2023	ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
2024		depTag := ctx.OtherModuleDependencyTag(child)
2025		if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
2026			return false
2027		}
2028		depName := ctx.OtherModuleName(child)
2029		if _, isDirectDep := parent.(*apexBundle); isDirectDep {
2030			switch depTag {
2031			case sharedLibTag, jniLibTag:
2032				isJniLib := depTag == jniLibTag
2033				if c, ok := child.(*cc.Module); ok {
2034					fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs)
2035					fi.isJniLib = isJniLib
2036					filesInfo = append(filesInfo, fi)
2037					// Collect the list of stub-providing libs except:
2038					// - VNDK libs are only for vendors
2039					// - bootstrap bionic libs are treated as provided by system
2040					if c.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
2041						provideNativeLibs = append(provideNativeLibs, fi.Stem())
2042					}
2043					return true // track transitive dependencies
2044				} else {
2045					propertyName := "native_shared_libs"
2046					if isJniLib {
2047						propertyName = "jni_libs"
2048					}
2049					ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
2050				}
2051			case executableTag:
2052				if cc, ok := child.(*cc.Module); ok {
2053					filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc))
2054					return true // track transitive dependencies
2055				} else if sh, ok := child.(*sh.ShBinary); ok {
2056					filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh))
2057				} else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() {
2058					filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py))
2059				} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
2060					filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb))
2061				} else {
2062					ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
2063				}
2064			case javaLibTag:
2065				switch child.(type) {
2066				case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport:
2067					af := apexFileForJavaLibrary(ctx, child.(javaModule))
2068					if !af.Ok() {
2069						ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
2070						return false
2071					}
2072					filesInfo = append(filesInfo, af)
2073					return true // track transitive dependencies
2074				default:
2075					ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
2076				}
2077			case androidAppTag:
2078				if ap, ok := child.(*java.AndroidApp); ok {
2079					filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
2080					return true // track transitive dependencies
2081				} else if ap, ok := child.(*java.AndroidAppImport); ok {
2082					filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
2083				} else if ap, ok := child.(*java.AndroidTestHelperApp); ok {
2084					filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
2085				} else if ap, ok := child.(*java.AndroidAppSet); ok {
2086					appDir := "app"
2087					if ap.Privileged() {
2088						appDir = "priv-app"
2089					}
2090					af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(),
2091						filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
2092					af.certificate = java.PresignedCertificate
2093					filesInfo = append(filesInfo, af)
2094				} else {
2095					ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
2096				}
2097			case rroTag:
2098				if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
2099					filesInfo = append(filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
2100				} else {
2101					ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
2102				}
2103			case prebuiltTag:
2104				if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2105					filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2106				} else if prebuilt, ok := child.(java.PlatformCompatConfigIntf); ok {
2107					filesInfo = append(filesInfo, apexFileForCompatConfig(ctx, prebuilt, depName))
2108				} else {
2109					ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc and not a platform_compat_config module", depName)
2110				}
2111			case testTag:
2112				if ccTest, ok := child.(*cc.Module); ok {
2113					if ccTest.IsTestPerSrcAllTestsVariation() {
2114						// Multiple-output test module (where `test_per_src: true`).
2115						//
2116						// `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
2117						// We do not add this variation to `filesInfo`, as it has no output;
2118						// however, we do add the other variations of this module as indirect
2119						// dependencies (see below).
2120					} else {
2121						// Single-output test module (where `test_per_src: false`).
2122						af := apexFileForExecutable(ctx, ccTest)
2123						af.class = nativeTest
2124						filesInfo = append(filesInfo, af)
2125					}
2126					return true // track transitive dependencies
2127				} else {
2128					ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
2129				}
2130			case keyTag:
2131				if key, ok := child.(*apexKey); ok {
2132					a.private_key_file = key.private_key_file
2133					a.public_key_file = key.public_key_file
2134				} else {
2135					ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
2136				}
2137				return false
2138			case certificateTag:
2139				if dep, ok := child.(*java.AndroidAppCertificate); ok {
2140					a.container_certificate_file = dep.Certificate.Pem
2141					a.container_private_key_file = dep.Certificate.Key
2142				} else {
2143					ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
2144				}
2145			case android.PrebuiltDepTag:
2146				// If the prebuilt is force disabled, remember to delete the prebuilt file
2147				// that might have been installed in the previous builds
2148				if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
2149					a.prebuiltFileToDelete = prebuilt.InstallFilename()
2150				}
2151			}
2152		} else if !a.vndkApex {
2153			// indirect dependencies
2154			if am, ok := child.(android.ApexModule); ok {
2155				// We cannot use a switch statement on `depTag` here as the checked
2156				// tags used below are private (e.g. `cc.sharedDepTag`).
2157				if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
2158					if cc, ok := child.(*cc.Module); ok {
2159						if android.InList(cc.Name(), providedNativeSharedLibs) {
2160							// If we're using a shared library which is provided from other APEX,
2161							// don't include it in this APEX
2162							return false
2163						}
2164						if cc.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && cc.IsVndk() {
2165							requireNativeLibs = append(requireNativeLibs, ":vndk")
2166							return false
2167						}
2168						af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
2169						af.transitiveDep = true
2170						if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
2171							// If the dependency is a stubs lib, don't include it in this APEX,
2172							// but make sure that the lib is installed on the device.
2173							// In case no APEX is having the lib, the lib is installed to the system
2174							// partition.
2175							//
2176							// Always include if we are a host-apex however since those won't have any
2177							// system libraries.
2178							if !android.DirectlyInAnyApex(ctx, depName) {
2179								// we need a module name for Make
2180								name := cc.BaseModuleName() + cc.Properties.SubName
2181								if proptools.Bool(a.properties.Use_vendor) {
2182									// we don't use subName(.vendor) for a "use_vendor: true" apex
2183									// which is supposed to be installed in /system
2184									name = cc.BaseModuleName()
2185								}
2186								if !android.InList(name, a.requiredDeps) {
2187									a.requiredDeps = append(a.requiredDeps, name)
2188								}
2189							}
2190							requireNativeLibs = append(requireNativeLibs, af.Stem())
2191							// Don't track further
2192							return false
2193						}
2194						filesInfo = append(filesInfo, af)
2195						return true // track transitive dependencies
2196					}
2197				} else if cc.IsTestPerSrcDepTag(depTag) {
2198					if cc, ok := child.(*cc.Module); ok {
2199						af := apexFileForExecutable(ctx, cc)
2200						// Handle modules created as `test_per_src` variations of a single test module:
2201						// use the name of the generated test binary (`fileToCopy`) instead of the name
2202						// of the original test module (`depName`, shared by all `test_per_src`
2203						// variations of that module).
2204						af.androidMkModuleName = filepath.Base(af.builtFile.String())
2205						// these are not considered transitive dep
2206						af.transitiveDep = false
2207						filesInfo = append(filesInfo, af)
2208						return true // track transitive dependencies
2209					}
2210				} else if java.IsJniDepTag(depTag) {
2211					// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
2212					return false
2213				} else if java.IsXmlPermissionsFileDepTag(depTag) {
2214					if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
2215						filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
2216					}
2217				} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
2218					ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
2219				}
2220			}
2221		}
2222		return false
2223	})
2224
2225	// Specific to the ART apex: dexpreopt artifacts for libcore Java libraries.
2226	// Build rules are generated by the dexpreopt singleton, and here we access build artifacts
2227	// via the global boot image config.
2228	if a.artApex {
2229		for arch, files := range java.DexpreoptedArtApexJars(ctx) {
2230			dirInApex := filepath.Join("javalib", arch.String())
2231			for _, f := range files {
2232				localModule := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
2233				af := newApexFile(ctx, f, localModule, dirInApex, etc, nil)
2234				filesInfo = append(filesInfo, af)
2235			}
2236		}
2237	}
2238
2239	if a.private_key_file == nil {
2240		ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.properties.Key))
2241		return
2242	}
2243
2244	// remove duplicates in filesInfo
2245	removeDup := func(filesInfo []apexFile) []apexFile {
2246		encountered := make(map[string]apexFile)
2247		for _, f := range filesInfo {
2248			dest := filepath.Join(f.installDir, f.builtFile.Base())
2249			if e, ok := encountered[dest]; !ok {
2250				encountered[dest] = f
2251			} else {
2252				// If a module is directly included and also transitively depended on
2253				// consider it as directly included.
2254				e.transitiveDep = e.transitiveDep && f.transitiveDep
2255				encountered[dest] = e
2256			}
2257		}
2258		var result []apexFile
2259		for _, v := range encountered {
2260			result = append(result, v)
2261		}
2262		return result
2263	}
2264	filesInfo = removeDup(filesInfo)
2265
2266	// to have consistent build rules
2267	sort.Slice(filesInfo, func(i, j int) bool {
2268		return filesInfo[i].builtFile.String() < filesInfo[j].builtFile.String()
2269	})
2270
2271	a.installDir = android.PathForModuleInstall(ctx, "apex")
2272	a.filesInfo = filesInfo
2273
2274	// Optimization. If we are building bundled APEX, for the files that are gathered due to the
2275	// transitive dependencies, don't place them inside the APEX, but place a symlink pointing
2276	// the same library in the system partition, thus effectively sharing the same libraries
2277	// across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
2278	// in the APEX.
2279	a.linkToSystemLib = !ctx.Config().UnbundledBuild() &&
2280		a.installable() &&
2281		!proptools.Bool(a.properties.Use_vendor)
2282
2283	// APEXes targeting other than system/system_ext partitions use vendor/product variants.
2284	// So we can't link them to /system/lib libs which are core variants.
2285	if a.SocSpecific() || a.DeviceSpecific() ||
2286		(a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
2287		a.linkToSystemLib = false
2288	}
2289
2290	// We don't need the optimization for updatable APEXes, as it might give false signal
2291	// to the system health when the APEXes are still bundled (b/149805758)
2292	if a.Updatable() && a.properties.ApexType == imageApex {
2293		a.linkToSystemLib = false
2294	}
2295
2296	// We also don't want the optimization for host APEXes, because it doesn't make sense.
2297	if ctx.Host() {
2298		a.linkToSystemLib = false
2299	}
2300
2301	// prepare apex_manifest.json
2302	a.buildManifest(ctx, provideNativeLibs, requireNativeLibs)
2303
2304	a.buildFileContexts(ctx)
2305
2306	a.setCertificateAndPrivateKey(ctx)
2307	if a.properties.ApexType == flattenedApex {
2308		a.buildFlattenedApex(ctx)
2309	} else {
2310		a.buildUnflattenedApex(ctx)
2311	}
2312
2313	a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
2314
2315	a.buildApexDependencyInfo(ctx)
2316
2317	a.buildLintReports(ctx)
2318}
2319
2320// Enforce that Java deps of the apex are using stable SDKs to compile
2321func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
2322	// Visit direct deps only. As long as we guarantee top-level deps are using
2323	// stable SDKs, java's checkLinkType guarantees correct usage for transitive deps
2324	ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
2325		tag := ctx.OtherModuleDependencyTag(module)
2326		switch tag {
2327		case javaLibTag, androidAppTag:
2328			if m, ok := module.(interface{ CheckStableSdkVersion() error }); ok {
2329				if err := m.CheckStableSdkVersion(); err != nil {
2330					ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
2331				}
2332			}
2333		}
2334	})
2335}
2336
2337func baselineApexAvailable(apex, moduleName string) bool {
2338	key := apex
2339	moduleName = normalizeModuleName(moduleName)
2340
2341	if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
2342		return true
2343	}
2344
2345	key = android.AvailableToAnyApex
2346	if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
2347		return true
2348	}
2349
2350	return false
2351}
2352
2353func normalizeModuleName(moduleName string) string {
2354	// Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
2355	// system. Trim the prefix for the check since they are confusing
2356	moduleName = strings.TrimPrefix(moduleName, "prebuilt_")
2357	if strings.HasPrefix(moduleName, "libclang_rt.") {
2358		// This module has many arch variants that depend on the product being built.
2359		// We don't want to list them all
2360		moduleName = "libclang_rt"
2361	}
2362	if strings.HasPrefix(moduleName, "androidx.") {
2363		// TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
2364		moduleName = "androidx"
2365	}
2366	return moduleName
2367}
2368
2369func newApexBundle() *apexBundle {
2370	module := &apexBundle{}
2371	module.AddProperties(&module.properties)
2372	module.AddProperties(&module.targetProperties)
2373	module.AddProperties(&module.overridableProperties)
2374	android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
2375	android.InitDefaultableModule(module)
2376	android.InitSdkAwareModule(module)
2377	android.InitOverridableModule(module, &module.overridableProperties.Overrides)
2378	return module
2379}
2380
2381func ApexBundleFactory(testApex bool, artApex bool) android.Module {
2382	bundle := newApexBundle()
2383	bundle.testApex = testApex
2384	bundle.artApex = artApex
2385	return bundle
2386}
2387
2388// apex_test is an APEX for testing. The difference from the ordinary apex module type is that
2389// certain compatibility checks such as apex_available are not done for apex_test.
2390func testApexBundleFactory() android.Module {
2391	bundle := newApexBundle()
2392	bundle.testApex = true
2393	return bundle
2394}
2395
2396// apex packages other modules into an APEX file which is a packaging format for system-level
2397// components like binaries, shared libraries, etc.
2398func BundleFactory() android.Module {
2399	return newApexBundle()
2400}
2401
2402//
2403// Defaults
2404//
2405type Defaults struct {
2406	android.ModuleBase
2407	android.DefaultsModuleBase
2408}
2409
2410func defaultsFactory() android.Module {
2411	return DefaultsFactory()
2412}
2413
2414func DefaultsFactory(props ...interface{}) android.Module {
2415	module := &Defaults{}
2416
2417	module.AddProperties(props...)
2418	module.AddProperties(
2419		&apexBundleProperties{},
2420		&apexTargetBundleProperties{},
2421		&overridableProperties{},
2422	)
2423
2424	android.InitDefaultsModule(module)
2425	return module
2426}
2427
2428//
2429// OverrideApex
2430//
2431type OverrideApex struct {
2432	android.ModuleBase
2433	android.OverrideModuleBase
2434}
2435
2436func (o *OverrideApex) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2437	// All the overrides happen in the base module.
2438}
2439
2440// override_apex is used to create an apex module based on another apex module
2441// by overriding some of its properties.
2442func overrideApexFactory() android.Module {
2443	m := &OverrideApex{}
2444	m.AddProperties(&overridableProperties{})
2445
2446	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
2447	android.InitOverrideModule(m)
2448	return m
2449}
2450