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