• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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	"path/filepath"
22	"strings"
23
24	"github.com/google/blueprint"
25	"github.com/google/blueprint/proptools"
26
27	"android/soong/android"
28	"android/soong/bazel"
29	"android/soong/cc"
30	"android/soong/dexpreopt"
31	"android/soong/tradefed"
32)
33
34func init() {
35	RegisterAppBuildComponents(android.InitRegistrationContext)
36}
37
38func RegisterAppBuildComponents(ctx android.RegistrationContext) {
39	ctx.RegisterModuleType("android_app", AndroidAppFactory)
40	ctx.RegisterModuleType("android_test", AndroidTestFactory)
41	ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
42	ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
43	ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
44	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
45}
46
47// AndroidManifest.xml merging
48// package splits
49
50type appProperties struct {
51	// Names of extra android_app_certificate modules to sign the apk with in the form ":module".
52	Additional_certificates []string
53
54	// If set, create package-export.apk, which other packages can
55	// use to get PRODUCT-agnostic resource data like IDs and type definitions.
56	Export_package_resources *bool
57
58	// Specifies that this app should be installed to the priv-app directory,
59	// where the system will grant it additional privileges not available to
60	// normal apps.
61	Privileged *bool
62
63	// list of resource labels to generate individual resource packages
64	Package_splits []string
65
66	// list of native libraries that will be provided in or alongside the resulting jar
67	Jni_libs []string `android:"arch_variant"`
68
69	// if true, use JNI libraries that link against platform APIs even if this module sets
70	// sdk_version.
71	Jni_uses_platform_apis *bool
72
73	// if true, use JNI libraries that link against SDK APIs even if this module does not set
74	// sdk_version.
75	Jni_uses_sdk_apis *bool
76
77	// STL library to use for JNI libraries.
78	Stl *string `android:"arch_variant"`
79
80	// Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
81	// flag so that they are used from inside the APK at runtime.  Defaults to true for android_test modules unless
82	// sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
83	// android_app modules that are embedded to APEXes, defaults to false for other module types where the native
84	// libraries are generally preinstalled outside the APK.
85	Use_embedded_native_libs *bool
86
87	// Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
88	// they are used from inside the APK at runtime.
89	Use_embedded_dex *bool
90
91	// Forces native libraries to always be packaged into the APK,
92	// Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
93	// True for android_test* modules.
94	AlwaysPackageNativeLibs bool `blueprint:"mutated"`
95
96	// If set, find and merge all NOTICE files that this module and its dependencies have and store
97	// it in the APK as an asset.
98	Embed_notices *bool
99
100	// cc.Coverage related properties
101	PreventInstall    bool `blueprint:"mutated"`
102	IsCoverageVariant bool `blueprint:"mutated"`
103
104	// It can be set to test the behaviour of default target sdk version.
105	// Only required when updatable: false. It is an error if updatable: true and this is false.
106	Enforce_default_target_sdk_version *bool
107
108	// If set, the targetSdkVersion for the target is set to the latest default API level.
109	// This would be by default false, unless updatable: true or
110	// enforce_default_target_sdk_version: true in which case this defaults to true.
111	EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
112
113	// Whether this app is considered mainline updatable or not. When set to true, this will enforce
114	// additional rules to make sure an app can safely be updated. Default is false.
115	// Prefer using other specific properties if build behaviour must be changed; avoid using this
116	// flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
117	Updatable *bool
118}
119
120// android_app properties that can be overridden by override_android_app
121type overridableAppProperties struct {
122	// The name of a certificate in the default certificate directory, blank to use the default product certificate,
123	// or an android_app_certificate module name in the form ":module".
124	Certificate *string
125
126	// Name of the signing certificate lineage file or filegroup module.
127	Lineage *string `android:"path"`
128
129	// For overriding the --rotation-min-sdk-version property of apksig
130	RotationMinSdkVersion *string
131
132	// the package name of this app. The package name in the manifest file is used if one was not given.
133	Package_name *string
134
135	// the logging parent of this app.
136	Logging_parent *string
137
138	// Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
139	Rename_resources_package *bool
140
141	// Names of modules to be overridden. Listed modules can only be other binaries
142	// (in Make or Soong).
143	// This does not completely prevent installation of the overridden binaries, but if both
144	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
145	// from PRODUCT_PACKAGES.
146	Overrides []string
147}
148
149type AndroidApp struct {
150	android.BazelModuleBase
151	Library
152	aapt
153	android.OverridableModuleBase
154
155	certificate Certificate
156
157	appProperties appProperties
158
159	overridableAppProperties overridableAppProperties
160
161	jniLibs                  []jniLib
162	installPathForJNISymbols android.Path
163	embeddedJniLibs          bool
164	jniCoverageOutputs       android.Paths
165
166	bundleFile android.Path
167
168	// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
169	installApkName string
170
171	installDir android.InstallPath
172
173	onDeviceDir string
174
175	additionalAaptFlags []string
176
177	overriddenManifestPackageName string
178
179	android.ApexBundleDepsInfo
180
181	javaApiUsedByOutputFile android.ModuleOutPath
182}
183
184func (a *AndroidApp) IsInstallable() bool {
185	return Bool(a.properties.Installable)
186}
187
188func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
189	return nil
190}
191
192func (a *AndroidApp) ExportedStaticPackages() android.Paths {
193	return nil
194}
195
196func (a *AndroidApp) OutputFile() android.Path {
197	return a.outputFile
198}
199
200func (a *AndroidApp) Certificate() Certificate {
201	return a.certificate
202}
203
204func (a *AndroidApp) JniCoverageOutputs() android.Paths {
205	return a.jniCoverageOutputs
206}
207
208var _ AndroidLibraryDependency = (*AndroidApp)(nil)
209
210type Certificate struct {
211	Pem, Key  android.Path
212	presigned bool
213}
214
215var PresignedCertificate = Certificate{presigned: true}
216
217func (c Certificate) AndroidMkString() string {
218	if c.presigned {
219		return "PRESIGNED"
220	} else {
221		return c.Pem.String()
222	}
223}
224
225func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
226	a.Module.deps(ctx)
227
228	if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
229		ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
230	}
231
232	sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
233	if sdkDep.hasFrameworkLibs() {
234		a.aapt.deps(ctx, sdkDep)
235	}
236
237	usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
238
239	if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
240		ctx.PropertyErrorf("jni_uses_sdk_apis",
241			"can only be set for modules that do not set sdk_version")
242	} else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
243		ctx.PropertyErrorf("jni_uses_platform_apis",
244			"can only be set for modules that set sdk_version")
245	}
246
247	for _, jniTarget := range ctx.MultiTargets() {
248		variation := append(jniTarget.Variations(),
249			blueprint.Variation{Mutator: "link", Variation: "shared"})
250
251		// If the app builds against an Android SDK use the SDK variant of JNI dependencies
252		// unless jni_uses_platform_apis is set.
253		// Don't require the SDK variant for apps that are shipped on vendor, etc., as they already
254		// have stable APIs through the VNDK.
255		if (usesSDK && !a.RequiresStableAPIs(ctx) &&
256			!Bool(a.appProperties.Jni_uses_platform_apis)) ||
257			Bool(a.appProperties.Jni_uses_sdk_apis) {
258			variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
259		}
260		ctx.AddFarVariationDependencies(variation, jniLibTag, a.appProperties.Jni_libs...)
261	}
262
263	a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
264}
265
266func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
267	cert := android.SrcIsModule(a.getCertString(ctx))
268	if cert != "" {
269		ctx.AddDependency(ctx.Module(), certificateTag, cert)
270	}
271
272	for _, cert := range a.appProperties.Additional_certificates {
273		cert = android.SrcIsModule(cert)
274		if cert != "" {
275			ctx.AddDependency(ctx.Module(), certificateTag, cert)
276		} else {
277			ctx.PropertyErrorf("additional_certificates",
278				`must be names of android_app_certificate modules in the form ":module"`)
279		}
280	}
281}
282
283func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
284	a.generateAndroidBuildActions(ctx)
285}
286
287func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
288	a.checkAppSdkVersions(ctx)
289	a.generateAndroidBuildActions(ctx)
290	a.generateJavaUsedByApex(ctx)
291}
292
293func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
294	if a.Updatable() {
295		if !a.SdkVersion(ctx).Stable() {
296			ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
297		}
298		if String(a.deviceProperties.Min_sdk_version) == "" {
299			ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
300		}
301
302		if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
303			a.checkJniLibsSdkVersion(ctx, minSdkVersion)
304			android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
305		} else {
306			ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
307		}
308
309		if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
310			ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
311		}
312		// TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
313		if a.deviceProperties.Target_sdk_version == nil {
314			a.SetEnforceDefaultTargetSdkVersion(true)
315		}
316	}
317
318	a.checkPlatformAPI(ctx)
319	a.checkSdkVersions(ctx)
320}
321
322// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
323// This check is enforced for "updatable" APKs (including APK-in-APEX).
324func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
325	// It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
326	ctx.VisitDirectDeps(func(m android.Module) {
327		if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
328			return
329		}
330		dep, _ := m.(*cc.Module)
331		// The domain of cc.sdk_version is "current" and <number>
332		// We can rely on android.SdkSpec to convert it to <number> so that "current" is
333		// handled properly regardless of sdk finalization.
334		jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
335		if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
336			ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
337				dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
338			return
339		}
340
341	})
342}
343
344// Returns true if the native libraries should be stored in the APK uncompressed and the
345// extractNativeLibs application flag should be set to false in the manifest.
346func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
347	minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
348	if err != nil {
349		ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
350	}
351
352	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
353	return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
354		!apexInfo.IsForPlatform()
355}
356
357// Returns whether this module should have the dex file stored uncompressed in the APK.
358func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
359	if Bool(a.appProperties.Use_embedded_dex) {
360		return true
361	}
362
363	// Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
364	// be preinstalled as prebuilts).
365	if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
366		return true
367	}
368
369	if ctx.Config().UnbundledBuild() {
370		return false
371	}
372
373	return shouldUncompressDex(ctx, &a.dexpreopter)
374}
375
376func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
377	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
378	return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
379		!apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
380}
381
382func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
383	aaptFlags := []string{"--rename-manifest-package " + packageName}
384	if renameResourcesPackage {
385		// Required to rename the package name in the resources table.
386		aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
387	}
388	return aaptFlags
389}
390
391func (a *AndroidApp) OverriddenManifestPackageName() string {
392	return a.overriddenManifestPackageName
393}
394
395func (a *AndroidApp) renameResourcesPackage() bool {
396	return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
397}
398
399func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
400	usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
401	if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
402		usePlatformAPI = true
403	}
404	a.aapt.usesNonSdkApis = usePlatformAPI
405
406	// Ask manifest_fixer to add or update the application element indicating this app has no code.
407	a.aapt.hasNoCode = !a.hasCode(ctx)
408
409	aaptLinkFlags := []string{}
410
411	// Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
412	hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
413	if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
414		aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
415	}
416
417	if !Bool(a.aaptProperties.Aapt_include_all_resources) {
418		// Product AAPT config
419		for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
420			aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
421		}
422
423		// Product AAPT preferred config
424		if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
425			aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
426		}
427	}
428
429	manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
430	if overridden || a.overridableAppProperties.Package_name != nil {
431		// The product override variable has a priority over the package_name property.
432		if !overridden {
433			manifestPackageName = *a.overridableAppProperties.Package_name
434		}
435		aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
436		a.overriddenManifestPackageName = manifestPackageName
437	}
438
439	aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
440
441	a.aapt.splitNames = a.appProperties.Package_splits
442	a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
443	if a.Updatable() {
444		a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
445	}
446	a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts,
447		a.usesLibraryProperties.Exclude_uses_libs, a.enforceDefaultTargetSdkVersion(), aaptLinkFlags...)
448
449	// apps manifests are handled by aapt, don't let Module see them
450	a.properties.Manifest = nil
451}
452
453func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
454	var staticLibProguardFlagFiles android.Paths
455	ctx.VisitDirectDeps(func(m android.Module) {
456		if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
457			staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
458		}
459	})
460
461	staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
462
463	a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...)
464	a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile)
465}
466
467func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
468	var installDir string
469	if ctx.ModuleName() == "framework-res" {
470		// framework-res.apk is installed as system/framework/framework-res.apk
471		installDir = "framework"
472	} else if a.Privileged() {
473		installDir = filepath.Join("priv-app", a.installApkName)
474	} else {
475		installDir = filepath.Join("app", a.installApkName)
476	}
477
478	return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
479}
480
481func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
482	a.dexpreopter.installPath = a.installPath(ctx)
483	a.dexpreopter.isApp = true
484	if a.dexProperties.Uncompress_dex == nil {
485		// If the value was not force-set by the user, use reasonable default based on the module.
486		a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
487	}
488	a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
489	a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
490	a.dexpreopter.classLoaderContexts = a.classLoaderContexts
491	a.dexpreopter.manifestFile = a.mergedManifestFile
492	a.dexpreopter.preventInstall = a.appProperties.PreventInstall
493
494	if ctx.ModuleName() != "framework-res" {
495		a.Module.compile(ctx, a.aaptSrcJar)
496	}
497
498	return a.dexJarFile.PathOrNil()
499}
500
501func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
502	var jniJarFile android.WritablePath
503	if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
504		a.jniLibs = jniLibs
505		if a.shouldEmbedJnis(ctx) {
506			jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
507			a.installPathForJNISymbols = a.installPath(ctx)
508			TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
509			for _, jni := range jniLibs {
510				if jni.coverageFile.Valid() {
511					// Only collect coverage for the first target arch if this is a multilib target.
512					// TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
513					// data file path collisions since the current coverage file path format doesn't contain
514					// arch-related strings. This is fine for now though; the code coverage team doesn't use
515					// multi-arch targets such as test_suite_* for coverage collections yet.
516					//
517					// Work with the team to come up with a new format that handles multilib modules properly
518					// and change this.
519					if len(ctx.Config().Targets[android.Android]) == 1 ||
520						ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
521						a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
522					}
523				}
524			}
525			a.embeddedJniLibs = true
526		}
527	}
528	return jniJarFile
529}
530
531func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
532	var jniSymbols android.RuleBuilderInstalls
533	for _, jniLib := range a.jniLibs {
534		if jniLib.unstrippedFile != nil {
535			jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
536				From: jniLib.unstrippedFile,
537				To:   filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
538			})
539		}
540	}
541	return jniSymbols
542}
543
544// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
545// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
546func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
547	ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
548	if android.SrcIsModule(certPropValue) == "" {
549		var mainCert Certificate
550		if certPropValue != "" {
551			defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
552			mainCert = Certificate{
553				Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
554				Key: defaultDir.Join(ctx, certPropValue+".pk8"),
555			}
556		} else {
557			pem, key := ctx.Config().DefaultAppCertificate(ctx)
558			mainCert = Certificate{
559				Pem: pem,
560				Key: key,
561			}
562		}
563		certificates = append([]Certificate{mainCert}, certificates...)
564	}
565
566	if len(certificates) > 0 {
567		mainCertificate = certificates[0]
568	} else {
569		// This can be reached with an empty certificate list if AllowMissingDependencies is set
570		// and the certificate property for this module is a module reference to a missing module.
571		if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
572			panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
573		}
574		// Set a certificate to avoid panics later when accessing it.
575		mainCertificate = Certificate{
576			Key: android.PathForModuleOut(ctx, "missing.pk8"),
577			Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
578		}
579	}
580
581	if !m.Platform() {
582		certPath := mainCertificate.Pem.String()
583		systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
584		if strings.HasPrefix(certPath, systemCertPath) {
585			enforceSystemCert := ctx.Config().EnforceSystemCertificate()
586			allowed := ctx.Config().EnforceSystemCertificateAllowList()
587
588			if enforceSystemCert && !inList(m.Name(), allowed) {
589				ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
590			}
591		}
592	}
593
594
595	return mainCertificate, certificates
596}
597
598func (a *AndroidApp) InstallApkName() string {
599	return a.installApkName
600}
601
602func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
603	var apkDeps android.Paths
604
605	if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() {
606		a.hideApexVariantFromMake = true
607	}
608
609	a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
610	a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
611
612	// Check if the install APK name needs to be overridden.
613	a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Stem())
614
615	if ctx.ModuleName() == "framework-res" {
616		// framework-res.apk is installed as system/framework/framework-res.apk
617		a.installDir = android.PathForModuleInstall(ctx, "framework")
618	} else if a.Privileged() {
619		a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
620	} else if ctx.InstallInTestcases() {
621		a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
622	} else {
623		a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
624	}
625	a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
626
627	a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
628
629	var noticeAssetPath android.WritablePath
630	if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
631		// The rule to create the notice file can't be generated yet, as the final output path
632		// for the apk isn't known yet.  Add the path where the notice file will be generated to the
633		// aapt rules now before calling aaptBuildActions, the rule to create the notice file will
634		// be generated later.
635		noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
636		a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
637	}
638
639	// For apps targeting latest target_sdk_version
640	if Bool(a.appProperties.Enforce_default_target_sdk_version) {
641		a.SetEnforceDefaultTargetSdkVersion(true)
642	}
643
644	// Process all building blocks, from AAPT to certificates.
645	a.aaptBuildActions(ctx)
646
647	// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
648	a.usesLibrary.freezeEnforceUsesLibraries()
649
650	// Add implicit SDK libraries to <uses-library> list.
651	requiredUsesLibs, optionalUsesLibs := a.classLoaderContexts.UsesLibs()
652	for _, usesLib := range requiredUsesLibs {
653		a.usesLibrary.addLib(usesLib, false)
654	}
655	for _, usesLib := range optionalUsesLibs {
656		a.usesLibrary.addLib(usesLib, true)
657	}
658
659	// Check that the <uses-library> list is coherent with the manifest.
660	if a.usesLibrary.enforceUsesLibraries() {
661		manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
662		apkDeps = append(apkDeps, manifestCheckFile)
663	}
664
665	a.proguardBuildActions(ctx)
666
667	a.linter.mergedManifest = a.aapt.mergedManifestFile
668	a.linter.manifest = a.aapt.manifestPath
669	a.linter.resources = a.aapt.resourceFiles
670	a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
671
672	dexJarFile := a.dexBuildActions(ctx)
673
674	jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
675	jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
676
677	if ctx.Failed() {
678		return
679	}
680
681	a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
682
683	// Build a final signed app package.
684	packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
685	v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
686	var v4SignatureFile android.WritablePath = nil
687	if v4SigningRequested {
688		v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
689	}
690	var lineageFile android.Path
691	if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
692		lineageFile = android.PathForModuleSrc(ctx, lineage)
693	}
694	rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
695
696	CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, Bool(a.dexProperties.Optimize.Shrink_resources))
697	a.outputFile = packageFile
698	if v4SigningRequested {
699		a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
700	}
701
702	if a.aapt.noticeFile.Valid() {
703		// Generating the notice file rule has to be here after a.outputFile is known.
704		noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
705		android.BuildNoticeHtmlOutputFromLicenseMetadata(
706			ctx, noticeFile, "", "",
707			[]string{
708				a.installDir.String() + "/",
709				android.PathForModuleInstall(ctx).String() + "/",
710				a.outputFile.String(),
711			})
712		builder := android.NewRuleBuilder(pctx, ctx)
713		builder.Command().Text("cp").
714			Input(noticeFile).
715			Output(noticeAssetPath)
716		builder.Build("notice_dir", "Building notice dir")
717	}
718
719	for _, split := range a.aapt.splits {
720		// Sign the split APKs
721		packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
722		if v4SigningRequested {
723			v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
724		}
725		CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, false)
726		a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
727		if v4SigningRequested {
728			a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
729		}
730	}
731
732	// Build an app bundle.
733	bundleFile := android.PathForModuleOut(ctx, "base.zip")
734	BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
735	a.bundleFile = bundleFile
736
737	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
738
739	// Install the app package.
740	if (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() &&
741		!a.appProperties.PreventInstall {
742
743		var extraInstalledPaths android.Paths
744		for _, extra := range a.extraOutputFiles {
745			installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
746			extraInstalledPaths = append(extraInstalledPaths, installed)
747		}
748		ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
749	}
750
751	a.buildAppDependencyInfo(ctx)
752}
753
754type appDepsInterface interface {
755	SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
756	MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
757	RequiresStableAPIs(ctx android.BaseModuleContext) bool
758}
759
760func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
761	shouldCollectRecursiveNativeDeps bool,
762	checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
763
764	var jniLibs []jniLib
765	var prebuiltJniPackages android.Paths
766	var certificates []Certificate
767	seenModulePaths := make(map[string]bool)
768
769	if checkNativeSdkVersion {
770		checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
771			app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
772	}
773
774	ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
775		otherName := ctx.OtherModuleName(module)
776		tag := ctx.OtherModuleDependencyTag(module)
777
778		if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
779			if dep, ok := module.(cc.LinkableInterface); ok {
780				if dep.IsNdk(ctx.Config()) || dep.IsStubs() {
781					return false
782				}
783
784				lib := dep.OutputFile()
785				if lib.Valid() {
786					path := lib.Path()
787					if seenModulePaths[path.String()] {
788						return false
789					}
790					seenModulePaths[path.String()] = true
791
792					if checkNativeSdkVersion && dep.SdkVersion() == "" {
793						ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
794							otherName)
795					}
796
797					jniLibs = append(jniLibs, jniLib{
798						name:           ctx.OtherModuleName(module),
799						path:           path,
800						target:         module.Target(),
801						coverageFile:   dep.CoverageOutputFile(),
802						unstrippedFile: dep.UnstrippedOutputFile(),
803						partition:      dep.Partition(),
804					})
805				} else if ctx.Config().AllowMissingDependencies() {
806					ctx.AddMissingDependencies([]string{otherName})
807				} else {
808					ctx.ModuleErrorf("dependency %q missing output file", otherName)
809				}
810			} else {
811				ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
812			}
813
814			return shouldCollectRecursiveNativeDeps
815		}
816
817		if info, ok := ctx.OtherModuleProvider(module, JniPackageProvider).(JniPackageInfo); ok {
818			prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
819		}
820
821		if tag == certificateTag {
822			if dep, ok := module.(*AndroidAppCertificate); ok {
823				certificates = append(certificates, dep.Certificate)
824			} else {
825				ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
826			}
827		}
828
829		return false
830	})
831
832	return jniLibs, prebuiltJniPackages, certificates
833}
834
835func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
836	ctx.WalkDeps(func(child, parent android.Module) bool {
837		isExternal := !a.DepIsInSameApex(ctx, child)
838		if am, ok := child.(android.ApexModule); ok {
839			if !do(ctx, parent, am, isExternal) {
840				return false
841			}
842		}
843		return !isExternal
844	})
845}
846
847func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
848	if ctx.Host() {
849		return
850	}
851
852	depsInfo := android.DepNameToDepInfoMap{}
853	a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
854		depName := to.Name()
855
856		// Skip dependencies that are only available to APEXes; they are developed with updatability
857		// in mind and don't need manual approval.
858		if to.(android.ApexModule).NotAvailableForPlatform() {
859			return true
860		}
861
862		if info, exist := depsInfo[depName]; exist {
863			info.From = append(info.From, from.Name())
864			info.IsExternal = info.IsExternal && externalDep
865			depsInfo[depName] = info
866		} else {
867			toMinSdkVersion := "(no version)"
868			if m, ok := to.(interface {
869				MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
870			}); ok {
871				if v := m.MinSdkVersion(ctx); !v.IsNone() {
872					toMinSdkVersion = v.String()
873				}
874			} else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
875				// TODO(b/175678607) eliminate the use of MinSdkVersion returning
876				// string
877				if v := m.MinSdkVersion(); v != "" {
878					toMinSdkVersion = v
879				}
880			}
881			depsInfo[depName] = android.ApexModuleDepInfo{
882				To:            depName,
883				From:          []string{from.Name()},
884				IsExternal:    externalDep,
885				MinSdkVersion: toMinSdkVersion,
886			}
887		}
888		return true
889	})
890
891	a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
892}
893
894func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
895	return a.appProperties.EnforceDefaultTargetSdkVersion
896}
897
898func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
899	a.appProperties.EnforceDefaultTargetSdkVersion = val
900}
901
902func (a *AndroidApp) Updatable() bool {
903	return Bool(a.appProperties.Updatable)
904}
905
906func (a *AndroidApp) SetUpdatable(val bool) {
907	a.appProperties.Updatable = &val
908}
909
910func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
911	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
912	if overridden {
913		return ":" + certificate
914	}
915	return String(a.overridableAppProperties.Certificate)
916}
917
918func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
919	if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
920		return true
921	}
922	return a.Library.DepIsInSameApex(ctx, dep)
923}
924
925// For OutputFileProducer interface
926func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) {
927	switch tag {
928	case ".aapt.srcjar":
929		return []android.Path{a.aaptSrcJar}, nil
930	case ".export-package.apk":
931		return []android.Path{a.exportPackage}, nil
932	}
933	return a.Library.OutputFiles(tag)
934}
935
936func (a *AndroidApp) Privileged() bool {
937	return Bool(a.appProperties.Privileged)
938}
939
940func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
941	return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
942}
943
944func (a *AndroidApp) SetPreventInstall() {
945	a.appProperties.PreventInstall = true
946}
947
948func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
949	a.appProperties.IsCoverageVariant = coverage
950}
951
952func (a *AndroidApp) EnableCoverageIfNeeded() {}
953
954var _ cc.Coverage = (*AndroidApp)(nil)
955
956// android_app compiles sources and Android resources into an Android application package `.apk` file.
957func AndroidAppFactory() android.Module {
958	module := &AndroidApp{}
959
960	module.Module.dexProperties.Optimize.EnabledByDefault = true
961	module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
962
963	module.Module.properties.Instrument = true
964	module.Module.properties.Supports_static_instrumentation = true
965	module.Module.properties.Installable = proptools.BoolPtr(true)
966
967	module.addHostAndDeviceProperties()
968	module.AddProperties(
969		&module.aaptProperties,
970		&module.appProperties,
971		&module.overridableAppProperties)
972
973	module.usesLibrary.enforce = true
974
975	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
976	android.InitDefaultableModule(module)
977	android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
978	android.InitApexModule(module)
979	android.InitBazelModule(module)
980
981	return module
982}
983
984type appTestProperties struct {
985	// The name of the android_app module that the tests will run against.
986	Instrumentation_for *string
987
988	// If specified, the instrumentation target package name in the manifest is overwritten by it.
989	Instrumentation_target_package *string
990
991	// If specified, the mainline module package name in the test config is overwritten by it.
992	Mainline_package_name *string
993}
994
995type AndroidTest struct {
996	AndroidApp
997
998	appTestProperties appTestProperties
999
1000	testProperties testProperties
1001
1002	testConfig       android.Path
1003	extraTestConfigs android.Paths
1004	data             android.Paths
1005}
1006
1007func (a *AndroidTest) InstallInTestcases() bool {
1008	return true
1009}
1010
1011type androidTestApp interface {
1012	includedInTestSuite(searchPrefix string) bool
1013}
1014
1015func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1016	return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1017}
1018
1019func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1020	return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1021}
1022
1023func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1024	var configs []tradefed.Config
1025	if a.appTestProperties.Instrumentation_target_package != nil {
1026		a.additionalAaptFlags = append(a.additionalAaptFlags,
1027			"--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1028	} else if a.appTestProperties.Instrumentation_for != nil {
1029		// Check if the instrumentation target package is overridden.
1030		manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1031		if overridden {
1032			a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1033		}
1034	}
1035	a.generateAndroidBuildActions(ctx)
1036
1037	for _, module := range a.testProperties.Test_mainline_modules {
1038		configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1039	}
1040
1041	testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
1042		a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
1043	a.testConfig = a.FixTestConfig(ctx, testConfig)
1044	a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
1045	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
1046}
1047
1048func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1049	if testConfig == nil {
1050		return nil
1051	}
1052
1053	fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
1054	rule := android.NewRuleBuilder(pctx, ctx)
1055	command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
1056	fixNeeded := false
1057
1058	// Auto-generated test config uses `ModuleName` as the APK name. So fix it if it is not the case.
1059	if ctx.ModuleName() != a.installApkName {
1060		fixNeeded = true
1061		command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1062	}
1063
1064	if a.overridableAppProperties.Package_name != nil {
1065		fixNeeded = true
1066		command.FlagWithInput("--manifest ", a.manifestPath).
1067			FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
1068	}
1069
1070	if a.appTestProperties.Mainline_package_name != nil {
1071		fixNeeded = true
1072		command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1073	}
1074
1075	if fixNeeded {
1076		rule.Build("fix_test_config", "fix test config")
1077		return fixedConfig
1078	}
1079	return testConfig
1080}
1081
1082func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
1083	a.AndroidApp.DepsMutator(ctx)
1084}
1085
1086func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1087	a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
1088	if a.appTestProperties.Instrumentation_for != nil {
1089		// The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1090		// but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1091		// use instrumentationForTag instead of libTag.
1092		ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1093	}
1094}
1095
1096// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1097// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
1098func AndroidTestFactory() android.Module {
1099	module := &AndroidTest{}
1100
1101	module.Module.dexProperties.Optimize.EnabledByDefault = false
1102
1103	module.Module.properties.Instrument = true
1104	module.Module.properties.Supports_static_instrumentation = true
1105	module.Module.properties.Installable = proptools.BoolPtr(true)
1106	module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1107	module.appProperties.AlwaysPackageNativeLibs = true
1108	module.Module.dexpreopter.isTest = true
1109	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
1110
1111	module.addHostAndDeviceProperties()
1112	module.AddProperties(
1113		&module.aaptProperties,
1114		&module.appProperties,
1115		&module.appTestProperties,
1116		&module.overridableAppProperties,
1117		&module.testProperties)
1118
1119	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1120	android.InitDefaultableModule(module)
1121	android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
1122	return module
1123}
1124
1125type appTestHelperAppProperties struct {
1126	// list of compatibility suites (for example "cts", "vts") that the module should be
1127	// installed into.
1128	Test_suites []string `android:"arch_variant"`
1129
1130	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1131	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1132	// explicitly.
1133	Auto_gen_config *bool
1134
1135	// Install the test into a folder named for the module in all test suites.
1136	Per_testcase_directory *bool
1137}
1138
1139type AndroidTestHelperApp struct {
1140	AndroidApp
1141
1142	appTestHelperAppProperties appTestHelperAppProperties
1143}
1144
1145func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1146	return true
1147}
1148
1149// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1150// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1151// test.
1152func AndroidTestHelperAppFactory() android.Module {
1153	module := &AndroidTestHelperApp{}
1154
1155	// TODO(b/192032291): Disable by default after auditing downstream usage.
1156	module.Module.dexProperties.Optimize.EnabledByDefault = true
1157
1158	module.Module.properties.Installable = proptools.BoolPtr(true)
1159	module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1160	module.appProperties.AlwaysPackageNativeLibs = true
1161	module.Module.dexpreopter.isTest = true
1162	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
1163
1164	module.addHostAndDeviceProperties()
1165	module.AddProperties(
1166		&module.aaptProperties,
1167		&module.appProperties,
1168		&module.appTestHelperAppProperties,
1169		&module.overridableAppProperties)
1170
1171	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1172	android.InitDefaultableModule(module)
1173	android.InitApexModule(module)
1174	return module
1175}
1176
1177type AndroidAppCertificate struct {
1178	android.ModuleBase
1179	android.BazelModuleBase
1180
1181	properties  AndroidAppCertificateProperties
1182	Certificate Certificate
1183}
1184
1185type AndroidAppCertificateProperties struct {
1186	// Name of the certificate files.  Extensions .x509.pem and .pk8 will be added to the name.
1187	Certificate *string
1188}
1189
1190// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1191// the signing key.
1192func AndroidAppCertificateFactory() android.Module {
1193	module := &AndroidAppCertificate{}
1194	module.AddProperties(&module.properties)
1195	android.InitAndroidModule(module)
1196	android.InitBazelModule(module)
1197	return module
1198}
1199
1200func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1201	cert := String(c.properties.Certificate)
1202	c.Certificate = Certificate{
1203		Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1204		Key: android.PathForModuleSrc(ctx, cert+".pk8"),
1205	}
1206}
1207
1208type OverrideAndroidApp struct {
1209	android.ModuleBase
1210	android.OverrideModuleBase
1211}
1212
1213func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
1214	// All the overrides happen in the base module.
1215	// TODO(jungjw): Check the base module type.
1216}
1217
1218// override_android_app is used to create an android_app module based on another android_app by overriding
1219// some of its properties.
1220func OverrideAndroidAppModuleFactory() android.Module {
1221	m := &OverrideAndroidApp{}
1222	m.AddProperties(
1223		&OverridableDeviceProperties{},
1224		&overridableAppProperties{},
1225	)
1226
1227	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1228	android.InitOverrideModule(m)
1229	return m
1230}
1231
1232type OverrideAndroidTest struct {
1233	android.ModuleBase
1234	android.OverrideModuleBase
1235}
1236
1237func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) {
1238	// All the overrides happen in the base module.
1239	// TODO(jungjw): Check the base module type.
1240}
1241
1242// override_android_test is used to create an android_app module based on another android_test by overriding
1243// some of its properties.
1244func OverrideAndroidTestModuleFactory() android.Module {
1245	m := &OverrideAndroidTest{}
1246	m.AddProperties(&overridableAppProperties{})
1247	m.AddProperties(&appTestProperties{})
1248
1249	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1250	android.InitOverrideModule(m)
1251	return m
1252}
1253
1254type UsesLibraryProperties struct {
1255	// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
1256	Uses_libs []string
1257
1258	// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1259	// required=false.
1260	Optional_uses_libs []string
1261
1262	// If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file.  Defaults
1263	// to true if either uses_libs or optional_uses_libs is set.  Will unconditionally default to true in the future.
1264	Enforce_uses_libs *bool
1265
1266	// Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1267	// libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1268	// normally is the same as the module name, but there are exceptions.
1269	Provides_uses_lib *string
1270
1271	// A list of shared library names to exclude from the classpath of the APK. Adding a library here
1272	// will prevent it from being used when precompiling the APK and prevent it from being implicitly
1273	// added to the APK's manifest's <uses-library> elements.
1274	//
1275	// Care must be taken when using this as it could result in runtime errors if the APK actually
1276	// uses classes provided by the library and which are not provided in any other way.
1277	//
1278	// This is primarily intended for use by various CTS tests that check the runtime handling of the
1279	// android.test.base shared library (and related libraries) but which depend on some common
1280	// libraries that depend on the android.test.base library. Without this those tests will end up
1281	// with a <uses-library android:name="android.test.base"/> in their manifest which would either
1282	// render the tests worthless (as they would be testing the wrong behavior), or would break the
1283	// test altogether by providing access to classes that the tests were not expecting. Those tests
1284	// provide the android.test.base statically and use jarjar to rename them so they do not collide
1285	// with the classes provided by the android.test.base library.
1286	Exclude_uses_libs []string
1287}
1288
1289// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1290// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1291// uses_libs and optional_uses_libs properties.  The build system's values are used by dexpreopt to preopt apps
1292// with knowledge of their shared libraries.
1293type usesLibrary struct {
1294	usesLibraryProperties UsesLibraryProperties
1295
1296	// Whether to enforce verify_uses_library check.
1297	enforce bool
1298}
1299
1300func (u *usesLibrary) addLib(lib string, optional bool) {
1301	if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) {
1302		if optional {
1303			u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib)
1304		} else {
1305			u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib)
1306		}
1307	}
1308}
1309
1310func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
1311	if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
1312		ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
1313		ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...)
1314		// Only add these extra dependencies if the module is an app that depends on framework
1315		// libs. This avoids creating a cyclic dependency:
1316		//     e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
1317		if addCompatDeps {
1318			// Dexpreopt needs paths to the dex jars of these libraries in order to construct
1319			// class loader context for dex2oat. Add them as a dependency with a special tag.
1320			ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1321			ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1322			ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
1323		}
1324	} else {
1325		ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
1326		ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
1327	}
1328}
1329
1330// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the
1331// build.
1332func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
1333	optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries())
1334	return optionalUsesLibs
1335}
1336
1337// Helper function to replace string in a list.
1338func replaceInList(list []string, oldstr, newstr string) {
1339	for i, str := range list {
1340		if str == oldstr {
1341			list[i] = newstr
1342		}
1343	}
1344}
1345
1346// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1347// host and on device.
1348func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1349	clcMap := make(dexpreopt.ClassLoaderContextMap)
1350
1351	// Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1352	// UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1353	if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1354		return clcMap
1355	}
1356
1357	ctx.VisitDirectDeps(func(m android.Module) {
1358		tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1359		if !isUsesLibTag {
1360			return
1361		}
1362
1363		dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
1364
1365		// Skip stub libraries. A dependency on the implementation library has been added earlier,
1366		// so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1367		// from implementation libraries by their name, which is different as it has a suffix.
1368		if comp, ok := m.(SdkLibraryComponentDependency); ok {
1369			if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1370				return
1371			}
1372		}
1373
1374		if lib, ok := m.(UsesLibraryDependency); ok {
1375			libName := dep
1376			if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
1377				libName = *ulib.ProvidesUsesLib()
1378				// Replace module name with library name in `uses_libs`/`optional_uses_libs` in
1379				// order to pass verify_uses_libraries check (which compares these properties
1380				// against library names written in the manifest).
1381				replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
1382				replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
1383			}
1384			clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
1385				lib.DexJarBuildPath().PathOrNil(), lib.DexJarInstallPath(),
1386				lib.ClassLoaderContexts())
1387		} else if ctx.Config().AllowMissingDependencies() {
1388			ctx.AddMissingDependencies([]string{dep})
1389		} else {
1390			ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1391		}
1392	})
1393	return clcMap
1394}
1395
1396// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1397// properties.  Defaults to true if either of uses_libs or optional_uses_libs is specified.  Will default to true
1398// unconditionally in the future.
1399func (u *usesLibrary) enforceUsesLibraries() bool {
1400	defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
1401		len(u.usesLibraryProperties.Optional_uses_libs) > 0
1402	return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
1403}
1404
1405// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
1406func (u *usesLibrary) freezeEnforceUsesLibraries() {
1407	enforce := u.enforceUsesLibraries()
1408	u.usesLibraryProperties.Enforce_uses_libs = &enforce
1409}
1410
1411// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1412// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1413// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1414// extension: APKs are supposed to end with '.apk').
1415func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
1416	outputFile android.WritablePath) android.Path {
1417
1418	statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
1419
1420	// Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1421	// check is not necessary, and although it is good to have, it is difficult to maintain on
1422	// non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1423	// various unrelated reasons, such as a failure to get manifest from an APK).
1424	global := dexpreopt.GetGlobalConfig(ctx)
1425	if global.DisablePreopt || global.OnlyPreoptBootImageAndSystemServer {
1426		return inputFile
1427	}
1428
1429	rule := android.NewRuleBuilder(pctx, ctx)
1430	cmd := rule.Command().BuiltTool("manifest_check").
1431		Flag("--enforce-uses-libraries").
1432		Input(inputFile).
1433		FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
1434		FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
1435
1436	if outputFile != nil {
1437		cmd.FlagWithOutput("-o ", outputFile)
1438	}
1439
1440	if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1441		cmd.Flag("--enforce-uses-libraries-relax")
1442	}
1443
1444	for _, lib := range u.usesLibraryProperties.Uses_libs {
1445		cmd.FlagWithArg("--uses-library ", lib)
1446	}
1447
1448	for _, lib := range u.usesLibraryProperties.Optional_uses_libs {
1449		cmd.FlagWithArg("--optional-uses-library ", lib)
1450	}
1451
1452	rule.Build("verify_uses_libraries", "verify <uses-library>")
1453	return outputFile
1454}
1455
1456// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1457// the build system and returns the path to a copy of the manifest.
1458func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
1459	outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
1460	return u.verifyUsesLibraries(ctx, manifest, outputFile)
1461}
1462
1463// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1464// system and returns the path to a copy of the APK.
1465func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
1466	u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file
1467	outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
1468	return outputFile
1469}
1470
1471// For Bazel / bp2build
1472
1473type bazelAndroidAppCertificateAttributes struct {
1474	Certificate string
1475}
1476
1477func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
1478	androidAppCertificateBp2Build(ctx, m)
1479}
1480
1481func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) {
1482	var certificate string
1483	if module.properties.Certificate != nil {
1484		certificate = *module.properties.Certificate
1485	}
1486
1487	attrs := &bazelAndroidAppCertificateAttributes{
1488		Certificate: certificate,
1489	}
1490
1491	props := bazel.BazelTargetModuleProperties{
1492		Rule_class:        "android_app_certificate",
1493		Bzl_load_location: "//build/bazel/rules/android:rules.bzl",
1494	}
1495
1496	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
1497}
1498
1499type manifestValueAttribute struct {
1500	MinSdkVersion *string
1501}
1502
1503type bazelAndroidAppAttributes struct {
1504	*javaCommonAttributes
1505	*bazelAapt
1506	Deps             bazel.LabelListAttribute
1507	Custom_package   *string
1508	Certificate      bazel.LabelAttribute
1509	Certificate_name bazel.StringAttribute
1510	Manifest_values  *manifestValueAttribute
1511}
1512
1513// ConvertWithBp2build is used to convert android_app to Bazel.
1514func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
1515	commonAttrs, bp2BuildInfo := a.convertLibraryAttrsBp2Build(ctx)
1516	depLabels := bp2BuildInfo.DepLabels
1517
1518	deps := depLabels.Deps
1519	deps.Append(depLabels.StaticDeps)
1520
1521	aapt := a.convertAaptAttrsWithBp2Build(ctx)
1522
1523	certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate)
1524
1525	manifestValues := &manifestValueAttribute{}
1526	// TODO(b/274474008 ): Directly convert deviceProperties.Min_sdk_version in bp2build
1527	// MinSdkVersion(ctx) calls SdkVersion(ctx) if no value for min_sdk_version is set
1528	minSdkVersion := a.MinSdkVersion(ctx)
1529	if !minSdkVersion.IsPreview() && !minSdkVersion.IsInvalid() {
1530		minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx)
1531		if err == nil {
1532			manifestValues.MinSdkVersion = &minSdkStr
1533		}
1534	}
1535
1536	appAttrs := &bazelAndroidAppAttributes{
1537		// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
1538		Custom_package:   a.overridableAppProperties.Package_name,
1539		Certificate:      certificate,
1540		Certificate_name: certificateName,
1541		Manifest_values:  manifestValues,
1542	}
1543
1544	props := bazel.BazelTargetModuleProperties{
1545		Rule_class:        "android_binary",
1546		Bzl_load_location: "//build/bazel/rules/android:rules.bzl",
1547	}
1548
1549	if !bp2BuildInfo.hasKotlin {
1550		appAttrs.javaCommonAttributes = commonAttrs
1551		appAttrs.bazelAapt = aapt
1552		appAttrs.Deps = deps
1553	} else {
1554		ktName := a.Name() + "_kt"
1555		ctx.CreateBazelTargetModule(
1556			AndroidLibraryBazelTargetModuleProperties(),
1557			android.CommonAttributes{Name: ktName},
1558			&bazelAndroidLibrary{
1559				javaLibraryAttributes: &javaLibraryAttributes{
1560					javaCommonAttributes: commonAttrs,
1561					Deps:                 deps,
1562				},
1563				bazelAapt: aapt,
1564			},
1565		)
1566
1567		appAttrs.bazelAapt = &bazelAapt{Manifest: aapt.Manifest}
1568		appAttrs.Deps = bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + ktName})
1569		appAttrs.javaCommonAttributes = &javaCommonAttributes{
1570			Sdk_version: commonAttrs.Sdk_version,
1571		}
1572	}
1573
1574	ctx.CreateBazelTargetModule(
1575		props,
1576		android.CommonAttributes{Name: a.Name()},
1577		appAttrs,
1578	)
1579
1580}
1581