blob: ccc60a4e3fb0d8208aa96842cda56f582213d9af [file] [log] [blame]
Colin Cross30e076a2015-04-13 13:58:27 -07001// 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
Jaewoong Jungf9b44652020-12-21 12:29:12 -080017// This file contains the module implementations for android_app, android_test, and some more
18// related module types, including their override variants.
Colin Cross30e076a2015-04-13 13:58:27 -070019
20import (
Jiakai Zhang4f65a032023-06-01 15:16:58 +010021 "fmt"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070022 "path/filepath"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070023 "strings"
Colin Cross30e076a2015-04-13 13:58:27 -070024
Colin Cross50ddcc42019-05-16 12:28:22 -070025 "github.com/google/blueprint"
Colin Crossa14fb6a2024-10-23 16:57:06 -070026 "github.com/google/blueprint/depset"
Colin Cross50ddcc42019-05-16 12:28:22 -070027 "github.com/google/blueprint/proptools"
28
Colin Cross635c3b02016-05-18 15:37:25 -070029 "android/soong/android"
Colin Crossa4f08812018-10-02 22:03:40 -070030 "android/soong/cc"
Ulya Trafimovichd4bcea42020-06-03 14:57:22 +010031 "android/soong/dexpreopt"
Colin Cross303e21f2018-08-07 16:49:25 -070032 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070033)
34
Colin Cross3bc7ffa2017-11-22 16:19:37 -080035func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000036 RegisterAppBuildComponents(android.InitRegistrationContext)
Andrei Onea580636b2022-08-17 16:53:46 +000037 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080038}
39
Andrei Onea580636b2022-08-17 16:53:46 +000040var (
41 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
42 blueprint.RuleParams{
43 Command: "${ModifyAllowlistCmd} $in $packageName $out",
44 CommandDeps: []string{"${ModifyAllowlistCmd}"},
45 }, "packageName")
46)
47
Jihoon Kang9aef7772024-06-14 23:45:06 +000048type FlagsPackages struct {
49 // Paths to the aconfig dump output text files that are consumed by aapt2
50 AconfigTextFiles android.Paths
51}
52
53var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
54
Paul Duffinf9b1da02019-12-18 19:51:55 +000055func RegisterAppBuildComponents(ctx android.RegistrationContext) {
56 ctx.RegisterModuleType("android_app", AndroidAppFactory)
57 ctx.RegisterModuleType("android_test", AndroidTestFactory)
58 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
59 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
60 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
61 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000062}
63
Colin Cross99939e92024-10-01 16:02:46 -070064type AppInfo struct {
65 // Updatable is set to the value of the updatable property
66 Updatable bool
67
68 // TestHelperApp is true if the module is a android_test_helper_app
69 TestHelperApp bool
Colin Crossb614cd42024-10-11 12:52:21 -070070
71 // EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
72 EmbeddedJNILibs android.Paths
Yu Liu7eebf8b2025-01-17 00:23:57 +000073
74 MergedManifestFile android.Path
Yu Liu0a37d422025-02-13 02:05:00 +000075
76 Prebuilt bool
77 AppSet bool
78 Privileged bool
79 OutputFile android.Path
80 InstallApkName string
81 JacocoReportClassesFile android.Path
82 Certificate Certificate
83 PrivAppAllowlist android.OptionalPath
84 OverriddenManifestPackageName *string
Colin Cross99939e92024-10-01 16:02:46 -070085}
86
87var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
88
Colin Cross30e076a2015-04-13 13:58:27 -070089// AndroidManifest.xml merging
90// package splits
91
Colin Crossfabb6082018-02-20 17:22:23 -080092type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070093 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070094 Additional_certificates []string
95
96 // If set, create package-export.apk, which other packages can
97 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080098 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070099
Colin Cross16056062017-12-13 22:46:28 -0800100 // Specifies that this app should be installed to the priv-app directory,
101 // where the system will grant it additional privileges not available to
102 // normal apps.
103 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -0700104
105 // list of resource labels to generate individual resource packages
106 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -0400107
Colin Crossa4f08812018-10-02 22:03:40 -0700108 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +0000109 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -0700110
Colin Cross7204cf02020-05-06 17:51:39 -0700111 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -0800112 // sdk_version.
113 Jni_uses_platform_apis *bool
114
Colin Cross7204cf02020-05-06 17:51:39 -0700115 // if true, use JNI libraries that link against SDK APIs even if this module does not set
116 // sdk_version.
117 Jni_uses_sdk_apis *bool
118
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700119 // STL library to use for JNI libraries.
120 Stl *string `android:"arch_variant"`
121
Colin Crosse4246ab2019-02-05 21:55:21 -0800122 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900123 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
124 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
125 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
126 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800127 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800128
129 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
130 // they are used from inside the APK at runtime.
131 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700132
Jiyong Parkd044bb42024-05-15 02:09:54 +0900133 // Forces native libraries to always be packaged into the APK,
134 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
135 // True for android_test* modules.
136 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700137
138 // If set, find and merge all NOTICE files that this module and its dependencies have and store
139 // it in the APK as an asset.
140 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700141
142 // cc.Coverage related properties
143 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700144 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100145
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000146 // It can be set to test the behaviour of default target sdk version.
147 // Only required when updatable: false. It is an error if updatable: true and this is false.
148 Enforce_default_target_sdk_version *bool
149
150 // If set, the targetSdkVersion for the target is set to the latest default API level.
151 // This would be by default false, unless updatable: true or
152 // enforce_default_target_sdk_version: true in which case this defaults to true.
153 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
154
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100155 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100156 // additional rules to make sure an app can safely be updated. Default is false.
157 // Prefer using other specific properties if build behaviour must be changed; avoid using this
158 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100159 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000160
161 // Specifies the file that contains the allowlist for this app.
162 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900163
164 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
165 // and install the RRO package to /product partition, instead of passing --product argument
166 // to aapt2. Default is false.
167 // Setting this will make this APK identical to all targets, regardless of
168 // PRODUCT_CHARACTERISTICS.
169 Generate_product_characteristics_rro *bool
170
171 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
172 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700173}
174
Jaewoong Jung525443a2019-02-28 15:35:54 -0800175// android_app properties that can be overridden by override_android_app
176type overridableAppProperties struct {
177 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
178 // or an android_app_certificate module name in the form ":module".
Cole Fausteb9c1482024-11-18 16:49:19 -0800179 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700180
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800181 // Name of the signing certificate lineage file or filegroup module.
182 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700183
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400184 // For overriding the --rotation-min-sdk-version property of apksig
185 RotationMinSdkVersion *string
186
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700187 // the package name of this app. The package name in the manifest file is used if one was not given.
Cole Faust258b96f2024-10-04 10:48:24 -0700188 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800189
190 // the logging parent of this app.
191 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000192
193 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
194 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000195
196 // Names of modules to be overridden. Listed modules can only be other binaries
197 // (in Make or Soong).
198 // This does not completely prevent installation of the overridden binaries, but if both
199 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
200 // from PRODUCT_PACKAGES.
201 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800202}
203
Colin Cross30e076a2015-04-13 13:58:27 -0700204type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700205 Library
206 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800207 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700208
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900209 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700210
Colin Crossfabb6082018-02-20 17:22:23 -0800211 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700212
Jaewoong Jung525443a2019-02-28 15:35:54 -0800213 overridableAppProperties overridableAppProperties
214
Colin Cross403cc152020-07-06 14:15:24 -0700215 jniLibs []jniLib
216 installPathForJNISymbols android.Path
217 embeddedJniLibs bool
218 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700219
220 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800221
222 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
223 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800224
Colin Cross70dda7e2019-10-01 22:05:35 -0700225 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700226
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700227 onDeviceDir string
228
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800229 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700230
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900231 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100232
233 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000234
235 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000236
237 privAppAllowlist android.OptionalPath
Spandan Dasde588a32024-12-03 22:52:24 +0000238
239 requiredModuleNames []string
Colin Crosse1731a52017-12-14 11:22:55 -0800240}
241
Martin Stjernholm6d415272020-01-31 17:10:36 +0000242func (a *AndroidApp) IsInstallable() bool {
243 return Bool(a.properties.Installable)
244}
245
Colin Crossa14fb6a2024-10-23 16:57:06 -0700246func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000247 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700248}
249
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900250func (a *AndroidApp) OutputFile() android.Path {
251 return a.outputFile
252}
253
Colin Cross503c1d02020-01-28 14:00:53 -0800254func (a *AndroidApp) Certificate() Certificate {
255 return a.certificate
256}
257
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700258func (a *AndroidApp) JniCoverageOutputs() android.Paths {
259 return a.jniCoverageOutputs
260}
261
Andrei Onea580636b2022-08-17 16:53:46 +0000262func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
263 return a.privAppAllowlist
264}
265
Colin Crossa97c5d32018-03-28 14:58:31 -0700266var _ AndroidLibraryDependency = (*AndroidApp)(nil)
267
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900268type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800269 Pem, Key android.Path
270 presigned bool
271}
272
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700273var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800274
275func (c Certificate) AndroidMkString() string {
276 if c.presigned {
277 return "PRESIGNED"
278 } else {
279 return c.Pem.String()
280 }
Colin Cross30e076a2015-04-13 13:58:27 -0700281}
282
Colin Cross46c9b8b2017-06-22 16:51:17 -0700283func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900284 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700285 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
286 }
287
Jiyong Parkf1691d22021-03-29 20:11:58 +0900288 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000289 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
290 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100291 if sdkDep.hasFrameworkLibs() {
292 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700293 }
Colin Crossa4f08812018-10-02 22:03:40 -0700294
Jiyong Park92315372021-04-02 08:45:46 +0900295 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700296
297 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
298 ctx.PropertyErrorf("jni_uses_sdk_apis",
299 "can only be set for modules that do not set sdk_version")
300 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
301 ctx.PropertyErrorf("jni_uses_platform_apis",
302 "can only be set for modules that set sdk_version")
303 }
304
Colin Crossa4f08812018-10-02 22:03:40 -0700305 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700306 variation := append(jniTarget.Variations(),
307 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000308
Jiyong Park92d84042024-05-17 22:58:54 +0000309 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
310 // Many factors are considered here.
311 // 1. Basically, the selection follows whether the app has sdk_version set or not.
312 jniUsesSdkVariant := usesSDK
313 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
314 if Bool(a.appProperties.Jni_uses_sdk_apis) {
315 jniUsesSdkVariant = true
316 }
317 if Bool(a.appProperties.Jni_uses_platform_apis) {
318 jniUsesSdkVariant = false
319 }
320 // 3. Then the use of SDK variant is again prohibited for the following cases:
321 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
322 // partition (not only the app) is considered unbudled, there's no need to use the
323 // SDK variant.
324 // 3.2. the app doesn't support embedding the JNI libs
325 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
326 jniUsesSdkVariant = false
327 }
328 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000329 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
330 }
Jiyong Park92d84042024-05-17 22:58:54 +0000331
332 // Use the installable dep tag when the JNIs are not embedded
333 var tag dependencyTag
334 if a.shouldEmbedJnis(ctx) {
335 tag = jniLibTag
336 } else {
337 tag = jniInstallTag
338 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000339 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700340 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000341 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
342 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
343 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700344}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700345
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700346func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800347 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700348 if cert != "" {
349 ctx.AddDependency(ctx.Module(), certificateTag, cert)
350 }
351
Andrei Onea580636b2022-08-17 16:53:46 +0000352 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000353 // There are a few uids that are explicitly considered privileged regardless of their
354 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
355 // but for now, allow it not to be in priv-app.
356 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
357 if !privilegedBecauseOfUid {
358 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
359 }
Andrei Onea580636b2022-08-17 16:53:46 +0000360 }
361
Colin Crossbd01e2a2018-10-04 15:21:03 -0700362 for _, cert := range a.appProperties.Additional_certificates {
363 cert = android.SrcIsModule(cert)
364 if cert != "" {
365 ctx.AddDependency(ctx.Module(), certificateTag, cert)
366 } else {
367 ctx.PropertyErrorf("additional_certificates",
368 `must be names of android_app_certificate modules in the form ":module"`)
369 }
370 }
Colin Cross30e076a2015-04-13 13:58:27 -0700371}
372
Spandan Dasb0410872024-06-25 03:30:03 +0000373// TODO(b/156476221): Remove this allowlist
374var (
375 missingMinSdkVersionMtsAllowlist = []string{
376 "CellBroadcastReceiverGoogleUnitTests",
377 "CellBroadcastReceiverUnitTests",
378 "CtsBatterySavingTestCases",
379 "CtsDeviceAndProfileOwnerApp23",
380 "CtsDeviceAndProfileOwnerApp30",
381 "CtsIntentSenderApp",
382 "CtsJobSchedulerTestCases",
383 "CtsMimeMapTestCases",
384 "CtsTareTestCases",
385 "LibStatsPullTests",
386 "MediaProviderClientTests",
387 "TeleServiceTests",
388 "TestExternalImsServiceApp",
389 "TestSmsRetrieverApp",
390 "TetheringPrivilegedTests",
391 }
392)
393
394func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
395 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
396 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
397 }
398}
399
Jeongik Cha538c0d02019-07-11 15:54:27 +0900400func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000401 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000402 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
403 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700404 packageName := a.overridableAppProperties.Package_name.Get(ctx)
405 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000406 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
407 }
408 a.aapt.manifestValues.applicationId = *applicationId
409 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900410 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700411 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
412 TestOnly: true,
413 })
Yu Liu0a37d422025-02-13 02:05:00 +0000414 appInfo := &AppInfo{
Colin Cross99939e92024-10-01 16:02:46 -0700415 Updatable: Bool(a.appProperties.Updatable),
416 TestHelperApp: true,
Yu Liu0a37d422025-02-13 02:05:00 +0000417 }
418 setCommonAppInfo(appInfo, a)
419 android.SetProvider(ctx, AppInfoProvider, appInfo)
Cole Faust866ab392025-01-23 12:56:20 -0800420
421 moduleInfoJSON := ctx.ModuleInfoJSON()
422 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
423 if len(a.appTestHelperAppProperties.Test_suites) > 0 {
424 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...)
425 } else {
426 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
427 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900428}
429
Colin Cross46c9b8b2017-06-22 16:51:17 -0700430func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100431 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000432 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700433 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000434 a.generateJavaUsedByApex(ctx)
Colin Crossb614cd42024-10-11 12:52:21 -0700435
436 var embeddedJniLibs []android.Path
437
438 if a.embeddedJniLibs {
439 for _, jni := range a.jniLibs {
440 embeddedJniLibs = append(embeddedJniLibs, jni.path)
441 }
442 }
Yu Liu0a37d422025-02-13 02:05:00 +0000443 overriddenName := a.OverriddenManifestPackageName()
444 appInfo := &AppInfo{
445 Updatable: Bool(a.appProperties.Updatable),
446 TestHelperApp: false,
447 EmbeddedJNILibs: embeddedJniLibs,
448 MergedManifestFile: a.mergedManifest,
449 OverriddenManifestPackageName: &overriddenName,
450 }
451 setCommonAppInfo(appInfo, a)
452 android.SetProvider(ctx, AppInfoProvider, appInfo)
Spandan Dasde588a32024-12-03 22:52:24 +0000453
454 a.requiredModuleNames = a.getRequiredModuleNames(ctx)
455}
456
457func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
458 var required []string
459 if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
460 required = []string{a.productCharacteristicsRROPackageName()}
461 }
462 // Install the vendor overlay variant if this app is installed.
463 if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
464 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
465 }
466 // Install the product overlay variant if this app is installed.
467 if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
468 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
469 }
470 return required
Colin Crossae5caf52018-05-22 11:11:52 -0700471}
472
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100473func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100474 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900475 if !a.SdkVersion(ctx).Stable() {
476 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100477 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000478 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100479 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
480 }
Jooyung Han749dc692020-04-15 11:03:39 +0900481
Jiyong Park92315372021-04-02 08:45:46 +0900482 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900483 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000484 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900485 } else {
486 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
487 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000488
489 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
490 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
491 }
492 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
493 if a.deviceProperties.Target_sdk_version == nil {
494 a.SetEnforceDefaultTargetSdkVersion(true)
495 }
496 }
497
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100498 a.checkPlatformAPI(ctx)
499 a.checkSdkVersions(ctx)
500}
501
Jiyong Park970c5242024-05-17 22:58:54 +0000502// Ensures that use_embedded_native_libs are set for apk-in-apex
503func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
504 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
505 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000506 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000507
508 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
509 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
510 }
511}
512
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900513// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
514// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900515func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900516 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
Yu Liufc8d5c12025-01-09 00:19:06 +0000517 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900518 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
519 return
520 }
Yu Liufc8d5c12025-01-09 00:19:06 +0000521 if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
522 panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
523 }
524 commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
525 if !ok {
526 panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
527 }
Jooyung Han652d5b32020-05-20 17:12:13 +0900528 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900529 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
530 // handled properly regardless of sdk finalization.
Yu Liu5d3a2cf2025-02-06 00:25:22 +0000531 ver := ""
532 if !commonInfo.MinSdkVersion.IsPlatform {
533 ver = commonInfo.MinSdkVersion.ApiLevel.String()
534 }
535 jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900536 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Yu Liufc8d5c12025-01-09 00:19:06 +0000537 ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
Yu Liu5d3a2cf2025-02-06 00:25:22 +0000538 ver, minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900539 return
540 }
541
542 })
543}
544
Sasha Smundak6ad77252019-05-01 13:16:22 -0700545// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800546// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700547func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900548 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800549 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900550 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800551 }
552
Jiyong Parkd044bb42024-05-15 02:09:54 +0900553 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
554 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
555 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800556}
557
Colin Cross43f08db2018-11-12 10:13:39 -0800558// Returns whether this module should have the dex file stored uncompressed in the APK.
559func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800560 if Bool(a.appProperties.Use_embedded_dex) {
561 return true
562 }
563
Colin Cross53a87f52019-06-25 13:35:30 -0700564 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
565 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900566 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000567 return true
568 }
569
Colin Cross53a87f52019-06-25 13:35:30 -0700570 if ctx.Config().UnbundledBuild() {
571 return false
572 }
573
Spandan Dase21a8d42024-01-23 23:56:29 +0000574 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700575}
576
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700577func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900578 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000579 Bool(a.appProperties.Updatable) ||
580 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000581}
582
Liz Kammer9f9fd022020-06-18 19:44:06 +0000583func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
584 aaptFlags := []string{"--rename-manifest-package " + packageName}
585 if renameResourcesPackage {
586 // Required to rename the package name in the resources table.
587 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
588 }
589 return aaptFlags
590}
591
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900592func (a *AndroidApp) OverriddenManifestPackageName() string {
593 return a.overriddenManifestPackageName
594}
595
Liz Kammer9f9fd022020-06-18 19:44:06 +0000596func (a *AndroidApp) renameResourcesPackage() bool {
597 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
598}
599
Jihoon Kang9049c272024-03-19 21:57:36 +0000600func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Yu Liu460cf372025-01-10 00:34:06 +0000601 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000602 tag := ctx.OtherModuleDependencyTag(dep)
603 switch tag {
604 case staticLibTag:
605 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
606 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
607 }
608
609 case aconfigDeclarationTag:
610 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
611 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
612 } else {
613 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
614 "flags_packages property, but %s is not aconfig_declarations module type",
615 dep.Name(),
616 )
617 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000618 }
619 })
620
Jihoon Kang9aef7772024-06-14 23:45:06 +0000621 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000622}
623
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800624func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900625 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900626 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900627 usePlatformAPI = true
628 }
629 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000630
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700631 // Ask manifest_fixer to add or update the application element indicating this app has no code.
632 a.aapt.hasNoCode = !a.hasCode(ctx)
633
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800634 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800635
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800636 // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900637 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800638 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900639 characteristics := ctx.Config().ProductAAPTCharacteristics()
640 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
641 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700642 }
643
Dan Willemsen72be5902018-10-24 20:24:57 -0700644 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
645 // Product AAPT config
646 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800647 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700648 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700649
Dan Willemsen72be5902018-10-24 20:24:57 -0700650 // Product AAPT preferred config
651 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800652 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700653 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700654 }
655
Jiyong Park7f67f482019-01-05 12:57:48 +0900656 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700657 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
658 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700659 // The product override variable has a priority over the package_name property.
660 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700661 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700662 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000663 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900664 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900665 }
666
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800667 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
668
Colin Crosse560c4a2019-03-19 16:03:11 -0700669 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800670 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100671 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000672 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
673 a.aapt.defaultManifestVersion = override
674 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000675 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000676 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100677 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000678
Rico Winda2fa2632024-03-13 13:09:17 +0100679 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200680 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000681
682 aconfigTextFilePaths := getAconfigFilePaths(ctx)
683
Alixf7a10272023-09-27 16:47:56 +0000684 a.aapt.buildActions(ctx,
685 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000686 sdkContext: android.SdkContext(a),
687 classLoaderContexts: a.classLoaderContexts,
688 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
689 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100690 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000691 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000692 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000693 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000694 },
695 )
Colin Cross30e076a2015-04-13 13:58:27 -0700696
Colin Cross46c9b8b2017-06-22 16:51:17 -0700697 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700698 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000699
700 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
701 AconfigTextFiles: aconfigTextFilePaths,
702 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800703}
Colin Cross30e076a2015-04-13 13:58:27 -0700704
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800705func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700706 var staticLibProguardFlagFiles android.Paths
Yu Liu80b68c42025-01-15 18:14:34 +0000707 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Colin Cross313aa542023-12-13 13:47:44 -0800708 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400709 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
710 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
711 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700712 }
713 })
714
715 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
716
Colin Cross312634e2023-11-21 15:13:56 -0800717 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200718 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100719 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
720 // live for code references and (transitively) mark these as live.
721 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
722 // dead code alive)
723 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
724 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800725}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800726
Colin Cross403cc152020-07-06 14:15:24 -0700727func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800728 var installDir string
729 if ctx.ModuleName() == "framework-res" {
730 // framework-res.apk is installed as system/framework/framework-res.apk
731 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900732 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800733 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800734 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800735 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800736 }
Colin Cross403cc152020-07-06 14:15:24 -0700737
738 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
739}
740
Yu Liu7eebf8b2025-01-17 00:23:57 +0000741func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) {
Colin Cross403cc152020-07-06 14:15:24 -0700742 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000743 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700744 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100745 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700746 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100747 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700748 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700749 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100750 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700751 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800752 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700753
Rico Wind98e7fa82023-11-27 09:44:03 +0100754 var packageResources = a.exportPackage
755
Yu Liu460cf372025-01-10 00:34:06 +0000756 javaInfo := &JavaInfo{}
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800757 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200758 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100759 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
760 aapt2Convert(ctx, protoFile, packageResources, "proto")
761 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
762 }
763
Colin Cross4eae06d2023-06-20 22:40:02 -0700764 var extraSrcJars android.Paths
765 var extraClasspathJars android.Paths
766 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800767 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700768 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
769 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
770 // classpath when compiling everything else, and add it to the final classes jar.
771 extraClasspathJars = android.Paths{a.aapt.rJar}
772 extraCombinedJars = android.Paths{a.aapt.rJar}
773 } else {
774 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
775 // R.java files for the app's package and the packages from all transitive static android_library
776 // dependencies. Compile the srcjar alongside the rest of the sources.
777 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
778 }
779
Yu Liu460cf372025-01-10 00:34:06 +0000780 javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200781 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100782 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
783 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
784 packageResources = binaryResources
785 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800786 }
Colin Cross30e076a2015-04-13 13:58:27 -0700787
Yu Liu7eebf8b2025-01-17 00:23:57 +0000788 return a.dexJarFile.PathOrNil(), packageResources, javaInfo
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800789}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800790
Sam Delmerico82602492022-06-10 17:05:42 +0000791func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700792 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000793 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700794 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700795 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700796 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800797 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000798 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700799 for _, jni := range jniLibs {
800 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700801 // Only collect coverage for the first target arch if this is a multilib target.
802 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
803 // data file path collisions since the current coverage file path format doesn't contain
804 // arch-related strings. This is fine for now though; the code coverage team doesn't use
805 // multi-arch targets such as test_suite_* for coverage collections yet.
806 //
807 // Work with the team to come up with a new format that handles multilib modules properly
808 // and change this.
809 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700810 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700811 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
812 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700813 }
814 }
Colin Cross403cc152020-07-06 14:15:24 -0700815 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700816 }
817 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800818 return jniJarFile
819}
Colin Crossa4f08812018-10-02 22:03:40 -0700820
Colin Cross403cc152020-07-06 14:15:24 -0700821func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
822 var jniSymbols android.RuleBuilderInstalls
823 for _, jniLib := range a.jniLibs {
824 if jniLib.unstrippedFile != nil {
825 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
826 From: jniLib.unstrippedFile,
827 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
828 })
829 }
830 }
831 return jniSymbols
832}
833
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700834// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
835// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700836func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
837 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700838 if android.SrcIsModule(certPropValue) == "" {
839 var mainCert Certificate
840 if certPropValue != "" {
841 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
842 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800843 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
844 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700845 }
846 } else {
847 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800848 mainCert = Certificate{
849 Pem: pem,
850 Key: key,
851 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700852 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700853 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700854 }
855
Colin Crossbc2c8a72022-09-14 12:45:42 -0700856 if len(certificates) > 0 {
857 mainCertificate = certificates[0]
858 } else {
859 // This can be reached with an empty certificate list if AllowMissingDependencies is set
860 // and the certificate property for this module is a module reference to a missing module.
861 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
862 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
863 }
864 // Set a certificate to avoid panics later when accessing it.
865 mainCertificate = Certificate{
866 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000867 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700868 }
869 }
870
Zyan Wub7550aa2023-05-18 15:46:31 +0800871 if !m.Platform() {
872 certPath := mainCertificate.Pem.String()
873 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
874 if strings.HasPrefix(certPath, systemCertPath) {
875 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
876 allowed := ctx.Config().EnforceSystemCertificateAllowList()
877
878 if enforceSystemCert && !inList(m.Name(), allowed) {
879 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
880 }
881 }
882 }
883
Colin Crossbc2c8a72022-09-14 12:45:42 -0700884 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800885}
886
Jooyung Han39ee1192020-03-23 20:21:11 +0900887func (a *AndroidApp) InstallApkName() string {
888 return a.installApkName
889}
890
Sam Delmerico15809f82023-05-15 17:21:47 -0400891func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000892 if a.appProperties.Privapp_allowlist == nil {
893 return nil
894 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400895
896 isOverrideApp := a.GetOverriddenBy() != ""
897 if !isOverrideApp {
898 // if this is not an override, we don't need to rewrite the existing privapp allowlist
899 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
900 }
901
Cole Faust258b96f2024-10-04 10:48:24 -0700902 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
903 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000904 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
905 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400906
Cole Faust258b96f2024-10-04 10:48:24 -0700907 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000908 fileName := "privapp_allowlist_" + packageName + ".xml"
Cole Faust4e9f5922024-11-13 16:09:23 -0800909 outPath := android.PathForModuleOut(ctx, fileName)
Andrei Onea580636b2022-08-17 16:53:46 +0000910 ctx.Build(pctx, android.BuildParams{
911 Rule: modifyAllowlist,
912 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
913 Output: outPath,
914 Args: map[string]string{
915 "packageName": packageName,
916 },
917 })
Cole Faust4e9f5922024-11-13 16:09:23 -0800918 return outPath
Andrei Onea580636b2022-08-17 16:53:46 +0000919}
920
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800921func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700922 var apkDeps android.Paths
923
Colin Crossff694a82023-12-13 15:54:49 -0800924 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
925 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700926 a.hideApexVariantFromMake = true
927 }
928
Jeongik Cha538c0d02019-07-11 15:54:27 +0900929 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
930 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
931
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000932 // Unlike installApkName, a.stem should respect base module name for override_android_app.
933 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000934 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000935
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800936 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000937 // Both android_app and override_android_app module are expected to possess
938 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
939 // from the base module. Therefore, use a.Name() which represents
940 // the module name for both android_app and override_android_app.
941 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000942 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800943
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700944 if ctx.ModuleName() == "framework-res" {
945 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700946 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900947 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700948 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
949 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800950 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700951 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700952 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700953 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700954 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700955
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100956 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000957 if a.usesLibrary.shouldDisableDexpreopt {
958 a.dexpreopter.disableDexpreopt()
959 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000960
Colin Cross61fb62e2022-06-23 10:46:28 -0700961 var noticeAssetPath android.WritablePath
962 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
963 // The rule to create the notice file can't be generated yet, as the final output path
964 // for the apk isn't known yet. Add the path where the notice file will be generated to the
965 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
966 // be generated later.
967 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
968 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
969 }
970
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000971 // For apps targeting latest target_sdk_version
972 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
973 a.SetEnforceDefaultTargetSdkVersion(true)
974 }
975
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800976 // Process all building blocks, from AAPT to certificates.
977 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100978 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700979 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100980
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100981 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700982 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000983 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
984 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700985 apkDeps = append(apkDeps, manifestCheckFile)
986 }
987
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800988 a.proguardBuildActions(ctx)
989
Colin Cross014489c2020-06-02 20:09:13 -0700990 a.linter.mergedManifest = a.aapt.mergedManifestFile
991 a.linter.manifest = a.aapt.manifestPath
992 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700993 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700994
Yu Liu7eebf8b2025-01-17 00:23:57 +0000995 dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800996
Jiyong Park92d84042024-05-17 22:58:54 +0000997 // No need to check the SDK version of the JNI deps unless we embed them
998 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
999 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +00001000 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001001
1002 if ctx.Failed() {
1003 return
1004 }
1005
Colin Crossbc2c8a72022-09-14 12:45:42 -07001006 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001007
1008 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -08001009 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001010 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
1011 var v4SignatureFile android.WritablePath = nil
1012 if v4SigningRequested {
1013 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
1014 }
Liz Kammere2b27f42020-05-07 13:24:05 -07001015 var lineageFile android.Path
1016 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
1017 lineageFile = android.PathForModuleSrc(ctx, lineage)
1018 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04001019 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
1020
Rico Wind98e7fa82023-11-27 09:44:03 +01001021 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001022 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -07001023 if v4SigningRequested {
1024 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1025 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001026
Colin Cross61fb62e2022-06-23 10:46:28 -07001027 if a.aapt.noticeFile.Valid() {
1028 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -07001029 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -07001030 android.BuildNoticeHtmlOutputFromLicenseMetadata(
1031 ctx, noticeFile, "", "",
1032 []string{
1033 a.installDir.String() + "/",
1034 android.PathForModuleInstall(ctx).String() + "/",
1035 a.outputFile.String(),
1036 })
Bob Badoureef4c1c2022-05-16 12:20:04 -07001037 builder := android.NewRuleBuilder(pctx, ctx)
1038 builder.Command().Text("cp").
1039 Input(noticeFile).
1040 Output(noticeAssetPath)
1041 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -07001042 }
1043
Colin Crosse560c4a2019-03-19 16:03:11 -07001044 for _, split := range a.aapt.splits {
1045 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -08001046 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001047 if v4SigningRequested {
1048 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
1049 }
Rico Wind98e7fa82023-11-27 09:44:03 +01001050 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -07001051 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -07001052 if v4SigningRequested {
1053 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1054 }
Colin Crosse560c4a2019-03-19 16:03:11 -07001055 }
1056
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001057 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -07001058 bundleFile := android.PathForModuleOut(ctx, "base.zip")
1059 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1060 a.bundleFile = bundleFile
1061
Andrei Onea580636b2022-08-17 16:53:46 +00001062 allowlist := a.createPrivappAllowlist(ctx)
1063 if allowlist != nil {
1064 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1065 }
1066
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001067 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001068 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1069 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001070 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001071 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1072 allowlistInstallFilename := a.installApkName + ".xml"
1073 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001074 }
1075
Colin Cross09ad3a62023-11-15 12:29:33 -08001076 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001077 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001078 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1079 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001080 }
Jiyong Park25b92222024-05-17 22:58:54 +00001081 // If we don't embed jni libs, make sure that those are installed along with the
1082 // app, and also place symlinks to the installed paths under the lib/<arch>
1083 // directory of the app installation directory. ex:
1084 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1085 if !a.embeddedJniLibs {
1086 for _, jniLib := range jniLibs {
1087 archStr := jniLib.target.Arch.ArchType.String()
1088 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1089 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001090 // install the symlink itself
1091 symlinkName := installedLib.Base()
1092 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1093 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1094 }
1095 }
1096 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001097 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001098 }
Artur Satayev1111b842020-04-27 19:05:28 +01001099
Colin Crossa6182ab2024-08-21 10:47:44 -07001100 ctx.CheckbuildFile(a.outputFile)
1101
Artur Satayev1111b842020-04-27 19:05:28 +01001102 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001103
1104 providePrebuiltInfo(ctx,
1105 prebuiltInfoProps{
1106 baseModuleName: a.BaseModuleName(),
1107 isPrebuilt: false,
1108 },
1109 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001110
Yu Liu7eebf8b2025-01-17 00:23:57 +00001111 if javaInfo != nil {
1112 javaInfo.OutputFile = a.outputFile
1113 setExtraJavaInfo(ctx, a, javaInfo)
1114 android.SetProvider(ctx, JavaInfoProvider, javaInfo)
1115 }
1116
Cole Faust866ab392025-01-23 12:56:20 -08001117 moduleInfoJSON := ctx.ModuleInfoJSON()
1118 moduleInfoJSON.Class = []string{"APPS"}
1119 if !a.embeddedJniLibs {
1120 for _, jniLib := range a.jniLibs {
1121 moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name)
1122 }
1123 }
1124
mrziwang9f7b9f42024-07-10 12:18:06 -07001125 a.setOutputFiles(ctx)
Wei Li986fe742025-01-30 15:14:42 -08001126
1127 buildComplianceMetadata(ctx)
mrziwang9f7b9f42024-07-10 12:18:06 -07001128}
1129
1130func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1131 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1132 if a.aaptSrcJar != nil {
1133 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1134 }
1135 if a.rJar != nil {
1136 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1137 }
1138 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1139 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1140 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1141 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001142}
1143
Colin Crossc2d24052020-05-13 11:05:02 -07001144type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001145 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001146 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001147 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1148}
1149
1150func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1151 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001152 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001153
Colin Crossc2d24052020-05-13 11:05:02 -07001154 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001155 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1156 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001157 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001158 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
Yu Liuf6f85492025-01-13 21:02:36 +00001159 checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool {
Spandan Das10c41362024-12-03 01:33:09 +00001160 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
Yu Liuf6f85492025-01-13 21:02:36 +00001161 childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
1162 parentIsLinkable := false
1163 if ctx.EqualModules(ctx.Module(), parent) {
1164 parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
1165 parentIsLinkable = parentLinkable != nil
1166 } else {
1167 _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider)
1168 }
1169 useStubsOfDep := childLinkable.IsStubs
1170 if apkInApex && parentIsLinkable {
Spandan Das10c41362024-12-03 01:33:09 +00001171 // APK-in-APEX
1172 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
Yu Liuf6f85492025-01-13 21:02:36 +00001173 useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child))
Spandan Das10c41362024-12-03 01:33:09 +00001174 }
Yu Liuf6f85492025-01-13 21:02:36 +00001175 return !childLinkable.IsNdk && !useStubsOfDep
Spandan Das10c41362024-12-03 01:33:09 +00001176 })
Makoto Onuki2ca84272024-02-10 00:15:21 +00001177
1178 var certificates []Certificate
1179
Colin Crossb614cd42024-10-11 12:52:21 -07001180 var directImplementationDeps android.Paths
1181 var transitiveImplementationDeps []depset.DepSet[android.Path]
Yu Liu728da7c2025-01-11 00:54:32 +00001182 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001183 otherName := ctx.OtherModuleName(module)
1184 tag := ctx.OtherModuleDependencyTag(module)
1185
1186 if tag == certificateTag {
Yu Liu728da7c2025-01-11 00:54:32 +00001187 if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001188 certificates = append(certificates, dep.Certificate)
1189 } else {
1190 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1191 }
1192 }
Colin Crossb614cd42024-10-11 12:52:21 -07001193
1194 if IsJniDepTag(tag) {
1195 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1196 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1197 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1198 }
1199 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001200 })
Colin Crossb614cd42024-10-11 12:52:21 -07001201 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1202 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1203 })
1204
Makoto Onuki2ca84272024-02-10 00:15:21 +00001205 return jniLib, prebuiltJniPackages, certificates
1206}
1207
1208func collectJniDeps(ctx android.ModuleContext,
1209 shouldCollectRecursiveNativeDeps bool,
1210 checkNativeSdkVersion bool,
Yu Liuf6f85492025-01-13 21:02:36 +00001211 filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001212 var jniLibs []jniLib
1213 var prebuiltJniPackages android.Paths
1214 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001215
Yu Liuf6f85492025-01-13 21:02:36 +00001216 ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
Yu Liub732c842025-01-16 00:15:54 +00001217 if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
1218 return false
1219 }
Colin Crossa4f08812018-10-02 22:03:40 -07001220 otherName := ctx.OtherModuleName(module)
1221 tag := ctx.OtherModuleDependencyTag(module)
1222
Colin Crossf0913fb2020-07-29 12:59:39 -07001223 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Yu Liuf6f85492025-01-13 21:02:36 +00001224 if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
Spandan Das10c41362024-12-03 01:33:09 +00001225 if filter != nil && !filter(parent, module) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001226 return false
1227 }
1228
Yu Liuf6f85492025-01-13 21:02:36 +00001229 lib := dep.OutputFile
Colin Crossa4f08812018-10-02 22:03:40 -07001230 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001231 path := lib.Path()
1232 if seenModulePaths[path.String()] {
1233 return false
1234 }
1235 seenModulePaths[path.String()] = true
1236
Yu Liuf6f85492025-01-13 21:02:36 +00001237 commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
1238 if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
Cole Faust64cb7c92021-09-14 17:32:49 -07001239 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1240 otherName)
1241 }
1242
Colin Crossa4f08812018-10-02 22:03:40 -07001243 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001244 name: ctx.OtherModuleName(module),
1245 path: path,
Yu Liuf6f85492025-01-13 21:02:36 +00001246 target: commonInfo.Target,
1247 coverageFile: dep.CoverageOutputFile,
1248 unstrippedFile: dep.UnstrippedOutputFile,
1249 partition: dep.Partition,
1250 installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001251 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001252 } else if ctx.Config().AllowMissingDependencies() {
1253 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001254 } else {
1255 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1256 }
1257 } else {
1258 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001259 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001260
1261 return shouldCollectRecursiveNativeDeps
1262 }
1263
Colin Cross313aa542023-12-13 13:47:44 -08001264 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001265 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1266 }
1267
Peter Collingbournead84f972019-12-17 16:46:18 -08001268 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001269 })
1270
Makoto Onuki2ca84272024-02-10 00:15:21 +00001271 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001272}
1273
Colin Cross8bf14fc2024-09-25 16:41:31 -07001274func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001275 ctx.WalkDeps(func(child, parent android.Module) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001276 // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
1277 // heuristics to every transitive dependency, when it should probably be using the heuristics of the
1278 // immediate parent.
Yu Liuf1806032025-02-07 00:23:34 +00001279 isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
Artur Satayev1111b842020-04-27 19:05:28 +01001280 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001281 if !do(ctx, parent, am, isExternal) {
1282 return false
1283 }
Artur Satayev1111b842020-04-27 19:05:28 +01001284 }
1285 return !isExternal
1286 })
1287}
1288
1289func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1290 if ctx.Host() {
1291 return
1292 }
1293
1294 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross9cf55a52024-12-05 14:26:03 -08001295 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001296 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001297
1298 // Skip dependencies that are only available to APEXes; they are developed with updatability
1299 // in mind and don't need manual approval.
Yu Liudf0b8392025-02-12 18:27:03 +00001300 if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoKey).NotAvailableForPlatform {
Artur Satayev533b98c2021-03-11 18:03:42 +00001301 return true
1302 }
1303
Artur Satayev1111b842020-04-27 19:05:28 +01001304 if info, exist := depsInfo[depName]; exist {
1305 info.From = append(info.From, from.Name())
1306 info.IsExternal = info.IsExternal && externalDep
1307 depsInfo[depName] = info
1308 } else {
1309 toMinSdkVersion := "(no version)"
Yu Liudf0b8392025-02-12 18:27:03 +00001310 if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok &&
1311 !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
1312 toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001313 }
1314 depsInfo[depName] = android.ApexModuleDepInfo{
1315 To: depName,
1316 From: []string{from.Name()},
1317 IsExternal: externalDep,
1318 MinSdkVersion: toMinSdkVersion,
1319 }
1320 }
Jooyung Han749dc692020-04-15 11:03:39 +09001321 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001322 })
1323
Jiyong Park92315372021-04-02 08:45:46 +09001324 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001325}
1326
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001327func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1328 return a.appProperties.EnforceDefaultTargetSdkVersion
1329}
1330
1331func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1332 a.appProperties.EnforceDefaultTargetSdkVersion = val
1333}
1334
Artur Satayev849f8442020-04-28 14:57:42 +01001335func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001336 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001337}
1338
Colin Cross0ea8ba82019-06-06 14:33:29 -07001339func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001340 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1341 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001342 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001343 }
Cole Fausteb9c1482024-11-18 16:49:19 -08001344 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001345}
1346
Yu Liuf1806032025-02-07 00:23:34 +00001347func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker {
1348 return AppDepInSameApexChecker{}
1349}
1350
1351type AppDepInSameApexChecker struct {
1352 android.BaseDepInSameApexChecker
1353}
1354
1355func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001356 if IsJniDepTag(tag) {
Jiyong Park0f80c182020-01-31 02:49:53 +09001357 return true
1358 }
Yu Liuf1806032025-02-07 00:23:34 +00001359 return depIsInSameApex(tag)
Jiyong Park0f80c182020-01-31 02:49:53 +09001360}
1361
Jiyong Parkf7487312019-10-17 12:54:30 +09001362func (a *AndroidApp) Privileged() bool {
1363 return Bool(a.appProperties.Privileged)
1364}
1365
Colin Crosse1a85552024-06-14 12:17:37 -07001366func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001367 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001368}
1369
Ivan Lozanod7586b62021-04-01 09:49:36 -04001370func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001371 a.appProperties.PreventInstall = true
1372}
1373
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001374func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1375 a.appProperties.IsCoverageVariant = coverage
1376}
1377
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001378func (a *AndroidApp) EnableCoverageIfNeeded() {}
1379
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001380var _ cc.Coverage = (*AndroidApp)(nil)
1381
Cole Faustb36d31d2024-08-27 16:04:28 -07001382func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1383 a.Library.IDEInfo(ctx, dpInfo)
1384 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001385}
1386
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001387func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1388 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1389}
1390
1391func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1392 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1393}
1394
Colin Cross1b16b0e2019-02-12 14:41:32 -08001395// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001396func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001397 module := &AndroidApp{}
1398
Liz Kammera7a64f32020-07-09 15:16:41 -07001399 module.Module.dexProperties.Optimize.EnabledByDefault = true
1400 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001401 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001402
Colin Crossae5caf52018-05-22 11:11:52 -07001403 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001404 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001405 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001406
Colin Crossce6734e2020-06-15 16:09:53 -07001407 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001408 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001409 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001410 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001411 &module.overridableAppProperties,
1412 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001413
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001414 module.usesLibrary.enforce = true
1415
Colin Crossa4f08812018-10-02 22:03:40 -07001416 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1417 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001418 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001419 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001420
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001421 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1422 a := ctx.Module().(*AndroidApp)
1423
1424 characteristics := ctx.Config().ProductAAPTCharacteristics()
1425 if characteristics == "default" || characteristics == "" {
1426 module.appProperties.Generate_product_characteristics_rro = nil
1427 // no need to create RRO
1428 return
1429 }
1430
1431 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1432 return
1433 }
1434
1435 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1436 rroManifestName := rroPackageName + "_manifest"
1437
1438 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1439 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1440
1441 rroManifestProperties := struct {
1442 Name *string
1443 Tools []string
1444 Out []string
1445 Srcs []string
1446 Cmd *string
1447 }{
1448 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001449 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001450 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001451 Srcs: []string{":" + a.Name() + "{.apk}"},
1452 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001453 }
Cole Fauste19d3352024-10-17 10:30:57 -07001454 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001455
1456 rroProperties := struct {
1457 Name *string
1458 Filter_product *string
1459 Aaptflags []string
1460 Manifest *string
Cole Faust5b989772024-11-06 11:03:16 -08001461 Resource_dirs proptools.Configurable[[]string]
Jihoon Kangf62f4222024-10-21 23:06:41 +00001462 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001463 }{
1464 Name: proptools.StringPtr(rroPackageName),
1465 Filter_product: proptools.StringPtr(characteristics),
1466 Aaptflags: []string{"--auto-add-overlay"},
1467 Manifest: proptools.StringPtr(":" + rroManifestName),
1468 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001469 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001470 }
优秀d75e9982024-05-09 07:15:55 +00001471 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1472 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1473 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1474 }
1475 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001476 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
Spandan Dasde588a32024-12-03 22:52:24 +00001477
1478 })
1479
1480 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1481 createInternalRuntimeOverlays(ctx, module.ModuleBase)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001482 })
1483
Colin Cross36242852017-06-23 15:06:31 -07001484 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001485}
Colin Crossae5caf52018-05-22 11:11:52 -07001486
Spandan Das71be42d2024-11-20 18:34:16 +00001487func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1488 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1489}
1490
Spandan Dasde588a32024-12-03 22:52:24 +00001491type createModuleContext interface {
1492 android.EarlyModuleContext
1493 CreateModule(android.ModuleFactory, ...interface{}) android.Module
1494}
1495
1496func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
1497 if !ctx.Config().HasDeviceProduct() {
1498 return
1499 }
1500 // vendor
1501 vendorOverlayProps := struct {
1502 Name *string
1503 Base *string
1504 Vendor *bool
1505 Product_specific *bool
1506 System_ext_specific *bool
1507 Manifest *string
1508 Sdk_version *string
1509 Compile_multilib *string
1510 Enabled proptools.Configurable[bool]
1511 }{
1512 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")),
1513 Base: proptools.StringPtr(a.Name()),
1514 Vendor: proptools.BoolPtr(true),
1515 Product_specific: proptools.BoolPtr(false),
1516 System_ext_specific: proptools.BoolPtr(false),
1517 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1518 Sdk_version: proptools.StringPtr("current"),
1519 Compile_multilib: proptools.StringPtr("first"),
1520 Enabled: a.EnabledProperty().Clone(),
1521 }
1522 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
1523
1524 // product
1525 productOverlayProps := struct {
1526 Name *string
1527 Base *string
1528 Vendor *bool
1529 Proprietary *bool
1530 Soc_specific *bool
1531 Product_specific *bool
1532 System_ext_specific *bool
1533 Manifest *string
1534 Sdk_version *string
1535 Compile_multilib *string
1536 Enabled proptools.Configurable[bool]
1537 }{
1538 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
1539 Base: proptools.StringPtr(a.Name()),
1540 Vendor: proptools.BoolPtr(false),
1541 Proprietary: proptools.BoolPtr(false),
1542 Soc_specific: proptools.BoolPtr(false),
1543 Product_specific: proptools.BoolPtr(true),
1544 System_ext_specific: proptools.BoolPtr(false),
1545 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1546 Sdk_version: proptools.StringPtr("current"),
1547 Compile_multilib: proptools.StringPtr("first"),
1548 Enabled: a.EnabledProperty().Clone(),
1549 }
1550 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
1551}
1552
Alix96ea88452023-08-31 15:48:23 +00001553// A dictionary of values to be overridden in the manifest.
1554type Manifest_values struct {
1555 // Overrides the value of package_name in the manifest
1556 ApplicationId *string
1557}
1558
Colin Crossae5caf52018-05-22 11:11:52 -07001559type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001560 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001561 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001562
Seth Moorec6f4b532023-02-02 13:22:26 -08001563 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001564 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001565
1566 // If specified, the mainline module package name in the test config is overwritten by it.
1567 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001568
1569 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001570}
1571
1572type AndroidTest struct {
1573 AndroidApp
1574
1575 appTestProperties appTestProperties
1576
1577 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001578
Dan Shi95d19422020-08-15 12:24:26 -07001579 testConfig android.Path
1580 extraTestConfigs android.Paths
1581 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001582}
1583
Jaewoong Jung0949f312019-09-11 10:25:18 -07001584func (a *AndroidTest) InstallInTestcases() bool {
1585 return true
1586}
1587
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001588type androidTestApp interface {
1589 includedInTestSuite(searchPrefix string) bool
1590}
1591
1592func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1593 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1594}
1595
1596func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1597 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1598}
1599
Colin Crossae5caf52018-05-22 11:11:52 -07001600func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001601 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001602 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001603 if a.appTestProperties.Instrumentation_target_package != nil {
1604 a.additionalAaptFlags = append(a.additionalAaptFlags,
1605 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1606 } else if a.appTestProperties.Instrumentation_for != nil {
1607 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001608 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1609 if overridden {
1610 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1611 }
1612 }
Alix96ea88452023-08-31 15:48:23 +00001613 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1614 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001615 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1616 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001617 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1618 }
1619 a.aapt.manifestValues.applicationId = *applicationId
1620 }
Colin Crossae5caf52018-05-22 11:11:52 -07001621 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001622
Jiyong Parkf528b702024-12-30 16:01:58 +09001623 for _, c := range a.testProperties.Test_options.Tradefed_options {
1624 configs = append(configs, c)
1625 }
easoncylee5bcff5d2020-04-30 14:57:06 +08001626 for _, module := range a.testProperties.Test_mainline_modules {
1627 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1628 }
1629
Jaewoong Jung39982342020-01-14 10:27:18 -08001630 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001631 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1632 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001633 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001634 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001635 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001636 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1637 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001638 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001639
Spandan Dasa65d1e02025-01-28 19:34:04 +00001640 // Install test deps
1641 if !ctx.Config().KatiEnabled() {
1642 pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name())
1643 if a.testConfig != nil {
1644 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig)
1645 }
1646 testDeps := append(a.data, a.extraTestConfigs...)
1647 for _, data := range android.SortedUniquePaths(testDeps) {
1648 dataPath := android.DataPath{SrcPath: data}
1649 ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
1650 }
1651 }
1652
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001653 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001654 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001655 OutputFile: a.OutputFile(),
1656 TestConfig: a.testConfig,
1657 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001658 TestSuites: a.testProperties.Test_suites,
1659 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001660 LocalCertificate: a.certificate.AndroidMkString(),
1661 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001662 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1663 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001664 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001665 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1666 TestOnly: true,
1667 TopLevelTarget: true,
1668 })
1669
Cole Faust866ab392025-01-23 12:56:20 -08001670 moduleInfoJSON := ctx.ModuleInfoJSON()
1671 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
1672 if a.testConfig != nil {
1673 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String())
1674 }
1675 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...)
1676 if len(a.testProperties.Test_suites) > 0 {
1677 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...)
1678 } else {
1679 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
1680 }
1681
1682 if _, ok := testConfig.(android.WritablePath); ok {
1683 moduleInfoJSON.AutoTestConfig = []string{"true"}
1684 }
1685 moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
Colin Cross303e21f2018-08-07 16:49:25 -07001686}
1687
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001688func testcaseRel(paths android.Paths) []string {
1689 relPaths := []string{}
1690 for _, p := range paths {
1691 relPaths = append(relPaths, p.Rel())
1692 }
1693 return relPaths
1694}
1695
Jaewoong Jung39982342020-01-14 10:27:18 -08001696func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1697 if testConfig == nil {
1698 return nil
1699 }
1700
1701 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001702 rule := android.NewRuleBuilder(pctx, ctx)
1703 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001704 fixNeeded := false
1705
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001706 // Auto-generated test config uses `ModuleName` as the APK name. So fix it if it is not the case.
Jaewoong Jung39982342020-01-14 10:27:18 -08001707 if ctx.ModuleName() != a.installApkName {
1708 fixNeeded = true
1709 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1710 }
1711
Cole Faust258b96f2024-10-04 10:48:24 -07001712 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1713 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001714 fixNeeded = true
1715 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001716 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001717 }
1718
Seth Moorec6f4b532023-02-02 13:22:26 -08001719 if a.appTestProperties.Mainline_package_name != nil {
1720 fixNeeded = true
1721 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1722 }
1723
Jaewoong Jung39982342020-01-14 10:27:18 -08001724 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001725 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001726 return fixedConfig
1727 }
1728 return testConfig
1729}
1730
Yihan Dong8be09c22024-08-29 15:32:13 +08001731func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1732 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1733 // Instrument the android_test_helper target to log potential API calls at the run time.
1734 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1735 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1736 a.setApiMapper(true)
1737 }
1738 a.AndroidApp.DepsMutator(ctx)
1739}
1740
Colin Cross303e21f2018-08-07 16:49:25 -07001741func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001742 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1743 // Instrument the android_test_helper target to log potential API calls at the run time.
1744 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1745 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1746 a.setApiMapper(true)
1747 }
Colin Cross303e21f2018-08-07 16:49:25 -07001748 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001749}
1750
1751func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1752 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001753 if a.appTestProperties.Instrumentation_for != nil {
1754 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1755 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1756 // use instrumentationForTag instead of libTag.
1757 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1758 }
Colin Crossae5caf52018-05-22 11:11:52 -07001759}
1760
Colin Cross1b16b0e2019-02-12 14:41:32 -08001761// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1762// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001763func AndroidTestFactory() android.Module {
1764 module := &AndroidTest{}
1765
Jared Duke63a3da92022-06-02 19:11:14 +00001766 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001767
1768 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001769 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001770 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001771 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1772 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001773 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001774 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001775
Colin Crossce6734e2020-06-15 16:09:53 -07001776 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001777 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001778 &module.aaptProperties,
1779 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001780 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001781 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001782 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001783
Colin Crossa4f08812018-10-02 22:03:40 -07001784 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1785 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001786 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001787
Colin Crossae5caf52018-05-22 11:11:52 -07001788 return module
1789}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001790
Colin Cross252fc6f2018-10-04 15:22:03 -07001791type appTestHelperAppProperties struct {
1792 // list of compatibility suites (for example "cts", "vts") that the module should be
1793 // installed into.
1794 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001795
1796 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1797 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1798 // explicitly.
1799 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001800
1801 // Install the test into a folder named for the module in all test suites.
1802 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001803
1804 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001805}
1806
1807type AndroidTestHelperApp struct {
1808 AndroidApp
1809
1810 appTestHelperAppProperties appTestHelperAppProperties
1811}
1812
Jaewoong Jung326a9412019-11-21 10:41:00 -08001813func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1814 return true
1815}
1816
Colin Cross1b16b0e2019-02-12 14:41:32 -08001817// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1818// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1819// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001820func AndroidTestHelperAppFactory() android.Module {
1821 module := &AndroidTestHelperApp{}
1822
Jared Duke63a3da92022-06-02 19:11:14 +00001823 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001824 module.Module.dexProperties.Optimize.EnabledByDefault = true
Christoffer Adamsenc8fd1f12025-01-06 19:04:03 +01001825 module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
1826 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross252fc6f2018-10-04 15:22:03 -07001827
1828 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001829 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1830 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001831 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001832 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001833
Colin Crossce6734e2020-06-15 16:09:53 -07001834 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001835 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001836 &module.aaptProperties,
1837 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001838 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001839 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001840
1841 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1842 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001843 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001844 return module
1845}
1846
Colin Crossbd01e2a2018-10-04 15:21:03 -07001847type AndroidAppCertificate struct {
1848 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001849
Colin Crossbd01e2a2018-10-04 15:21:03 -07001850 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001851 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001852}
1853
1854type AndroidAppCertificateProperties struct {
1855 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1856 Certificate *string
1857}
1858
Yu Liu728da7c2025-01-11 00:54:32 +00001859type AndroidAppCertificateInfo struct {
1860 Certificate Certificate
1861}
1862
1863var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]()
1864
Colin Cross1b16b0e2019-02-12 14:41:32 -08001865// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1866// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001867func AndroidAppCertificateFactory() android.Module {
1868 module := &AndroidAppCertificate{}
1869 module.AddProperties(&module.properties)
1870 android.InitAndroidModule(module)
1871 return module
1872}
1873
Colin Crossbd01e2a2018-10-04 15:21:03 -07001874func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1875 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001876 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001877 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1878 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001879 }
Yu Liu728da7c2025-01-11 00:54:32 +00001880
1881 android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{
1882 Certificate: c.Certificate,
1883 })
Colin Crossbd01e2a2018-10-04 15:21:03 -07001884}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001885
1886type OverrideAndroidApp struct {
1887 android.ModuleBase
1888 android.OverrideModuleBase
1889}
1890
Sasha Smundak613cbb12020-06-05 10:27:23 -07001891func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001892 // All the overrides happen in the base module.
1893 // TODO(jungjw): Check the base module type.
1894}
1895
1896// override_android_app is used to create an android_app module based on another android_app by overriding
1897// some of its properties.
1898func OverrideAndroidAppModuleFactory() android.Module {
1899 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001900 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001901 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001902 &overridableAppProperties{},
1903 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001904
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001905 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001906 android.InitOverrideModule(m)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001907 android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) {
Spandan Dasde588a32024-12-03 22:52:24 +00001908 createInternalRuntimeOverlays(ctx, m.ModuleBase)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001909 }, 1) // Run after soong config load hoook
Spandan Dasde588a32024-12-03 22:52:24 +00001910
Jaewoong Jung525443a2019-02-28 15:35:54 -08001911 return m
1912}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001913
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001914type OverrideAndroidTest struct {
1915 android.ModuleBase
1916 android.OverrideModuleBase
1917}
1918
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001919func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001920 // All the overrides happen in the base module.
1921 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001922 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1923 TestOnly: true,
1924 TopLevelTarget: true,
1925 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001926}
1927
1928// override_android_test is used to create an android_app module based on another android_test by overriding
1929// some of its properties.
1930func OverrideAndroidTestModuleFactory() android.Module {
1931 m := &OverrideAndroidTest{}
1932 m.AddProperties(&overridableAppProperties{})
1933 m.AddProperties(&appTestProperties{})
1934
1935 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1936 android.InitOverrideModule(m)
1937 return m
1938}
1939
Colin Cross50ddcc42019-05-16 12:28:22 -07001940type UsesLibraryProperties struct {
1941 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
Cole Faust64f2d842024-10-17 13:28:34 -07001942 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001943
1944 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1945 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001946 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001947
1948 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1949 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1950 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001951
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001952 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1953 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1954 // normally is the same as the module name, but there are exceptions.
1955 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001956
1957 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1958 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1959 // added to the APK's manifest's <uses-library> elements.
1960 //
1961 // Care must be taken when using this as it could result in runtime errors if the APK actually
1962 // uses classes provided by the library and which are not provided in any other way.
1963 //
1964 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1965 // android.test.base shared library (and related libraries) but which depend on some common
1966 // libraries that depend on the android.test.base library. Without this those tests will end up
1967 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1968 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1969 // test altogether by providing access to classes that the tests were not expecting. Those tests
1970 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1971 // with the classes provided by the android.test.base library.
1972 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001973
1974 // The module names of optional uses-library libraries that are missing from the source tree.
1975 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001976}
1977
1978// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1979// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1980// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1981// with knowledge of their shared libraries.
1982type usesLibrary struct {
1983 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001984
1985 // Whether to enforce verify_uses_library check.
1986 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001987
1988 // Whether dexpreopt should be disabled
1989 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001990}
1991
Colin Cross4a80a152022-12-21 21:51:52 -08001992func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001993 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07001994 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001995 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1996 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001997 // Only add these extra dependencies if the module is an app that depends on framework
1998 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001999 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08002000 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002001 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
2002 // class loader context for dex2oat. Add them as a dependency with a special tag.
2003 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
2004 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
2005 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07002006 }
Cole Faust64f2d842024-10-17 13:28:34 -07002007 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00002008 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002009 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07002010 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002011 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07002012 }
2013}
2014
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002015// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07002016func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07002017 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002018 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01002019 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002020 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
2021 }
2022 return exists
2023 })
Colin Cross50ddcc42019-05-16 12:28:22 -07002024 return optionalUsesLibs
2025}
2026
Ulya Trafimovich24446712021-07-15 14:59:34 +01002027// Returns a map of module names of shared library dependencies to the paths to their dex jars on
2028// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002029func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
2030 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002031
2032 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
2033 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
2034 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
2035 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002036 }
2037
Yu Liu27b74aa2025-01-11 00:04:41 +00002038 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Ulya Trafimovich24446712021-07-15 14:59:34 +01002039 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
2040 if !isUsesLibTag {
2041 return
2042 }
2043
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002044 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01002045
Yu Liu27b74aa2025-01-11 00:04:41 +00002046 javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
2047 if !ok {
2048 return
2049 }
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002050 // Skip stub libraries. A dependency on the implementation library has been added earlier,
2051 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
2052 // from implementation libraries by their name, which is different as it has a suffix.
Yu Liu27b74aa2025-01-11 00:04:41 +00002053 if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
2054 if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002055 return
2056 }
2057 }
2058
Yu Liu27b74aa2025-01-11 00:04:41 +00002059 if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002060 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
2061 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
2062 // This will be restricted to optional_uses_libs
Yu Liu0a37d422025-02-13 02:05:00 +00002063 if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002064 u.shouldDisableDexpreopt = true
2065 return
2066 }
2067 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002068 libName := dep
Yu Liu27b74aa2025-01-11 00:04:41 +00002069 if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil {
2070 libName = *ulib.ProvidesUsesLib
Ulya Trafimovich24446712021-07-15 14:59:34 +01002071 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002072 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Yu Liu0a37d422025-02-13 02:05:00 +00002073 javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath,
Yu Liu27b74aa2025-01-11 00:04:41 +00002074 lib.ClassLoaderContexts)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002075 } else if ctx.Config().AllowMissingDependencies() {
2076 ctx.AddMissingDependencies([]string{dep})
2077 } else {
2078 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
2079 }
2080 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002081 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002082}
2083
2084// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
2085// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
2086// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07002087func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
2088 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
2089 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002090 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002091}
2092
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002093// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
Cole Faust64f2d842024-10-17 13:28:34 -07002094func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
2095 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002096 u.usesLibraryProperties.Enforce_uses_libs = &enforce
2097}
2098
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002099// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
2100// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
2101// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
2102// extension: APKs are supposed to end with '.apk').
2103func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00002104 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002105
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002106 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07002107
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002108 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
2109 // check is not necessary, and although it is good to have, it is difficult to maintain on
2110 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
2111 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01002112 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00002113 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002114 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002115 }
2116
Colin Crossf1a035e2020-11-16 17:32:30 -08002117 rule := android.NewRuleBuilder(pctx, ctx)
2118 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07002119 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002120 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002121 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00002122 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002123
2124 if outputFile != nil {
2125 cmd.FlagWithOutput("-o ", outputFile)
2126 }
Colin Cross50ddcc42019-05-16 12:28:22 -07002127
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002128 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
2129 cmd.Flag("--enforce-uses-libraries-relax")
2130 }
2131
Jiakai Zhangf98da192024-04-15 11:15:41 +00002132 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
2133 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002134 cmd.FlagWithArg("--uses-library ", lib)
2135 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00002136 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002137 cmd.FlagWithArg("--optional-uses-library ", lib)
2138 }
2139
Jiakai Zhangf98da192024-04-15 11:15:41 +00002140 // Also add missing optional uses libs, as the manifest check expects them.
2141 // Note that what we add here are the module names of those missing libs, not library names, while
2142 // the manifest check actually expects library names. However, the case where a library is missing
2143 // and the module name != the library name is too rare for us to handle.
2144 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
2145 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
2146 }
2147
Colin Crossf1a035e2020-11-16 17:32:30 -08002148 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002149 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002150}
Colin Cross50ddcc42019-05-16 12:28:22 -07002151
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002152// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
2153// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002154func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
2155 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002156 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00002157 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07002158}
2159
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002160// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
2161// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002162func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
2163 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
2164 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07002165}
Yu Liu0a37d422025-02-13 02:05:00 +00002166
2167// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
2168// the same way.
2169type androidApp interface {
2170 android.Module
2171 Privileged() bool
2172 InstallApkName() string
2173 OutputFile() android.Path
2174 JacocoReportClassesFile() android.Path
2175 Certificate() Certificate
2176 BaseModuleName() string
2177 PrivAppAllowlist() android.OptionalPath
2178}
2179
2180var _ androidApp = (*AndroidApp)(nil)
2181var _ androidApp = (*AndroidAppImport)(nil)
2182var _ androidApp = (*AndroidTestHelperApp)(nil)
2183
2184func setCommonAppInfo(appInfo *AppInfo, m androidApp) {
2185 appInfo.Privileged = m.Privileged()
2186 appInfo.OutputFile = m.OutputFile()
2187 appInfo.InstallApkName = m.InstallApkName()
2188 appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile()
2189 appInfo.Certificate = m.Certificate()
2190 appInfo.PrivAppAllowlist = m.PrivAppAllowlist()
2191}