xref: /aosp_15_r20/build/soong/java/app.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17// This file contains the module implementations for android_app, android_test, and some more
18// related module types, including their override variants.
19
20import (
21	"fmt"
22	"path/filepath"
23	"strings"
24
25	"github.com/google/blueprint"
26	"github.com/google/blueprint/depset"
27	"github.com/google/blueprint/proptools"
28
29	"android/soong/android"
30	"android/soong/cc"
31	"android/soong/dexpreopt"
32	"android/soong/tradefed"
33)
34
35func init() {
36	RegisterAppBuildComponents(android.InitRegistrationContext)
37	pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
38}
39
40var (
41	modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
42		blueprint.RuleParams{
43			Command:     "${ModifyAllowlistCmd} $in $packageName $out",
44			CommandDeps: []string{"${ModifyAllowlistCmd}"},
45		}, "packageName")
46)
47
48type FlagsPackages struct {
49	// Paths to the aconfig dump output text files that are consumed by aapt2
50	AconfigTextFiles android.Paths
51}
52
53var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
54
55func RegisterAppBuildComponents(ctx android.RegistrationContext) {
56	ctx.RegisterModuleType("android_app", AndroidAppFactory)
57	ctx.RegisterModuleType("android_test", AndroidTestFactory)
58	ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
59	ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
60	ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
61	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
62}
63
64type AppInfo struct {
65	// Updatable is set to the value of the updatable property
66	Updatable bool
67
68	// TestHelperApp is true if the module is a android_test_helper_app
69	TestHelperApp bool
70
71	// EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
72	EmbeddedJNILibs android.Paths
73}
74
75var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
76
77// AndroidManifest.xml merging
78// package splits
79
80type appProperties struct {
81	// Names of extra android_app_certificate modules to sign the apk with in the form ":module".
82	Additional_certificates []string
83
84	// If set, create package-export.apk, which other packages can
85	// use to get PRODUCT-agnostic resource data like IDs and type definitions.
86	Export_package_resources *bool
87
88	// Specifies that this app should be installed to the priv-app directory,
89	// where the system will grant it additional privileges not available to
90	// normal apps.
91	Privileged *bool
92
93	// list of resource labels to generate individual resource packages
94	Package_splits []string
95
96	// list of native libraries that will be provided in or alongside the resulting jar
97	Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
98
99	// if true, use JNI libraries that link against platform APIs even if this module sets
100	// sdk_version.
101	Jni_uses_platform_apis *bool
102
103	// if true, use JNI libraries that link against SDK APIs even if this module does not set
104	// sdk_version.
105	Jni_uses_sdk_apis *bool
106
107	// STL library to use for JNI libraries.
108	Stl *string `android:"arch_variant"`
109
110	// Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
111	// flag so that they are used from inside the APK at runtime.  Defaults to true for android_test modules unless
112	// sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
113	// android_app modules that are embedded to APEXes, defaults to false for other module types where the native
114	// libraries are generally preinstalled outside the APK.
115	Use_embedded_native_libs *bool
116
117	// Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
118	// they are used from inside the APK at runtime.
119	Use_embedded_dex *bool
120
121	// Forces native libraries to always be packaged into the APK,
122	// Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
123	// True for android_test* modules.
124	AlwaysPackageNativeLibs bool `blueprint:"mutated"`
125
126	// If set, find and merge all NOTICE files that this module and its dependencies have and store
127	// it in the APK as an asset.
128	Embed_notices *bool
129
130	// cc.Coverage related properties
131	PreventInstall    bool `blueprint:"mutated"`
132	IsCoverageVariant bool `blueprint:"mutated"`
133
134	// It can be set to test the behaviour of default target sdk version.
135	// Only required when updatable: false. It is an error if updatable: true and this is false.
136	Enforce_default_target_sdk_version *bool
137
138	// If set, the targetSdkVersion for the target is set to the latest default API level.
139	// This would be by default false, unless updatable: true or
140	// enforce_default_target_sdk_version: true in which case this defaults to true.
141	EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
142
143	// Whether this app is considered mainline updatable or not. When set to true, this will enforce
144	// additional rules to make sure an app can safely be updated. Default is false.
145	// Prefer using other specific properties if build behaviour must be changed; avoid using this
146	// flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
147	Updatable *bool
148
149	// Specifies the file that contains the allowlist for this app.
150	Privapp_allowlist *string `android:"path"`
151
152	// If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
153	// and install the RRO package to /product partition, instead of passing --product argument
154	// to aapt2. Default is false.
155	// Setting this will make this APK identical to all targets, regardless of
156	// PRODUCT_CHARACTERISTICS.
157	Generate_product_characteristics_rro *bool
158
159	ProductCharacteristicsRROPackageName        *string `blueprint:"mutated"`
160	ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
161}
162
163// android_app properties that can be overridden by override_android_app
164type overridableAppProperties struct {
165	// The name of a certificate in the default certificate directory, blank to use the default product certificate,
166	// or an android_app_certificate module name in the form ":module".
167	Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
168
169	// Name of the signing certificate lineage file or filegroup module.
170	Lineage *string `android:"path"`
171
172	// For overriding the --rotation-min-sdk-version property of apksig
173	RotationMinSdkVersion *string
174
175	// the package name of this app. The package name in the manifest file is used if one was not given.
176	Package_name proptools.Configurable[string]
177
178	// the logging parent of this app.
179	Logging_parent *string
180
181	// Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
182	Rename_resources_package *bool
183
184	// Names of modules to be overridden. Listed modules can only be other binaries
185	// (in Make or Soong).
186	// This does not completely prevent installation of the overridden binaries, but if both
187	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
188	// from PRODUCT_PACKAGES.
189	Overrides []string
190}
191
192type AndroidApp struct {
193	Library
194	aapt
195	android.OverridableModuleBase
196
197	certificate Certificate
198
199	appProperties appProperties
200
201	overridableAppProperties overridableAppProperties
202
203	jniLibs                  []jniLib
204	installPathForJNISymbols android.Path
205	embeddedJniLibs          bool
206	jniCoverageOutputs       android.Paths
207
208	bundleFile android.Path
209
210	// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
211	installApkName string
212
213	installDir android.InstallPath
214
215	onDeviceDir string
216
217	additionalAaptFlags []string
218
219	overriddenManifestPackageName string
220
221	android.ApexBundleDepsInfo
222
223	javaApiUsedByOutputFile android.ModuleOutPath
224
225	privAppAllowlist android.OptionalPath
226
227	requiredModuleNames []string
228}
229
230func (a *AndroidApp) IsInstallable() bool {
231	return Bool(a.properties.Installable)
232}
233
234func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
235	return a.aapt.resourcesNodesDepSet
236}
237
238func (a *AndroidApp) OutputFile() android.Path {
239	return a.outputFile
240}
241
242func (a *AndroidApp) Certificate() Certificate {
243	return a.certificate
244}
245
246func (a *AndroidApp) JniCoverageOutputs() android.Paths {
247	return a.jniCoverageOutputs
248}
249
250func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
251	return a.privAppAllowlist
252}
253
254var _ AndroidLibraryDependency = (*AndroidApp)(nil)
255
256type Certificate struct {
257	Pem, Key  android.Path
258	presigned bool
259}
260
261var PresignedCertificate = Certificate{presigned: true}
262
263func (c Certificate) AndroidMkString() string {
264	if c.presigned {
265		return "PRESIGNED"
266	} else {
267		return c.Pem.String()
268	}
269}
270
271func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
272	if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
273		ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
274	}
275
276	sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
277	a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
278	a.Module.deps(ctx)
279	if sdkDep.hasFrameworkLibs() {
280		a.aapt.deps(ctx, sdkDep)
281	}
282
283	usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
284
285	if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
286		ctx.PropertyErrorf("jni_uses_sdk_apis",
287			"can only be set for modules that do not set sdk_version")
288	} else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
289		ctx.PropertyErrorf("jni_uses_platform_apis",
290			"can only be set for modules that set sdk_version")
291	}
292
293	for _, jniTarget := range ctx.MultiTargets() {
294		variation := append(jniTarget.Variations(),
295			blueprint.Variation{Mutator: "link", Variation: "shared"})
296
297		// Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
298		// Many factors are considered here.
299		// 1. Basically, the selection follows whether the app has sdk_version set or not.
300		jniUsesSdkVariant := usesSDK
301		// 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
302		if Bool(a.appProperties.Jni_uses_sdk_apis) {
303			jniUsesSdkVariant = true
304		}
305		if Bool(a.appProperties.Jni_uses_platform_apis) {
306			jniUsesSdkVariant = false
307		}
308		// 3. Then the use of SDK variant is again prohibited for the following cases:
309		// 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
310		// partition (not only the app) is considered unbudled, there's no need to use the
311		// SDK variant.
312		// 3.2. the app doesn't support embedding the JNI libs
313		if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
314			jniUsesSdkVariant = false
315		}
316		if jniUsesSdkVariant {
317			variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
318		}
319
320		// Use the installable dep tag when the JNIs are not embedded
321		var tag dependencyTag
322		if a.shouldEmbedJnis(ctx) {
323			tag = jniLibTag
324		} else {
325			tag = jniInstallTag
326		}
327		ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
328	}
329	for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
330		ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
331	}
332}
333
334func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
335	cert := android.SrcIsModule(a.getCertString(ctx))
336	if cert != "" {
337		ctx.AddDependency(ctx.Module(), certificateTag, cert)
338	}
339
340	if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
341		// There are a few uids that are explicitly considered privileged regardless of their
342		// app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
343		// but for now, allow it not to be in priv-app.
344		privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
345		if !privilegedBecauseOfUid {
346			ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
347		}
348	}
349
350	for _, cert := range a.appProperties.Additional_certificates {
351		cert = android.SrcIsModule(cert)
352		if cert != "" {
353			ctx.AddDependency(ctx.Module(), certificateTag, cert)
354		} else {
355			ctx.PropertyErrorf("additional_certificates",
356				`must be names of android_app_certificate modules in the form ":module"`)
357		}
358	}
359}
360
361// TODO(b/156476221): Remove this allowlist
362var (
363	missingMinSdkVersionMtsAllowlist = []string{
364		"CellBroadcastReceiverGoogleUnitTests",
365		"CellBroadcastReceiverUnitTests",
366		"CtsBatterySavingTestCases",
367		"CtsDeviceAndProfileOwnerApp23",
368		"CtsDeviceAndProfileOwnerApp30",
369		"CtsIntentSenderApp",
370		"CtsJobSchedulerTestCases",
371		"CtsMimeMapTestCases",
372		"CtsTareTestCases",
373		"LibStatsPullTests",
374		"MediaProviderClientTests",
375		"TeleServiceTests",
376		"TestExternalImsServiceApp",
377		"TestSmsRetrieverApp",
378		"TetheringPrivilegedTests",
379	}
380)
381
382func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
383	if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
384		ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
385	}
386}
387
388func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
389	checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
390	applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
391	if applicationId != nil {
392		packageName := a.overridableAppProperties.Package_name.Get(ctx)
393		if packageName.IsPresent() {
394			ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
395		}
396		a.aapt.manifestValues.applicationId = *applicationId
397	}
398	a.generateAndroidBuildActions(ctx)
399	android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
400		TestOnly: true,
401	})
402	android.SetProvider(ctx, AppInfoProvider, &AppInfo{
403		Updatable:     Bool(a.appProperties.Updatable),
404		TestHelperApp: true,
405	})
406}
407
408func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
409	a.checkAppSdkVersions(ctx)
410	a.checkEmbedJnis(ctx)
411	a.generateAndroidBuildActions(ctx)
412	a.generateJavaUsedByApex(ctx)
413
414	var embeddedJniLibs []android.Path
415
416	if a.embeddedJniLibs {
417		for _, jni := range a.jniLibs {
418			embeddedJniLibs = append(embeddedJniLibs, jni.path)
419		}
420	}
421	android.SetProvider(ctx, AppInfoProvider, &AppInfo{
422		Updatable:       Bool(a.appProperties.Updatable),
423		TestHelperApp:   false,
424		EmbeddedJNILibs: embeddedJniLibs,
425	})
426
427	a.requiredModuleNames = a.getRequiredModuleNames(ctx)
428}
429
430func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
431	var required []string
432	if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
433		required = []string{a.productCharacteristicsRROPackageName()}
434	}
435	// Install the vendor overlay variant if this app is installed.
436	if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
437		required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
438	}
439	// Install the product overlay variant if this app is installed.
440	if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
441		required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
442	}
443	return required
444}
445
446func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
447	if a.Updatable() {
448		if !a.SdkVersion(ctx).Stable() {
449			ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
450		}
451		if String(a.overridableProperties.Min_sdk_version) == "" {
452			ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
453		}
454
455		if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
456			a.checkJniLibsSdkVersion(ctx, minSdkVersion)
457			android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
458		} else {
459			ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
460		}
461
462		if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
463			ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
464		}
465		// TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
466		if a.deviceProperties.Target_sdk_version == nil {
467			a.SetEnforceDefaultTargetSdkVersion(true)
468		}
469	}
470
471	a.checkPlatformAPI(ctx)
472	a.checkSdkVersions(ctx)
473}
474
475// Ensures that use_embedded_native_libs are set for apk-in-apex
476func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
477	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
478	apkInApex := !apexInfo.IsForPlatform()
479	hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
480
481	if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
482		ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
483	}
484}
485
486// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
487// This check is enforced for "updatable" APKs (including APK-in-APEX).
488func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
489	// It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
490	ctx.VisitDirectDeps(func(m android.Module) {
491		if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
492			return
493		}
494		dep, _ := m.(*cc.Module)
495		// The domain of cc.sdk_version is "current" and <number>
496		// We can rely on android.SdkSpec to convert it to <number> so that "current" is
497		// handled properly regardless of sdk finalization.
498		jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
499		if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
500			ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
501				dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
502			return
503		}
504
505	})
506}
507
508// Returns true if the native libraries should be stored in the APK uncompressed and the
509// extractNativeLibs application flag should be set to false in the manifest.
510func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
511	minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
512	if err != nil {
513		ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
514	}
515
516	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
517	return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
518		!apexInfo.IsForPlatform()
519}
520
521// Returns whether this module should have the dex file stored uncompressed in the APK.
522func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
523	if Bool(a.appProperties.Use_embedded_dex) {
524		return true
525	}
526
527	// Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
528	// be preinstalled as prebuilts).
529	if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
530		return true
531	}
532
533	if ctx.Config().UnbundledBuild() {
534		return false
535	}
536
537	return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
538}
539
540func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
541	return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
542		Bool(a.appProperties.Updatable) ||
543		a.appProperties.AlwaysPackageNativeLibs
544}
545
546func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
547	aaptFlags := []string{"--rename-manifest-package " + packageName}
548	if renameResourcesPackage {
549		// Required to rename the package name in the resources table.
550		aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
551	}
552	return aaptFlags
553}
554
555func (a *AndroidApp) OverriddenManifestPackageName() string {
556	return a.overriddenManifestPackageName
557}
558
559func (a *AndroidApp) renameResourcesPackage() bool {
560	return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
561}
562
563func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
564	ctx.VisitDirectDeps(func(dep android.Module) {
565		tag := ctx.OtherModuleDependencyTag(dep)
566		switch tag {
567		case staticLibTag:
568			if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
569				aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
570			}
571
572		case aconfigDeclarationTag:
573			if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
574				aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
575			} else {
576				ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
577					"flags_packages property, but %s is not aconfig_declarations module type",
578					dep.Name(),
579				)
580			}
581		}
582	})
583
584	return android.FirstUniquePaths(aconfigTextFilePaths)
585}
586
587func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
588	usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
589	if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
590		usePlatformAPI = true
591	}
592	a.aapt.usesNonSdkApis = usePlatformAPI
593
594	// Ask manifest_fixer to add or update the application element indicating this app has no code.
595	a.aapt.hasNoCode = !a.hasCode(ctx)
596
597	aaptLinkFlags := []string{}
598
599	// Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
600	autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
601	hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
602	characteristics := ctx.Config().ProductAAPTCharacteristics()
603	if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
604		aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
605	}
606
607	if !Bool(a.aaptProperties.Aapt_include_all_resources) {
608		// Product AAPT config
609		for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
610			aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
611		}
612
613		// Product AAPT preferred config
614		if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
615			aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
616		}
617	}
618
619	manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
620	packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
621	if overridden || packageNameProp.IsPresent() {
622		// The product override variable has a priority over the package_name property.
623		if !overridden {
624			manifestPackageName = packageNameProp.Get()
625		}
626		aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
627		a.overriddenManifestPackageName = manifestPackageName
628	}
629
630	aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
631
632	a.aapt.splitNames = a.appProperties.Package_splits
633	a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
634	if a.Updatable() {
635		if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
636			a.aapt.defaultManifestVersion = override
637		} else {
638			a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
639		}
640	}
641
642	// Use non final ids if we are doing optimized shrinking and are using R8.
643	nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
644
645	aconfigTextFilePaths := getAconfigFilePaths(ctx)
646
647	a.aapt.buildActions(ctx,
648		aaptBuildActionOptions{
649			sdkContext:                     android.SdkContext(a),
650			classLoaderContexts:            a.classLoaderContexts,
651			excludedLibs:                   a.usesLibraryProperties.Exclude_uses_libs,
652			enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
653			forceNonFinalResourceIDs:       nonFinalIds,
654			extraLinkFlags:                 aaptLinkFlags,
655			aconfigTextFiles:               aconfigTextFilePaths,
656			usesLibrary:                    &a.usesLibrary,
657		},
658	)
659
660	// apps manifests are handled by aapt, don't let Module see them
661	a.properties.Manifest = nil
662
663	android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
664		AconfigTextFiles: aconfigTextFilePaths,
665	})
666}
667
668func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
669	var staticLibProguardFlagFiles android.Paths
670	ctx.VisitDirectDeps(func(m android.Module) {
671		depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
672		staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
673		if ctx.OtherModuleDependencyTag(m) == staticLibTag {
674			staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
675		}
676	})
677
678	staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
679
680	a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
681	if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
682		// When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
683		// live for code references and (transitively) mark these as live.
684		// In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
685		// dead code alive)
686		a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
687	}
688}
689
690func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
691	var installDir string
692	if ctx.ModuleName() == "framework-res" {
693		// framework-res.apk is installed as system/framework/framework-res.apk
694		installDir = "framework"
695	} else if a.Privileged() {
696		installDir = filepath.Join("priv-app", a.installApkName)
697	} else {
698		installDir = filepath.Join("app", a.installApkName)
699	}
700
701	return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
702}
703
704func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
705	a.dexpreopter.installPath = a.installPath(ctx)
706	a.dexpreopter.isApp = true
707	if a.dexProperties.Uncompress_dex == nil {
708		// If the value was not force-set by the user, use reasonable default based on the module.
709		a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
710	}
711	a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
712	a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
713	a.dexpreopter.classLoaderContexts = a.classLoaderContexts
714	a.dexpreopter.manifestFile = a.mergedManifestFile
715	a.dexpreopter.preventInstall = a.appProperties.PreventInstall
716
717	var packageResources = a.exportPackage
718
719	if ctx.ModuleName() != "framework-res" {
720		if a.dexProperties.resourceShrinkingEnabled(ctx) {
721			protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
722			aapt2Convert(ctx, protoFile, packageResources, "proto")
723			a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
724		}
725
726		var extraSrcJars android.Paths
727		var extraClasspathJars android.Paths
728		var extraCombinedJars android.Paths
729		if a.useResourceProcessorBusyBox(ctx) {
730			// When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
731			// created R.class files that provide IDs for resources in busybox/R.jar.  Pass that file in the
732			// classpath when compiling everything else, and add it to the final classes jar.
733			extraClasspathJars = android.Paths{a.aapt.rJar}
734			extraCombinedJars = android.Paths{a.aapt.rJar}
735		} else {
736			// When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
737			// R.java files for the app's package and the packages from all transitive static android_library
738			// dependencies.  Compile the srcjar alongside the rest of the sources.
739			extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
740		}
741
742		a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
743		if a.dexProperties.resourceShrinkingEnabled(ctx) {
744			binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
745			aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
746			packageResources = binaryResources
747		}
748	}
749
750	return a.dexJarFile.PathOrNil(), packageResources
751}
752
753func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
754	var jniJarFile android.WritablePath
755	if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
756		a.jniLibs = jniLibs
757		if a.shouldEmbedJnis(ctx) {
758			jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
759			a.installPathForJNISymbols = a.installPath(ctx)
760			TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
761			for _, jni := range jniLibs {
762				if jni.coverageFile.Valid() {
763					// Only collect coverage for the first target arch if this is a multilib target.
764					// TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
765					// data file path collisions since the current coverage file path format doesn't contain
766					// arch-related strings. This is fine for now though; the code coverage team doesn't use
767					// multi-arch targets such as test_suite_* for coverage collections yet.
768					//
769					// Work with the team to come up with a new format that handles multilib modules properly
770					// and change this.
771					if len(ctx.Config().Targets[android.Android]) == 1 ||
772						ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
773						a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
774					}
775				}
776			}
777			a.embeddedJniLibs = true
778		}
779	}
780	return jniJarFile
781}
782
783func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
784	var jniSymbols android.RuleBuilderInstalls
785	for _, jniLib := range a.jniLibs {
786		if jniLib.unstrippedFile != nil {
787			jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
788				From: jniLib.unstrippedFile,
789				To:   filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
790			})
791		}
792	}
793	return jniSymbols
794}
795
796// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
797// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
798func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
799	ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
800	if android.SrcIsModule(certPropValue) == "" {
801		var mainCert Certificate
802		if certPropValue != "" {
803			defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
804			mainCert = Certificate{
805				Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
806				Key: defaultDir.Join(ctx, certPropValue+".pk8"),
807			}
808		} else {
809			pem, key := ctx.Config().DefaultAppCertificate(ctx)
810			mainCert = Certificate{
811				Pem: pem,
812				Key: key,
813			}
814		}
815		certificates = append([]Certificate{mainCert}, certificates...)
816	}
817
818	if len(certificates) > 0 {
819		mainCertificate = certificates[0]
820	} else {
821		// This can be reached with an empty certificate list if AllowMissingDependencies is set
822		// and the certificate property for this module is a module reference to a missing module.
823		if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
824			panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
825		}
826		// Set a certificate to avoid panics later when accessing it.
827		mainCertificate = Certificate{
828			Key: android.PathForModuleOut(ctx, "missing.pk8"),
829			Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
830		}
831	}
832
833	if !m.Platform() {
834		certPath := mainCertificate.Pem.String()
835		systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
836		if strings.HasPrefix(certPath, systemCertPath) {
837			enforceSystemCert := ctx.Config().EnforceSystemCertificate()
838			allowed := ctx.Config().EnforceSystemCertificateAllowList()
839
840			if enforceSystemCert && !inList(m.Name(), allowed) {
841				ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
842			}
843		}
844	}
845
846	return mainCertificate, certificates
847}
848
849func (a *AndroidApp) InstallApkName() string {
850	return a.installApkName
851}
852
853func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
854	if a.appProperties.Privapp_allowlist == nil {
855		return nil
856	}
857
858	isOverrideApp := a.GetOverriddenBy() != ""
859	if !isOverrideApp {
860		// if this is not an override, we don't need to rewrite the existing privapp allowlist
861		return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
862	}
863
864	packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
865	if packageNameProp.IsEmpty() {
866		ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
867	}
868
869	packageName := packageNameProp.Get()
870	fileName := "privapp_allowlist_" + packageName + ".xml"
871	outPath := android.PathForModuleOut(ctx, fileName)
872	ctx.Build(pctx, android.BuildParams{
873		Rule:   modifyAllowlist,
874		Input:  android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
875		Output: outPath,
876		Args: map[string]string{
877			"packageName": packageName,
878		},
879	})
880	return outPath
881}
882
883func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
884	var apkDeps android.Paths
885
886	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
887	if !apexInfo.IsForPlatform() {
888		a.hideApexVariantFromMake = true
889	}
890
891	a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
892	a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
893
894	// Unlike installApkName, a.stem should respect base module name for override_android_app.
895	// Therefore, use ctx.ModuleName() instead of a.Name().
896	a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
897
898	// Check if the install APK name needs to be overridden.
899	// Both android_app and override_android_app module are expected to possess
900	// its module bound apk path. However, override_android_app inherits ctx.ModuleName()
901	// from the base module. Therefore, use a.Name() which represents
902	// the module name for both android_app and override_android_app.
903	a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
904		proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
905
906	if ctx.ModuleName() == "framework-res" {
907		// framework-res.apk is installed as system/framework/framework-res.apk
908		a.installDir = android.PathForModuleInstall(ctx, "framework")
909	} else if a.Privileged() {
910		a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
911	} else if ctx.InstallInTestcases() {
912		a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
913	} else {
914		a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
915	}
916	a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
917
918	a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
919	if a.usesLibrary.shouldDisableDexpreopt {
920		a.dexpreopter.disableDexpreopt()
921	}
922
923	var noticeAssetPath android.WritablePath
924	if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
925		// The rule to create the notice file can't be generated yet, as the final output path
926		// for the apk isn't known yet.  Add the path where the notice file will be generated to the
927		// aapt rules now before calling aaptBuildActions, the rule to create the notice file will
928		// be generated later.
929		noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
930		a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
931	}
932
933	// For apps targeting latest target_sdk_version
934	if Bool(a.appProperties.Enforce_default_target_sdk_version) {
935		a.SetEnforceDefaultTargetSdkVersion(true)
936	}
937
938	// Process all building blocks, from AAPT to certificates.
939	a.aaptBuildActions(ctx)
940	// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
941	a.usesLibrary.freezeEnforceUsesLibraries(ctx)
942
943	// Check that the <uses-library> list is coherent with the manifest.
944	if a.usesLibrary.enforceUsesLibraries(ctx) {
945		manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
946			ctx, a.mergedManifestFile, &a.classLoaderContexts)
947		apkDeps = append(apkDeps, manifestCheckFile)
948	}
949
950	a.proguardBuildActions(ctx)
951
952	a.linter.mergedManifest = a.aapt.mergedManifestFile
953	a.linter.manifest = a.aapt.manifestPath
954	a.linter.resources = a.aapt.resourceFiles
955	a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
956
957	dexJarFile, packageResources := a.dexBuildActions(ctx)
958
959	// No need to check the SDK version of the JNI deps unless we embed them
960	checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
961	jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
962	jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
963
964	if ctx.Failed() {
965		return
966	}
967
968	a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
969
970	// Build a final signed app package.
971	packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
972	v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
973	var v4SignatureFile android.WritablePath = nil
974	if v4SigningRequested {
975		v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
976	}
977	var lineageFile android.Path
978	if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
979		lineageFile = android.PathForModuleSrc(ctx, lineage)
980	}
981	rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
982
983	CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
984	a.outputFile = packageFile
985	if v4SigningRequested {
986		a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
987	}
988
989	if a.aapt.noticeFile.Valid() {
990		// Generating the notice file rule has to be here after a.outputFile is known.
991		noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
992		android.BuildNoticeHtmlOutputFromLicenseMetadata(
993			ctx, noticeFile, "", "",
994			[]string{
995				a.installDir.String() + "/",
996				android.PathForModuleInstall(ctx).String() + "/",
997				a.outputFile.String(),
998			})
999		builder := android.NewRuleBuilder(pctx, ctx)
1000		builder.Command().Text("cp").
1001			Input(noticeFile).
1002			Output(noticeAssetPath)
1003		builder.Build("notice_dir", "Building notice dir")
1004	}
1005
1006	for _, split := range a.aapt.splits {
1007		// Sign the split APKs
1008		packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
1009		if v4SigningRequested {
1010			v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
1011		}
1012		CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
1013		a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
1014		if v4SigningRequested {
1015			a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1016		}
1017	}
1018
1019	// Build an app bundle.
1020	bundleFile := android.PathForModuleOut(ctx, "base.zip")
1021	BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1022	a.bundleFile = bundleFile
1023
1024	allowlist := a.createPrivappAllowlist(ctx)
1025	if allowlist != nil {
1026		a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1027	}
1028
1029	// Install the app package.
1030	shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1031	if shouldInstallAppPackage {
1032		if a.privAppAllowlist.Valid() {
1033			allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1034			allowlistInstallFilename := a.installApkName + ".xml"
1035			ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
1036		}
1037
1038		var extraInstalledPaths android.InstallPaths
1039		for _, extra := range a.extraOutputFiles {
1040			installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1041			extraInstalledPaths = append(extraInstalledPaths, installed)
1042		}
1043		// If we don't embed jni libs, make sure that those are installed along with the
1044		// app, and also place symlinks to the installed paths under the lib/<arch>
1045		// directory of the app installation directory. ex:
1046		// /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1047		if !a.embeddedJniLibs {
1048			for _, jniLib := range jniLibs {
1049				archStr := jniLib.target.Arch.ArchType.String()
1050				symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1051				for _, installedLib := range jniLib.installPaths {
1052					// install the symlink itself
1053					symlinkName := installedLib.Base()
1054					symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1055					ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1056				}
1057			}
1058		}
1059		ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
1060	}
1061
1062	ctx.CheckbuildFile(a.outputFile)
1063
1064	a.buildAppDependencyInfo(ctx)
1065
1066	providePrebuiltInfo(ctx,
1067		prebuiltInfoProps{
1068			baseModuleName: a.BaseModuleName(),
1069			isPrebuilt:     false,
1070		},
1071	)
1072
1073	a.setOutputFiles(ctx)
1074}
1075
1076func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1077	ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1078	if a.aaptSrcJar != nil {
1079		ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1080	}
1081	if a.rJar != nil {
1082		ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1083	}
1084	ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1085	ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1086	ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1087	setOutputFiles(ctx, a.Library.Module)
1088}
1089
1090type appDepsInterface interface {
1091	SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
1092	MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
1093	RequiresStableAPIs(ctx android.BaseModuleContext) bool
1094}
1095
1096func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1097	shouldCollectRecursiveNativeDeps bool,
1098	checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
1099
1100	if checkNativeSdkVersion {
1101		checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1102			app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
1103	}
1104	jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1105		checkNativeSdkVersion, func(parent, child android.Module) bool {
1106			apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
1107			childLinkable, _ := child.(cc.LinkableInterface)
1108			parentLinkable, _ := parent.(cc.LinkableInterface)
1109			useStubsOfDep := childLinkable.IsStubs()
1110			if apkInApex && parentLinkable != nil {
1111				// APK-in-APEX
1112				// If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
1113				useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child))
1114			}
1115			return !childLinkable.IsNdk(ctx.Config()) && !useStubsOfDep
1116		})
1117
1118	var certificates []Certificate
1119
1120	var directImplementationDeps android.Paths
1121	var transitiveImplementationDeps []depset.DepSet[android.Path]
1122	ctx.VisitDirectDeps(func(module android.Module) {
1123		otherName := ctx.OtherModuleName(module)
1124		tag := ctx.OtherModuleDependencyTag(module)
1125
1126		if tag == certificateTag {
1127			if dep, ok := module.(*AndroidAppCertificate); ok {
1128				certificates = append(certificates, dep.Certificate)
1129			} else {
1130				ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1131			}
1132		}
1133
1134		if IsJniDepTag(tag) {
1135			directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1136			if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1137				transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1138			}
1139		}
1140	})
1141	android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1142		ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1143	})
1144
1145	return jniLib, prebuiltJniPackages, certificates
1146}
1147
1148func collectJniDeps(ctx android.ModuleContext,
1149	shouldCollectRecursiveNativeDeps bool,
1150	checkNativeSdkVersion bool,
1151	filter func(parent, child android.Module) bool) ([]jniLib, android.Paths) {
1152	var jniLibs []jniLib
1153	var prebuiltJniPackages android.Paths
1154	seenModulePaths := make(map[string]bool)
1155
1156	ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
1157		otherName := ctx.OtherModuleName(module)
1158		tag := ctx.OtherModuleDependencyTag(module)
1159
1160		if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
1161			if dep, ok := module.(cc.LinkableInterface); ok {
1162				if filter != nil && !filter(parent, module) {
1163					return false
1164				}
1165
1166				lib := dep.OutputFile()
1167				if lib.Valid() {
1168					path := lib.Path()
1169					if seenModulePaths[path.String()] {
1170						return false
1171					}
1172					seenModulePaths[path.String()] = true
1173
1174					if checkNativeSdkVersion && dep.SdkVersion() == "" {
1175						ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1176							otherName)
1177					}
1178
1179					jniLibs = append(jniLibs, jniLib{
1180						name:           ctx.OtherModuleName(module),
1181						path:           path,
1182						target:         module.Target(),
1183						coverageFile:   dep.CoverageOutputFile(),
1184						unstrippedFile: dep.UnstrippedOutputFile(),
1185						partition:      dep.Partition(),
1186						installPaths:   android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
1187					})
1188				} else if ctx.Config().AllowMissingDependencies() {
1189					ctx.AddMissingDependencies([]string{otherName})
1190				} else {
1191					ctx.ModuleErrorf("dependency %q missing output file", otherName)
1192				}
1193			} else {
1194				ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
1195			}
1196
1197			return shouldCollectRecursiveNativeDeps
1198		}
1199
1200		if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
1201			prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1202		}
1203
1204		return false
1205	})
1206
1207	return jniLibs, prebuiltJniPackages
1208}
1209
1210func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
1211	ctx.WalkDeps(func(child, parent android.Module) bool {
1212		isExternal := !a.DepIsInSameApex(ctx, child)
1213		if am, ok := child.(android.ApexModule); ok {
1214			if !do(ctx, parent, am, isExternal) {
1215				return false
1216			}
1217		}
1218		return !isExternal
1219	})
1220}
1221
1222func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1223	if ctx.Host() {
1224		return
1225	}
1226
1227	depsInfo := android.DepNameToDepInfoMap{}
1228	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
1229		depName := to.Name()
1230
1231		// Skip dependencies that are only available to APEXes; they are developed with updatability
1232		// in mind and don't need manual approval.
1233		if to.(android.ApexModule).NotAvailableForPlatform() {
1234			return true
1235		}
1236
1237		if info, exist := depsInfo[depName]; exist {
1238			info.From = append(info.From, from.Name())
1239			info.IsExternal = info.IsExternal && externalDep
1240			depsInfo[depName] = info
1241		} else {
1242			toMinSdkVersion := "(no version)"
1243			if m, ok := to.(interface {
1244				MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
1245			}); ok {
1246				if v := m.MinSdkVersion(ctx); !v.IsNone() {
1247					toMinSdkVersion = v.String()
1248				}
1249			} else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1250				// TODO(b/175678607) eliminate the use of MinSdkVersion returning
1251				// string
1252				if v := m.MinSdkVersion(); v != "" {
1253					toMinSdkVersion = v
1254				}
1255			}
1256			depsInfo[depName] = android.ApexModuleDepInfo{
1257				To:            depName,
1258				From:          []string{from.Name()},
1259				IsExternal:    externalDep,
1260				MinSdkVersion: toMinSdkVersion,
1261			}
1262		}
1263		return true
1264	})
1265
1266	a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
1267}
1268
1269func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1270	return a.appProperties.EnforceDefaultTargetSdkVersion
1271}
1272
1273func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1274	a.appProperties.EnforceDefaultTargetSdkVersion = val
1275}
1276
1277func (a *AndroidApp) Updatable() bool {
1278	return Bool(a.appProperties.Updatable)
1279}
1280
1281func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
1282	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1283	if overridden {
1284		return ":" + certificate
1285	}
1286	return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
1287}
1288
1289func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1290	if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1291		return true
1292	}
1293	return a.Library.DepIsInSameApex(ctx, dep)
1294}
1295
1296func (a *AndroidApp) Privileged() bool {
1297	return Bool(a.appProperties.Privileged)
1298}
1299
1300func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
1301	return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
1302}
1303
1304func (a *AndroidApp) SetPreventInstall() {
1305	a.appProperties.PreventInstall = true
1306}
1307
1308func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1309	a.appProperties.IsCoverageVariant = coverage
1310}
1311
1312func (a *AndroidApp) EnableCoverageIfNeeded() {}
1313
1314var _ cc.Coverage = (*AndroidApp)(nil)
1315
1316func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1317	a.Library.IDEInfo(ctx, dpInfo)
1318	a.aapt.IDEInfo(ctx, dpInfo)
1319}
1320
1321func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1322	return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1323}
1324
1325func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1326	return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1327}
1328
1329// android_app compiles sources and Android resources into an Android application package `.apk` file.
1330func AndroidAppFactory() android.Module {
1331	module := &AndroidApp{}
1332
1333	module.Module.dexProperties.Optimize.EnabledByDefault = true
1334	module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
1335	module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
1336
1337	module.Module.properties.Instrument = true
1338	module.Module.properties.Supports_static_instrumentation = true
1339	module.Module.properties.Installable = proptools.BoolPtr(true)
1340
1341	module.addHostAndDeviceProperties()
1342	module.AddProperties(
1343		&module.aaptProperties,
1344		&module.appProperties,
1345		&module.overridableAppProperties,
1346		&module.Library.sourceProperties)
1347
1348	module.usesLibrary.enforce = true
1349
1350	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1351	android.InitDefaultableModule(module)
1352	android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
1353	android.InitApexModule(module)
1354
1355	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1356		a := ctx.Module().(*AndroidApp)
1357
1358		characteristics := ctx.Config().ProductAAPTCharacteristics()
1359		if characteristics == "default" || characteristics == "" {
1360			module.appProperties.Generate_product_characteristics_rro = nil
1361			// no need to create RRO
1362			return
1363		}
1364
1365		if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1366			return
1367		}
1368
1369		rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1370		rroManifestName := rroPackageName + "_manifest"
1371
1372		a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1373		a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1374
1375		rroManifestProperties := struct {
1376			Name  *string
1377			Tools []string
1378			Out   []string
1379			Srcs  []string
1380			Cmd   *string
1381		}{
1382			Name:  proptools.StringPtr(rroManifestName),
1383			Tools: []string{"characteristics_rro_generator", "aapt2"},
1384			Out:   []string{"AndroidManifest.xml"},
1385			Srcs:  []string{":" + a.Name() + "{.apk}"},
1386			Cmd:   proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
1387		}
1388		ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
1389
1390		rroProperties := struct {
1391			Name           *string
1392			Filter_product *string
1393			Aaptflags      []string
1394			Manifest       *string
1395			Resource_dirs  proptools.Configurable[[]string]
1396			Flags_packages []string
1397		}{
1398			Name:           proptools.StringPtr(rroPackageName),
1399			Filter_product: proptools.StringPtr(characteristics),
1400			Aaptflags:      []string{"--auto-add-overlay"},
1401			Manifest:       proptools.StringPtr(":" + rroManifestName),
1402			Resource_dirs:  a.aaptProperties.Resource_dirs,
1403			Flags_packages: a.aaptProperties.Flags_packages,
1404		}
1405		if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1406			for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1407				rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1408			}
1409		}
1410		ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1411
1412	})
1413
1414	module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1415		createInternalRuntimeOverlays(ctx, module.ModuleBase)
1416	})
1417
1418	return module
1419}
1420
1421func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1422	return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1423}
1424
1425type createModuleContext interface {
1426	android.EarlyModuleContext
1427	CreateModule(android.ModuleFactory, ...interface{}) android.Module
1428}
1429
1430func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
1431	if !ctx.Config().HasDeviceProduct() {
1432		return
1433	}
1434	// vendor
1435	vendorOverlayProps := struct {
1436		Name                *string
1437		Base                *string
1438		Vendor              *bool
1439		Product_specific    *bool
1440		System_ext_specific *bool
1441		Manifest            *string
1442		Sdk_version         *string
1443		Compile_multilib    *string
1444		Enabled             proptools.Configurable[bool]
1445	}{
1446		Name:                proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")),
1447		Base:                proptools.StringPtr(a.Name()),
1448		Vendor:              proptools.BoolPtr(true),
1449		Product_specific:    proptools.BoolPtr(false),
1450		System_ext_specific: proptools.BoolPtr(false),
1451		Manifest:            proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1452		Sdk_version:         proptools.StringPtr("current"),
1453		Compile_multilib:    proptools.StringPtr("first"),
1454		Enabled:             a.EnabledProperty().Clone(),
1455	}
1456	ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
1457
1458	// product
1459	productOverlayProps := struct {
1460		Name                *string
1461		Base                *string
1462		Vendor              *bool
1463		Proprietary         *bool
1464		Soc_specific        *bool
1465		Product_specific    *bool
1466		System_ext_specific *bool
1467		Manifest            *string
1468		Sdk_version         *string
1469		Compile_multilib    *string
1470		Enabled             proptools.Configurable[bool]
1471	}{
1472		Name:                proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
1473		Base:                proptools.StringPtr(a.Name()),
1474		Vendor:              proptools.BoolPtr(false),
1475		Proprietary:         proptools.BoolPtr(false),
1476		Soc_specific:        proptools.BoolPtr(false),
1477		Product_specific:    proptools.BoolPtr(true),
1478		System_ext_specific: proptools.BoolPtr(false),
1479		Manifest:            proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1480		Sdk_version:         proptools.StringPtr("current"),
1481		Compile_multilib:    proptools.StringPtr("first"),
1482		Enabled:             a.EnabledProperty().Clone(),
1483	}
1484	ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
1485}
1486
1487// A dictionary of values to be overridden in the manifest.
1488type Manifest_values struct {
1489	// Overrides the value of package_name in the manifest
1490	ApplicationId *string
1491}
1492
1493type appTestProperties struct {
1494	// The name of the android_app module that the tests will run against.
1495	Instrumentation_for *string
1496
1497	// If specified, the instrumentation target package name in the manifest is overwritten by it.
1498	Instrumentation_target_package *string
1499
1500	// If specified, the mainline module package name in the test config is overwritten by it.
1501	Mainline_package_name *string
1502
1503	Manifest_values Manifest_values
1504}
1505
1506type AndroidTest struct {
1507	AndroidApp
1508
1509	appTestProperties appTestProperties
1510
1511	testProperties testProperties
1512
1513	testConfig       android.Path
1514	extraTestConfigs android.Paths
1515	data             android.Paths
1516}
1517
1518func (a *AndroidTest) InstallInTestcases() bool {
1519	return true
1520}
1521
1522type androidTestApp interface {
1523	includedInTestSuite(searchPrefix string) bool
1524}
1525
1526func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1527	return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1528}
1529
1530func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1531	return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1532}
1533
1534func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1535	checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
1536	var configs []tradefed.Config
1537	if a.appTestProperties.Instrumentation_target_package != nil {
1538		a.additionalAaptFlags = append(a.additionalAaptFlags,
1539			"--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1540	} else if a.appTestProperties.Instrumentation_for != nil {
1541		// Check if the instrumentation target package is overridden.
1542		manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1543		if overridden {
1544			a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1545		}
1546	}
1547	applicationId := a.appTestProperties.Manifest_values.ApplicationId
1548	if applicationId != nil {
1549		packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1550		if packageNameProp.IsPresent() {
1551			ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1552		}
1553		a.aapt.manifestValues.applicationId = *applicationId
1554	}
1555	a.generateAndroidBuildActions(ctx)
1556
1557	for _, module := range a.testProperties.Test_mainline_modules {
1558		configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1559	}
1560
1561	testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
1562		a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1563		a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
1564	a.testConfig = a.FixTestConfig(ctx, testConfig)
1565	a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
1566	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
1567	a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1568	a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
1569	a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
1570
1571	android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1572		TestcaseRelDataFiles:    testcaseRel(a.data),
1573		OutputFile:              a.OutputFile(),
1574		TestConfig:              a.testConfig,
1575		HostRequiredModuleNames: a.HostRequiredModuleNames(),
1576		TestSuites:              a.testProperties.Test_suites,
1577		IsHost:                  false,
1578		LocalCertificate:        a.certificate.AndroidMkString(),
1579		IsUnitTest:              Bool(a.testProperties.Test_options.Unit_test),
1580		MkInclude:               "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1581		MkAppClass:              "APPS",
1582	})
1583	android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1584		TestOnly:       true,
1585		TopLevelTarget: true,
1586	})
1587
1588}
1589
1590func testcaseRel(paths android.Paths) []string {
1591	relPaths := []string{}
1592	for _, p := range paths {
1593		relPaths = append(relPaths, p.Rel())
1594	}
1595	return relPaths
1596}
1597
1598func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1599	if testConfig == nil {
1600		return nil
1601	}
1602
1603	fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
1604	rule := android.NewRuleBuilder(pctx, ctx)
1605	command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
1606	fixNeeded := false
1607
1608	// Auto-generated test config uses `ModuleName` as the APK name. So fix it if it is not the case.
1609	if ctx.ModuleName() != a.installApkName {
1610		fixNeeded = true
1611		command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1612	}
1613
1614	packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1615	if packageNameProp.IsPresent() {
1616		fixNeeded = true
1617		command.FlagWithInput("--manifest ", a.manifestPath).
1618			FlagWithArg("--package-name ", packageNameProp.Get())
1619	}
1620
1621	if a.appTestProperties.Mainline_package_name != nil {
1622		fixNeeded = true
1623		command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1624	}
1625
1626	if fixNeeded {
1627		rule.Build("fix_test_config", "fix test config")
1628		return fixedConfig
1629	}
1630	return testConfig
1631}
1632
1633func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1634	if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1635		// Instrument the android_test_helper target to log potential API calls at the run time.
1636		// Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1637		ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1638		a.setApiMapper(true)
1639	}
1640	a.AndroidApp.DepsMutator(ctx)
1641}
1642
1643func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
1644	if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1645		// Instrument the android_test_helper target to log potential API calls at the run time.
1646		// Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1647		ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1648		a.setApiMapper(true)
1649	}
1650	a.AndroidApp.DepsMutator(ctx)
1651}
1652
1653func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1654	a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
1655	if a.appTestProperties.Instrumentation_for != nil {
1656		// The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1657		// but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1658		// use instrumentationForTag instead of libTag.
1659		ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1660	}
1661}
1662
1663// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1664// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
1665func AndroidTestFactory() android.Module {
1666	module := &AndroidTest{}
1667
1668	module.Module.dexProperties.Optimize.EnabledByDefault = false
1669
1670	module.Module.properties.Instrument = true
1671	module.Module.properties.Supports_static_instrumentation = true
1672	module.Module.properties.Installable = proptools.BoolPtr(true)
1673	module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1674	module.appProperties.AlwaysPackageNativeLibs = true
1675	module.Module.dexpreopter.isTest = true
1676	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
1677
1678	module.addHostAndDeviceProperties()
1679	module.AddProperties(
1680		&module.aaptProperties,
1681		&module.appProperties,
1682		&module.appTestProperties,
1683		&module.overridableAppProperties,
1684		&module.testProperties)
1685
1686	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1687	android.InitDefaultableModule(module)
1688	android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
1689
1690	return module
1691}
1692
1693type appTestHelperAppProperties struct {
1694	// list of compatibility suites (for example "cts", "vts") that the module should be
1695	// installed into.
1696	Test_suites []string `android:"arch_variant"`
1697
1698	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1699	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1700	// explicitly.
1701	Auto_gen_config *bool
1702
1703	// Install the test into a folder named for the module in all test suites.
1704	Per_testcase_directory *bool
1705
1706	Manifest_values Manifest_values
1707}
1708
1709type AndroidTestHelperApp struct {
1710	AndroidApp
1711
1712	appTestHelperAppProperties appTestHelperAppProperties
1713}
1714
1715func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1716	return true
1717}
1718
1719// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1720// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1721// test.
1722func AndroidTestHelperAppFactory() android.Module {
1723	module := &AndroidTestHelperApp{}
1724
1725	// TODO(b/192032291): Disable by default after auditing downstream usage.
1726	module.Module.dexProperties.Optimize.EnabledByDefault = true
1727
1728	module.Module.properties.Installable = proptools.BoolPtr(true)
1729	module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1730	module.appProperties.AlwaysPackageNativeLibs = true
1731	module.Module.dexpreopter.isTest = true
1732	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
1733
1734	module.addHostAndDeviceProperties()
1735	module.AddProperties(
1736		&module.aaptProperties,
1737		&module.appProperties,
1738		&module.appTestHelperAppProperties,
1739		&module.overridableAppProperties)
1740
1741	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1742	android.InitDefaultableModule(module)
1743	android.InitApexModule(module)
1744	return module
1745}
1746
1747type AndroidAppCertificate struct {
1748	android.ModuleBase
1749
1750	properties  AndroidAppCertificateProperties
1751	Certificate Certificate
1752}
1753
1754type AndroidAppCertificateProperties struct {
1755	// Name of the certificate files.  Extensions .x509.pem and .pk8 will be added to the name.
1756	Certificate *string
1757}
1758
1759// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1760// the signing key.
1761func AndroidAppCertificateFactory() android.Module {
1762	module := &AndroidAppCertificate{}
1763	module.AddProperties(&module.properties)
1764	android.InitAndroidModule(module)
1765	return module
1766}
1767
1768func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1769	cert := String(c.properties.Certificate)
1770	c.Certificate = Certificate{
1771		Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1772		Key: android.PathForModuleSrc(ctx, cert+".pk8"),
1773	}
1774}
1775
1776type OverrideAndroidApp struct {
1777	android.ModuleBase
1778	android.OverrideModuleBase
1779}
1780
1781func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
1782	// All the overrides happen in the base module.
1783	// TODO(jungjw): Check the base module type.
1784}
1785
1786// override_android_app is used to create an android_app module based on another android_app by overriding
1787// some of its properties.
1788func OverrideAndroidAppModuleFactory() android.Module {
1789	m := &OverrideAndroidApp{}
1790	m.AddProperties(
1791		&OverridableProperties{},
1792		&overridableAppProperties{},
1793	)
1794
1795	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1796	android.InitOverrideModule(m)
1797	android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) {
1798		createInternalRuntimeOverlays(ctx, m.ModuleBase)
1799	}, 1) // Run after soong config load hoook
1800
1801	return m
1802}
1803
1804type OverrideAndroidTest struct {
1805	android.ModuleBase
1806	android.OverrideModuleBase
1807}
1808
1809func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1810	// All the overrides happen in the base module.
1811	// TODO(jungjw): Check the base module type.
1812	android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1813		TestOnly:       true,
1814		TopLevelTarget: true,
1815	})
1816}
1817
1818// override_android_test is used to create an android_app module based on another android_test by overriding
1819// some of its properties.
1820func OverrideAndroidTestModuleFactory() android.Module {
1821	m := &OverrideAndroidTest{}
1822	m.AddProperties(&overridableAppProperties{})
1823	m.AddProperties(&appTestProperties{})
1824
1825	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1826	android.InitOverrideModule(m)
1827	return m
1828}
1829
1830type UsesLibraryProperties struct {
1831	// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
1832	Uses_libs proptools.Configurable[[]string]
1833
1834	// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1835	// required=false.
1836	Optional_uses_libs proptools.Configurable[[]string]
1837
1838	// If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file.  Defaults
1839	// to true if either uses_libs or optional_uses_libs is set.  Will unconditionally default to true in the future.
1840	Enforce_uses_libs *bool
1841
1842	// Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1843	// libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1844	// normally is the same as the module name, but there are exceptions.
1845	Provides_uses_lib *string
1846
1847	// A list of shared library names to exclude from the classpath of the APK. Adding a library here
1848	// will prevent it from being used when precompiling the APK and prevent it from being implicitly
1849	// added to the APK's manifest's <uses-library> elements.
1850	//
1851	// Care must be taken when using this as it could result in runtime errors if the APK actually
1852	// uses classes provided by the library and which are not provided in any other way.
1853	//
1854	// This is primarily intended for use by various CTS tests that check the runtime handling of the
1855	// android.test.base shared library (and related libraries) but which depend on some common
1856	// libraries that depend on the android.test.base library. Without this those tests will end up
1857	// with a <uses-library android:name="android.test.base"/> in their manifest which would either
1858	// render the tests worthless (as they would be testing the wrong behavior), or would break the
1859	// test altogether by providing access to classes that the tests were not expecting. Those tests
1860	// provide the android.test.base statically and use jarjar to rename them so they do not collide
1861	// with the classes provided by the android.test.base library.
1862	Exclude_uses_libs []string
1863
1864	// The module names of optional uses-library libraries that are missing from the source tree.
1865	Missing_optional_uses_libs []string `blueprint:"mutated"`
1866}
1867
1868// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1869// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1870// uses_libs and optional_uses_libs properties.  The build system's values are used by dexpreopt to preopt apps
1871// with knowledge of their shared libraries.
1872type usesLibrary struct {
1873	usesLibraryProperties UsesLibraryProperties
1874
1875	// Whether to enforce verify_uses_library check.
1876	enforce bool
1877
1878	// Whether dexpreopt should be disabled
1879	shouldDisableDexpreopt bool
1880}
1881
1882func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
1883	if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
1884		ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
1885		presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1886		ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
1887		// Only add these extra dependencies if the module is an app that depends on framework
1888		// libs. This avoids creating a cyclic dependency:
1889		//     e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
1890		if addCompatDeps {
1891			// Dexpreopt needs paths to the dex jars of these libraries in order to construct
1892			// class loader context for dex2oat. Add them as a dependency with a special tag.
1893			ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1894			ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1895			ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
1896		}
1897		_, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
1898		u.usesLibraryProperties.Missing_optional_uses_libs = diff
1899	} else {
1900		ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
1901		ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
1902	}
1903}
1904
1905// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
1906func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
1907	optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
1908		exists := ctx.OtherModuleExists(s)
1909		if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
1910			fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1911		}
1912		return exists
1913	})
1914	return optionalUsesLibs
1915}
1916
1917// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1918// host and on device.
1919func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1920	clcMap := make(dexpreopt.ClassLoaderContextMap)
1921
1922	// Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1923	// UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1924	if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1925		return clcMap
1926	}
1927
1928	ctx.VisitDirectDeps(func(m android.Module) {
1929		tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1930		if !isUsesLibTag {
1931			return
1932		}
1933
1934		dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
1935
1936		// Skip stub libraries. A dependency on the implementation library has been added earlier,
1937		// so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1938		// from implementation libraries by their name, which is different as it has a suffix.
1939		if comp, ok := m.(SdkLibraryComponentDependency); ok {
1940			if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1941				return
1942			}
1943		}
1944
1945		if lib, ok := m.(UsesLibraryDependency); ok {
1946			if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1947				// Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1948				// This will be restricted to optional_uses_libs
1949				if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
1950					u.shouldDisableDexpreopt = true
1951					return
1952				}
1953			}
1954			libName := dep
1955			if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
1956				libName = *ulib.ProvidesUsesLib()
1957			}
1958			clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
1959				lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
1960				lib.ClassLoaderContexts())
1961		} else if ctx.Config().AllowMissingDependencies() {
1962			ctx.AddMissingDependencies([]string{dep})
1963		} else {
1964			ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1965		}
1966	})
1967	return clcMap
1968}
1969
1970// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1971// properties.  Defaults to true if either of uses_libs or optional_uses_libs is specified.  Will default to true
1972// unconditionally in the future.
1973func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
1974	defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
1975		len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
1976	return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
1977}
1978
1979// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
1980func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
1981	enforce := u.enforceUsesLibraries(ctx)
1982	u.usesLibraryProperties.Enforce_uses_libs = &enforce
1983}
1984
1985// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1986// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1987// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1988// extension: APKs are supposed to end with '.apk').
1989func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
1990	outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
1991
1992	statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
1993
1994	// Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1995	// check is not necessary, and although it is good to have, it is difficult to maintain on
1996	// non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1997	// various unrelated reasons, such as a failure to get manifest from an APK).
1998	global := dexpreopt.GetGlobalConfig(ctx)
1999	if global.DisablePreopt || global.OnlyPreoptArtBootImage {
2000		return inputFile
2001	}
2002
2003	rule := android.NewRuleBuilder(pctx, ctx)
2004	cmd := rule.Command().BuiltTool("manifest_check").
2005		Flag("--enforce-uses-libraries").
2006		Input(inputFile).
2007		FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
2008		FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
2009
2010	if outputFile != nil {
2011		cmd.FlagWithOutput("-o ", outputFile)
2012	}
2013
2014	if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
2015		cmd.Flag("--enforce-uses-libraries-relax")
2016	}
2017
2018	requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
2019	for _, lib := range requiredUsesLibs {
2020		cmd.FlagWithArg("--uses-library ", lib)
2021	}
2022	for _, lib := range optionalUsesLibs {
2023		cmd.FlagWithArg("--optional-uses-library ", lib)
2024	}
2025
2026	// Also add missing optional uses libs, as the manifest check expects them.
2027	// Note that what we add here are the module names of those missing libs, not library names, while
2028	// the manifest check actually expects library names. However, the case where a library is missing
2029	// and the module name != the library name is too rare for us to handle.
2030	for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
2031		cmd.FlagWithArg("--missing-optional-uses-library ", lib)
2032	}
2033
2034	rule.Build("verify_uses_libraries", "verify <uses-library>")
2035	return outputFile
2036}
2037
2038// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
2039// the build system and returns the path to a copy of the manifest.
2040func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
2041	classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
2042	outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
2043	return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
2044}
2045
2046// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
2047// system and returns the path to a copy of the APK.
2048func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
2049	classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
2050	u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
2051}
2052