blob: 87685449a34debe963c5bd31c52a88842984163b [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
Aditya Choudhary9b593522023-10-06 19:54:58 +000025 "android/soong/testing"
Jihoon Kang84b25892023-12-01 22:01:06 +000026
Colin Cross50ddcc42019-05-16 12:28:22 -070027 "github.com/google/blueprint"
28 "github.com/google/blueprint/proptools"
29
Colin Cross635c3b02016-05-18 15:37:25 -070030 "android/soong/android"
Colin Crossa4f08812018-10-02 22:03:40 -070031 "android/soong/cc"
Ulya Trafimovichd4bcea42020-06-03 14:57:22 +010032 "android/soong/dexpreopt"
Romain Jobredeaux9973ace2023-08-30 00:27:09 -040033 "android/soong/genrule"
Colin Cross303e21f2018-08-07 16:49:25 -070034 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070035)
36
Colin Cross3bc7ffa2017-11-22 16:19:37 -080037func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000038 RegisterAppBuildComponents(android.InitRegistrationContext)
Andrei Onea580636b2022-08-17 16:53:46 +000039 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080040}
41
Andrei Onea580636b2022-08-17 16:53:46 +000042var (
43 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
44 blueprint.RuleParams{
45 Command: "${ModifyAllowlistCmd} $in $packageName $out",
46 CommandDeps: []string{"${ModifyAllowlistCmd}"},
47 }, "packageName")
48)
49
Jihoon Kang9aef7772024-06-14 23:45:06 +000050type FlagsPackages struct {
51 // Paths to the aconfig dump output text files that are consumed by aapt2
52 AconfigTextFiles android.Paths
53}
54
55var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
56
Paul Duffinf9b1da02019-12-18 19:51:55 +000057func RegisterAppBuildComponents(ctx android.RegistrationContext) {
58 ctx.RegisterModuleType("android_app", AndroidAppFactory)
59 ctx.RegisterModuleType("android_test", AndroidTestFactory)
60 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
61 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
62 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
63 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000064}
65
Colin Cross30e076a2015-04-13 13:58:27 -070066// AndroidManifest.xml merging
67// package splits
68
Colin Crossfabb6082018-02-20 17:22:23 -080069type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070070 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070071 Additional_certificates []string
72
73 // If set, create package-export.apk, which other packages can
74 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080075 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070076
Colin Cross16056062017-12-13 22:46:28 -080077 // Specifies that this app should be installed to the priv-app directory,
78 // where the system will grant it additional privileges not available to
79 // normal apps.
80 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070081
82 // list of resource labels to generate individual resource packages
83 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040084
Colin Crossa4f08812018-10-02 22:03:40 -070085 // list of native libraries that will be provided in or alongside the resulting jar
86 Jni_libs []string `android:"arch_variant"`
87
Colin Cross7204cf02020-05-06 17:51:39 -070088 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -080089 // sdk_version.
90 Jni_uses_platform_apis *bool
91
Colin Cross7204cf02020-05-06 17:51:39 -070092 // if true, use JNI libraries that link against SDK APIs even if this module does not set
93 // sdk_version.
94 Jni_uses_sdk_apis *bool
95
Jaewoong Jungbc625cd2019-05-06 15:48:44 -070096 // STL library to use for JNI libraries.
97 Stl *string `android:"arch_variant"`
98
Colin Crosse4246ab2019-02-05 21:55:21 -080099 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900100 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
101 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
102 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
103 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800104 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800105
106 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
107 // they are used from inside the APK at runtime.
108 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700109
Jiyong Parkd044bb42024-05-15 02:09:54 +0900110 // Forces native libraries to always be packaged into the APK,
111 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
112 // True for android_test* modules.
113 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700114
115 // If set, find and merge all NOTICE files that this module and its dependencies have and store
116 // it in the APK as an asset.
117 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700118
119 // cc.Coverage related properties
120 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700121 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100122
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000123 // It can be set to test the behaviour of default target sdk version.
124 // Only required when updatable: false. It is an error if updatable: true and this is false.
125 Enforce_default_target_sdk_version *bool
126
127 // If set, the targetSdkVersion for the target is set to the latest default API level.
128 // This would be by default false, unless updatable: true or
129 // enforce_default_target_sdk_version: true in which case this defaults to true.
130 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
131
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100132 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100133 // additional rules to make sure an app can safely be updated. Default is false.
134 // Prefer using other specific properties if build behaviour must be changed; avoid using this
135 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100136 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000137
138 // Specifies the file that contains the allowlist for this app.
139 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900140
141 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
142 // and install the RRO package to /product partition, instead of passing --product argument
143 // to aapt2. Default is false.
144 // Setting this will make this APK identical to all targets, regardless of
145 // PRODUCT_CHARACTERISTICS.
146 Generate_product_characteristics_rro *bool
147
148 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
149 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700150}
151
Jaewoong Jung525443a2019-02-28 15:35:54 -0800152// android_app properties that can be overridden by override_android_app
153type overridableAppProperties struct {
154 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
155 // or an android_app_certificate module name in the form ":module".
156 Certificate *string
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700157
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800158 // Name of the signing certificate lineage file or filegroup module.
159 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700160
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400161 // For overriding the --rotation-min-sdk-version property of apksig
162 RotationMinSdkVersion *string
163
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700164 // the package name of this app. The package name in the manifest file is used if one was not given.
165 Package_name *string
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800166
167 // the logging parent of this app.
168 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000169
170 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
171 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000172
173 // Names of modules to be overridden. Listed modules can only be other binaries
174 // (in Make or Soong).
175 // This does not completely prevent installation of the overridden binaries, but if both
176 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
177 // from PRODUCT_PACKAGES.
178 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800179}
180
Colin Cross30e076a2015-04-13 13:58:27 -0700181type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700182 Library
183 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800184 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700185
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900186 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700187
Colin Crossfabb6082018-02-20 17:22:23 -0800188 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700189
Jaewoong Jung525443a2019-02-28 15:35:54 -0800190 overridableAppProperties overridableAppProperties
191
Colin Cross403cc152020-07-06 14:15:24 -0700192 jniLibs []jniLib
193 installPathForJNISymbols android.Path
194 embeddedJniLibs bool
195 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700196
197 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800198
199 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
200 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800201
Colin Cross70dda7e2019-10-01 22:05:35 -0700202 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700203
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700204 onDeviceDir string
205
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800206 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700207
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900208 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100209
210 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000211
212 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000213
214 privAppAllowlist android.OptionalPath
Colin Crosse1731a52017-12-14 11:22:55 -0800215}
216
Martin Stjernholm6d415272020-01-31 17:10:36 +0000217func (a *AndroidApp) IsInstallable() bool {
218 return Bool(a.properties.Installable)
219}
220
Colin Crossab8d1382023-07-14 17:23:41 +0000221func (a *AndroidApp) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
222 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700223}
224
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900225func (a *AndroidApp) OutputFile() android.Path {
226 return a.outputFile
227}
228
Colin Cross503c1d02020-01-28 14:00:53 -0800229func (a *AndroidApp) Certificate() Certificate {
230 return a.certificate
231}
232
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700233func (a *AndroidApp) JniCoverageOutputs() android.Paths {
234 return a.jniCoverageOutputs
235}
236
Andrei Onea580636b2022-08-17 16:53:46 +0000237func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
238 return a.privAppAllowlist
239}
240
Colin Crossa97c5d32018-03-28 14:58:31 -0700241var _ AndroidLibraryDependency = (*AndroidApp)(nil)
242
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900243type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800244 Pem, Key android.Path
245 presigned bool
246}
247
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700248var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800249
250func (c Certificate) AndroidMkString() string {
251 if c.presigned {
252 return "PRESIGNED"
253 } else {
254 return c.Pem.String()
255 }
Colin Cross30e076a2015-04-13 13:58:27 -0700256}
257
Colin Cross46c9b8b2017-06-22 16:51:17 -0700258func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900259 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700260 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
261 }
262
Jiyong Parkf1691d22021-03-29 20:11:58 +0900263 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000264 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
265 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100266 if sdkDep.hasFrameworkLibs() {
267 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700268 }
Colin Crossa4f08812018-10-02 22:03:40 -0700269
Jiyong Park92315372021-04-02 08:45:46 +0900270 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700271
272 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
273 ctx.PropertyErrorf("jni_uses_sdk_apis",
274 "can only be set for modules that do not set sdk_version")
275 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
276 ctx.PropertyErrorf("jni_uses_platform_apis",
277 "can only be set for modules that set sdk_version")
278 }
279
Colin Crossa4f08812018-10-02 22:03:40 -0700280 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700281 variation := append(jniTarget.Variations(),
282 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000283
Jiyong Park92d84042024-05-17 22:58:54 +0000284 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
285 // Many factors are considered here.
286 // 1. Basically, the selection follows whether the app has sdk_version set or not.
287 jniUsesSdkVariant := usesSDK
288 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
289 if Bool(a.appProperties.Jni_uses_sdk_apis) {
290 jniUsesSdkVariant = true
291 }
292 if Bool(a.appProperties.Jni_uses_platform_apis) {
293 jniUsesSdkVariant = false
294 }
295 // 3. Then the use of SDK variant is again prohibited for the following cases:
296 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
297 // partition (not only the app) is considered unbudled, there's no need to use the
298 // SDK variant.
299 // 3.2. the app doesn't support embedding the JNI libs
300 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
301 jniUsesSdkVariant = false
302 }
303 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000304 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
305 }
Jiyong Park92d84042024-05-17 22:58:54 +0000306
307 // Use the installable dep tag when the JNIs are not embedded
308 var tag dependencyTag
309 if a.shouldEmbedJnis(ctx) {
310 tag = jniLibTag
311 } else {
312 tag = jniInstallTag
313 }
314 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
Colin Crossa4f08812018-10-02 22:03:40 -0700315 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000316 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
317 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
318 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700319}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700320
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700321func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800322 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700323 if cert != "" {
324 ctx.AddDependency(ctx.Module(), certificateTag, cert)
325 }
326
Andrei Onea580636b2022-08-17 16:53:46 +0000327 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000328 // There are a few uids that are explicitly considered privileged regardless of their
329 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
330 // but for now, allow it not to be in priv-app.
331 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
332 if !privilegedBecauseOfUid {
333 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
334 }
Andrei Onea580636b2022-08-17 16:53:46 +0000335 }
336
Colin Crossbd01e2a2018-10-04 15:21:03 -0700337 for _, cert := range a.appProperties.Additional_certificates {
338 cert = android.SrcIsModule(cert)
339 if cert != "" {
340 ctx.AddDependency(ctx.Module(), certificateTag, cert)
341 } else {
342 ctx.PropertyErrorf("additional_certificates",
343 `must be names of android_app_certificate modules in the form ":module"`)
344 }
345 }
Colin Cross30e076a2015-04-13 13:58:27 -0700346}
347
Spandan Dasb0410872024-06-25 03:30:03 +0000348// TODO(b/156476221): Remove this allowlist
349var (
350 missingMinSdkVersionMtsAllowlist = []string{
351 "CellBroadcastReceiverGoogleUnitTests",
352 "CellBroadcastReceiverUnitTests",
353 "CtsBatterySavingTestCases",
354 "CtsDeviceAndProfileOwnerApp23",
355 "CtsDeviceAndProfileOwnerApp30",
356 "CtsIntentSenderApp",
357 "CtsJobSchedulerTestCases",
358 "CtsMimeMapTestCases",
359 "CtsTareTestCases",
360 "LibStatsPullTests",
361 "MediaProviderClientTests",
362 "TeleServiceTests",
363 "TestExternalImsServiceApp",
364 "TestSmsRetrieverApp",
365 "TetheringPrivilegedTests",
366 }
367)
368
369func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
370 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
371 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
372 }
373}
374
Jeongik Cha538c0d02019-07-11 15:54:27 +0900375func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000376 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000377 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
378 if applicationId != nil {
379 if a.overridableAppProperties.Package_name != nil {
380 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
381 }
382 a.aapt.manifestValues.applicationId = *applicationId
383 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900384 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700385 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
386 TestOnly: true,
387 })
388
Jeongik Cha538c0d02019-07-11 15:54:27 +0900389}
390
Colin Cross46c9b8b2017-06-22 16:51:17 -0700391func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100392 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000393 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700394 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000395 a.generateJavaUsedByApex(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700396}
397
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100398func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100399 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900400 if !a.SdkVersion(ctx).Stable() {
401 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100402 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000403 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100404 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
405 }
Jooyung Han749dc692020-04-15 11:03:39 +0900406
Jiyong Park92315372021-04-02 08:45:46 +0900407 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900408 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000409 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900410 } else {
411 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
412 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000413
414 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
415 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
416 }
417 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
418 if a.deviceProperties.Target_sdk_version == nil {
419 a.SetEnforceDefaultTargetSdkVersion(true)
420 }
421 }
422
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100423 a.checkPlatformAPI(ctx)
424 a.checkSdkVersions(ctx)
425}
426
Jiyong Park970c5242024-05-17 22:58:54 +0000427// Ensures that use_embedded_native_libs are set for apk-in-apex
428func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
429 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
430 apkInApex := !apexInfo.IsForPlatform()
431 hasJnis := len(a.appProperties.Jni_libs) > 0
432
433 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
434 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
435 }
436}
437
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900438// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
439// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900440func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900441 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
442 ctx.VisitDirectDeps(func(m android.Module) {
443 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
444 return
445 }
446 dep, _ := m.(*cc.Module)
Jooyung Han652d5b32020-05-20 17:12:13 +0900447 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900448 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
449 // handled properly regardless of sdk finalization.
Spandan Das2e8c0442022-05-08 00:39:35 +0000450 jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900451 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Spandan Das2e8c0442022-05-08 00:39:35 +0000452 ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
453 dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900454 return
455 }
456
457 })
458}
459
Sasha Smundak6ad77252019-05-01 13:16:22 -0700460// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800461// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700462func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900463 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800464 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900465 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800466 }
467
Jiyong Parkd044bb42024-05-15 02:09:54 +0900468 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
469 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
470 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800471}
472
Colin Cross43f08db2018-11-12 10:13:39 -0800473// Returns whether this module should have the dex file stored uncompressed in the APK.
474func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800475 if Bool(a.appProperties.Use_embedded_dex) {
476 return true
477 }
478
Colin Cross53a87f52019-06-25 13:35:30 -0700479 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
480 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900481 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000482 return true
483 }
484
Colin Cross53a87f52019-06-25 13:35:30 -0700485 if ctx.Config().UnbundledBuild() {
486 return false
487 }
488
Spandan Dase21a8d42024-01-23 23:56:29 +0000489 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700490}
491
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700492func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900493 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000494 Bool(a.appProperties.Updatable) ||
495 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000496}
497
Liz Kammer9f9fd022020-06-18 19:44:06 +0000498func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
499 aaptFlags := []string{"--rename-manifest-package " + packageName}
500 if renameResourcesPackage {
501 // Required to rename the package name in the resources table.
502 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
503 }
504 return aaptFlags
505}
506
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900507func (a *AndroidApp) OverriddenManifestPackageName() string {
508 return a.overriddenManifestPackageName
509}
510
Liz Kammer9f9fd022020-06-18 19:44:06 +0000511func (a *AndroidApp) renameResourcesPackage() bool {
512 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
513}
514
Jihoon Kang9049c272024-03-19 21:57:36 +0000515func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000516 ctx.VisitDirectDeps(func(dep android.Module) {
517 tag := ctx.OtherModuleDependencyTag(dep)
518 switch tag {
519 case staticLibTag:
520 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
521 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
522 }
523
524 case aconfigDeclarationTag:
525 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
526 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
527 } else {
528 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
529 "flags_packages property, but %s is not aconfig_declarations module type",
530 dep.Name(),
531 )
532 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000533 }
534 })
535
Jihoon Kang9aef7772024-06-14 23:45:06 +0000536 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000537}
538
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800539func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900540 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900541 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900542 usePlatformAPI = true
543 }
544 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000545
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700546 // Ask manifest_fixer to add or update the application element indicating this app has no code.
547 a.aapt.hasNoCode = !a.hasCode(ctx)
548
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800549 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800550
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800551 // 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 +0900552 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800553 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900554 characteristics := ctx.Config().ProductAAPTCharacteristics()
555 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
556 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700557 }
558
Dan Willemsen72be5902018-10-24 20:24:57 -0700559 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
560 // Product AAPT config
561 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800562 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700563 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700564
Dan Willemsen72be5902018-10-24 20:24:57 -0700565 // Product AAPT preferred config
566 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800567 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700568 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700569 }
570
Jiyong Park7f67f482019-01-05 12:57:48 +0900571 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700572 if overridden || a.overridableAppProperties.Package_name != nil {
573 // The product override variable has a priority over the package_name property.
574 if !overridden {
575 manifestPackageName = *a.overridableAppProperties.Package_name
576 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000577 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900578 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900579 }
580
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800581 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
582
Colin Crosse560c4a2019-03-19 16:03:11 -0700583 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800584 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100585 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000586 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
587 a.aapt.defaultManifestVersion = override
588 } else {
589 a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
590 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100591 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000592
Rico Winda2fa2632024-03-13 13:09:17 +0100593 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200594 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000595
596 aconfigTextFilePaths := getAconfigFilePaths(ctx)
597
Alixf7a10272023-09-27 16:47:56 +0000598 a.aapt.buildActions(ctx,
599 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000600 sdkContext: android.SdkContext(a),
601 classLoaderContexts: a.classLoaderContexts,
602 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
603 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100604 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000605 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000606 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000607 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000608 },
609 )
Colin Cross30e076a2015-04-13 13:58:27 -0700610
Colin Cross46c9b8b2017-06-22 16:51:17 -0700611 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700612 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000613
614 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
615 AconfigTextFiles: aconfigTextFilePaths,
616 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800617}
Colin Cross30e076a2015-04-13 13:58:27 -0700618
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800619func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700620 var staticLibProguardFlagFiles android.Paths
621 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800622 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400623 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
624 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
625 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700626 }
627 })
628
629 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
630
Colin Cross312634e2023-11-21 15:13:56 -0800631 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200632 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100633 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
634 // live for code references and (transitively) mark these as live.
635 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
636 // dead code alive)
637 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
638 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800639}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800640
Colin Cross403cc152020-07-06 14:15:24 -0700641func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800642 var installDir string
643 if ctx.ModuleName() == "framework-res" {
644 // framework-res.apk is installed as system/framework/framework-res.apk
645 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900646 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800647 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800648 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800649 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800650 }
Colin Cross403cc152020-07-06 14:15:24 -0700651
652 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
653}
654
Rico Wind98e7fa82023-11-27 09:44:03 +0100655func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700656 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000657 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700658 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100659 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700660 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100661 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700662 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Colin Cross50ddcc42019-05-16 12:28:22 -0700663 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100664 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700665 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800666 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700667
Rico Wind98e7fa82023-11-27 09:44:03 +0100668 var packageResources = a.exportPackage
669
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800670 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200671 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100672 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
673 aapt2Convert(ctx, protoFile, packageResources, "proto")
674 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
675 }
676
Colin Cross4eae06d2023-06-20 22:40:02 -0700677 var extraSrcJars android.Paths
678 var extraClasspathJars android.Paths
679 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800680 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700681 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
682 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
683 // classpath when compiling everything else, and add it to the final classes jar.
684 extraClasspathJars = android.Paths{a.aapt.rJar}
685 extraCombinedJars = android.Paths{a.aapt.rJar}
686 } else {
687 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
688 // R.java files for the app's package and the packages from all transitive static android_library
689 // dependencies. Compile the srcjar alongside the rest of the sources.
690 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
691 }
692
693 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
Rico Wind936754c2024-05-07 09:08:31 +0200694 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100695 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
696 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
697 packageResources = binaryResources
698 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800699 }
Colin Cross30e076a2015-04-13 13:58:27 -0700700
Rico Wind98e7fa82023-11-27 09:44:03 +0100701 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800702}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800703
Sam Delmerico82602492022-06-10 17:05:42 +0000704func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700705 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000706 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700707 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700708 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700709 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800710 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000711 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700712 for _, jni := range jniLibs {
713 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700714 // Only collect coverage for the first target arch if this is a multilib target.
715 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
716 // data file path collisions since the current coverage file path format doesn't contain
717 // arch-related strings. This is fine for now though; the code coverage team doesn't use
718 // multi-arch targets such as test_suite_* for coverage collections yet.
719 //
720 // Work with the team to come up with a new format that handles multilib modules properly
721 // and change this.
722 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700723 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700724 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
725 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700726 }
727 }
Colin Cross403cc152020-07-06 14:15:24 -0700728 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700729 }
730 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800731 return jniJarFile
732}
Colin Crossa4f08812018-10-02 22:03:40 -0700733
Colin Cross403cc152020-07-06 14:15:24 -0700734func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
735 var jniSymbols android.RuleBuilderInstalls
736 for _, jniLib := range a.jniLibs {
737 if jniLib.unstrippedFile != nil {
738 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
739 From: jniLib.unstrippedFile,
740 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
741 })
742 }
743 }
744 return jniSymbols
745}
746
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700747// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
748// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700749func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
750 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700751 if android.SrcIsModule(certPropValue) == "" {
752 var mainCert Certificate
753 if certPropValue != "" {
754 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
755 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800756 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
757 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700758 }
759 } else {
760 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800761 mainCert = Certificate{
762 Pem: pem,
763 Key: key,
764 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700765 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700766 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700767 }
768
Colin Crossbc2c8a72022-09-14 12:45:42 -0700769 if len(certificates) > 0 {
770 mainCertificate = certificates[0]
771 } else {
772 // This can be reached with an empty certificate list if AllowMissingDependencies is set
773 // and the certificate property for this module is a module reference to a missing module.
774 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
775 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
776 }
777 // Set a certificate to avoid panics later when accessing it.
778 mainCertificate = Certificate{
779 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000780 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700781 }
782 }
783
Zyan Wub7550aa2023-05-18 15:46:31 +0800784 if !m.Platform() {
785 certPath := mainCertificate.Pem.String()
786 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
787 if strings.HasPrefix(certPath, systemCertPath) {
788 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
789 allowed := ctx.Config().EnforceSystemCertificateAllowList()
790
791 if enforceSystemCert && !inList(m.Name(), allowed) {
792 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
793 }
794 }
795 }
796
Colin Crossbc2c8a72022-09-14 12:45:42 -0700797 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800798}
799
Jooyung Han39ee1192020-03-23 20:21:11 +0900800func (a *AndroidApp) InstallApkName() string {
801 return a.installApkName
802}
803
Sam Delmerico15809f82023-05-15 17:21:47 -0400804func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000805 if a.appProperties.Privapp_allowlist == nil {
806 return nil
807 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400808
809 isOverrideApp := a.GetOverriddenBy() != ""
810 if !isOverrideApp {
811 // if this is not an override, we don't need to rewrite the existing privapp allowlist
812 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
813 }
814
Andrei Onea580636b2022-08-17 16:53:46 +0000815 if a.overridableAppProperties.Package_name == nil {
816 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
817 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400818
Andrei Onea580636b2022-08-17 16:53:46 +0000819 packageName := *a.overridableAppProperties.Package_name
820 fileName := "privapp_allowlist_" + packageName + ".xml"
821 outPath := android.PathForModuleOut(ctx, fileName).OutputPath
822 ctx.Build(pctx, android.BuildParams{
823 Rule: modifyAllowlist,
824 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
825 Output: outPath,
826 Args: map[string]string{
827 "packageName": packageName,
828 },
829 })
830 return &outPath
831}
832
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800833func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700834 var apkDeps android.Paths
835
Colin Crossff694a82023-12-13 15:54:49 -0800836 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
837 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700838 a.hideApexVariantFromMake = true
839 }
840
Jeongik Cha538c0d02019-07-11 15:54:27 +0900841 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
842 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
843
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000844 // Unlike installApkName, a.stem should respect base module name for override_android_app.
845 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000846 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000847
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800848 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000849 // Both android_app and override_android_app module are expected to possess
850 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
851 // from the base module. Therefore, use a.Name() which represents
852 // the module name for both android_app and override_android_app.
853 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000854 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800855
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700856 if ctx.ModuleName() == "framework-res" {
857 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700858 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900859 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700860 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
861 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800862 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700863 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700864 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700865 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700866 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700867
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100868 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000869 if a.usesLibrary.shouldDisableDexpreopt {
870 a.dexpreopter.disableDexpreopt()
871 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000872
Colin Cross61fb62e2022-06-23 10:46:28 -0700873 var noticeAssetPath android.WritablePath
874 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
875 // The rule to create the notice file can't be generated yet, as the final output path
876 // for the apk isn't known yet. Add the path where the notice file will be generated to the
877 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
878 // be generated later.
879 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
880 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
881 }
882
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000883 // For apps targeting latest target_sdk_version
884 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
885 a.SetEnforceDefaultTargetSdkVersion(true)
886 }
887
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800888 // Process all building blocks, from AAPT to certificates.
889 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100890 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
891 a.usesLibrary.freezeEnforceUsesLibraries()
892
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100893 // Check that the <uses-library> list is coherent with the manifest.
Colin Cross50ddcc42019-05-16 12:28:22 -0700894 if a.usesLibrary.enforceUsesLibraries() {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000895 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
896 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700897 apkDeps = append(apkDeps, manifestCheckFile)
898 }
899
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800900 a.proguardBuildActions(ctx)
901
Colin Cross014489c2020-06-02 20:09:13 -0700902 a.linter.mergedManifest = a.aapt.mergedManifestFile
903 a.linter.manifest = a.aapt.manifestPath
904 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700905 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700906
Rico Wind98e7fa82023-11-27 09:44:03 +0100907 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800908
Jiyong Park92d84042024-05-17 22:58:54 +0000909 // No need to check the SDK version of the JNI deps unless we embed them
910 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
911 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000912 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800913
914 if ctx.Failed() {
915 return
916 }
917
Colin Crossbc2c8a72022-09-14 12:45:42 -0700918 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800919
920 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800921 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700922 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
923 var v4SignatureFile android.WritablePath = nil
924 if v4SigningRequested {
925 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
926 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700927 var lineageFile android.Path
928 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
929 lineageFile = android.PathForModuleSrc(ctx, lineage)
930 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400931 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
932
Rico Wind98e7fa82023-11-27 09:44:03 +0100933 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800934 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700935 if v4SigningRequested {
936 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
937 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800938
Colin Cross61fb62e2022-06-23 10:46:28 -0700939 if a.aapt.noticeFile.Valid() {
940 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -0700941 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -0700942 android.BuildNoticeHtmlOutputFromLicenseMetadata(
943 ctx, noticeFile, "", "",
944 []string{
945 a.installDir.String() + "/",
946 android.PathForModuleInstall(ctx).String() + "/",
947 a.outputFile.String(),
948 })
Bob Badoureef4c1c2022-05-16 12:20:04 -0700949 builder := android.NewRuleBuilder(pctx, ctx)
950 builder.Command().Text("cp").
951 Input(noticeFile).
952 Output(noticeAssetPath)
953 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -0700954 }
955
Colin Crosse560c4a2019-03-19 16:03:11 -0700956 for _, split := range a.aapt.splits {
957 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -0800958 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700959 if v4SigningRequested {
960 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
961 }
Rico Wind98e7fa82023-11-27 09:44:03 +0100962 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -0700963 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -0700964 if v4SigningRequested {
965 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
966 }
Colin Crosse560c4a2019-03-19 16:03:11 -0700967 }
968
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800969 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -0700970 bundleFile := android.PathForModuleOut(ctx, "base.zip")
971 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
972 a.bundleFile = bundleFile
973
Andrei Onea580636b2022-08-17 16:53:46 +0000974 allowlist := a.createPrivappAllowlist(ctx)
975 if allowlist != nil {
976 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
977 }
978
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800979 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +0000980 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
981 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -0400982 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +0000983 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
984 allowlistInstallFilename := a.installApkName + ".xml"
985 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -0400986 }
987
Colin Cross09ad3a62023-11-15 12:29:33 -0800988 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +0900989 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -0700990 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
991 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +0900992 }
Jiyong Park25b92222024-05-17 22:58:54 +0000993 // If we don't embed jni libs, make sure that those are installed along with the
994 // app, and also place symlinks to the installed paths under the lib/<arch>
995 // directory of the app installation directory. ex:
996 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
997 if !a.embeddedJniLibs {
998 for _, jniLib := range jniLibs {
999 archStr := jniLib.target.Arch.ArchType.String()
1000 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1001 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001002 // install the symlink itself
1003 symlinkName := installedLib.Base()
1004 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1005 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1006 }
1007 }
1008 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001009 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001010 }
Artur Satayev1111b842020-04-27 19:05:28 +01001011
1012 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001013
1014 providePrebuiltInfo(ctx,
1015 prebuiltInfoProps{
1016 baseModuleName: a.BaseModuleName(),
1017 isPrebuilt: false,
1018 },
1019 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001020
1021 a.setOutputFiles(ctx)
1022}
1023
1024func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1025 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1026 if a.aaptSrcJar != nil {
1027 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1028 }
1029 if a.rJar != nil {
1030 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1031 }
1032 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1033 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1034 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1035 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001036}
1037
Colin Crossc2d24052020-05-13 11:05:02 -07001038type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001039 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001040 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001041 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1042}
1043
1044func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1045 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001046 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001047
Colin Crossc2d24052020-05-13 11:05:02 -07001048 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001049 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1050 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001051 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001052 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1053 checkNativeSdkVersion, func(dep cc.LinkableInterface) bool {
1054 return !dep.IsNdk(ctx.Config()) && !dep.IsStubs()
1055 })
1056
1057 var certificates []Certificate
1058
1059 ctx.VisitDirectDeps(func(module android.Module) {
1060 otherName := ctx.OtherModuleName(module)
1061 tag := ctx.OtherModuleDependencyTag(module)
1062
1063 if tag == certificateTag {
1064 if dep, ok := module.(*AndroidAppCertificate); ok {
1065 certificates = append(certificates, dep.Certificate)
1066 } else {
1067 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1068 }
1069 }
1070 })
1071 return jniLib, prebuiltJniPackages, certificates
1072}
1073
1074func collectJniDeps(ctx android.ModuleContext,
1075 shouldCollectRecursiveNativeDeps bool,
1076 checkNativeSdkVersion bool,
1077 filter func(cc.LinkableInterface) bool) ([]jniLib, android.Paths) {
1078 var jniLibs []jniLib
1079 var prebuiltJniPackages android.Paths
1080 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001081
Peter Collingbournead84f972019-12-17 16:46:18 -08001082 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001083 otherName := ctx.OtherModuleName(module)
1084 tag := ctx.OtherModuleDependencyTag(module)
1085
Colin Crossf0913fb2020-07-29 12:59:39 -07001086 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001087 if dep, ok := module.(cc.LinkableInterface); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001088 if filter != nil && !filter(dep) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001089 return false
1090 }
1091
Colin Crossa4f08812018-10-02 22:03:40 -07001092 lib := dep.OutputFile()
1093 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001094 path := lib.Path()
1095 if seenModulePaths[path.String()] {
1096 return false
1097 }
1098 seenModulePaths[path.String()] = true
1099
1100 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1101 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1102 otherName)
1103 }
1104
Colin Crossa4f08812018-10-02 22:03:40 -07001105 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001106 name: ctx.OtherModuleName(module),
1107 path: path,
1108 target: module.Target(),
1109 coverageFile: dep.CoverageOutputFile(),
1110 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001111 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001112 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001113 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001114 } else if ctx.Config().AllowMissingDependencies() {
1115 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001116 } else {
1117 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1118 }
1119 } else {
1120 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001121 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001122
1123 return shouldCollectRecursiveNativeDeps
1124 }
1125
Colin Cross313aa542023-12-13 13:47:44 -08001126 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001127 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1128 }
1129
Peter Collingbournead84f972019-12-17 16:46:18 -08001130 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001131 })
1132
Makoto Onuki2ca84272024-02-10 00:15:21 +00001133 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001134}
1135
Jooyung Han749dc692020-04-15 11:03:39 +09001136func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001137 ctx.WalkDeps(func(child, parent android.Module) bool {
1138 isExternal := !a.DepIsInSameApex(ctx, child)
1139 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001140 if !do(ctx, parent, am, isExternal) {
1141 return false
1142 }
Artur Satayev1111b842020-04-27 19:05:28 +01001143 }
1144 return !isExternal
1145 })
1146}
1147
1148func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1149 if ctx.Host() {
1150 return
1151 }
1152
1153 depsInfo := android.DepNameToDepInfoMap{}
Jooyung Han749dc692020-04-15 11:03:39 +09001154 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001155 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001156
1157 // Skip dependencies that are only available to APEXes; they are developed with updatability
1158 // in mind and don't need manual approval.
1159 if to.(android.ApexModule).NotAvailableForPlatform() {
1160 return true
1161 }
1162
Artur Satayev1111b842020-04-27 19:05:28 +01001163 if info, exist := depsInfo[depName]; exist {
1164 info.From = append(info.From, from.Name())
1165 info.IsExternal = info.IsExternal && externalDep
1166 depsInfo[depName] = info
1167 } else {
1168 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001169 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001170 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001171 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001172 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1173 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001174 }
Jiyong Park92315372021-04-02 08:45:46 +09001175 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1176 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1177 // string
1178 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001179 toMinSdkVersion = v
1180 }
Artur Satayev1111b842020-04-27 19:05:28 +01001181 }
1182 depsInfo[depName] = android.ApexModuleDepInfo{
1183 To: depName,
1184 From: []string{from.Name()},
1185 IsExternal: externalDep,
1186 MinSdkVersion: toMinSdkVersion,
1187 }
1188 }
Jooyung Han749dc692020-04-15 11:03:39 +09001189 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001190 })
1191
Jiyong Park92315372021-04-02 08:45:46 +09001192 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001193}
1194
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001195func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1196 return a.appProperties.EnforceDefaultTargetSdkVersion
1197}
1198
1199func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1200 a.appProperties.EnforceDefaultTargetSdkVersion = val
1201}
1202
Artur Satayev849f8442020-04-28 14:57:42 +01001203func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001204 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001205}
1206
Spandan Das42e89502022-05-06 22:12:55 +00001207func (a *AndroidApp) SetUpdatable(val bool) {
1208 a.appProperties.Updatable = &val
1209}
1210
Colin Cross0ea8ba82019-06-06 14:33:29 -07001211func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001212 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1213 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001214 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001215 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001216 return String(a.overridableAppProperties.Certificate)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001217}
1218
Jiyong Park0f80c182020-01-31 02:49:53 +09001219func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1220 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1221 return true
1222 }
1223 return a.Library.DepIsInSameApex(ctx, dep)
1224}
1225
Jiyong Parkf7487312019-10-17 12:54:30 +09001226func (a *AndroidApp) Privileged() bool {
1227 return Bool(a.appProperties.Privileged)
1228}
1229
Colin Crosse1a85552024-06-14 12:17:37 -07001230func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001231 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001232}
1233
Ivan Lozanod7586b62021-04-01 09:49:36 -04001234func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001235 a.appProperties.PreventInstall = true
1236}
1237
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001238func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1239 a.appProperties.IsCoverageVariant = coverage
1240}
1241
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001242func (a *AndroidApp) EnableCoverageIfNeeded() {}
1243
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001244var _ cc.Coverage = (*AndroidApp)(nil)
1245
Cole Faustb36d31d2024-08-27 16:04:28 -07001246func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1247 a.Library.IDEInfo(ctx, dpInfo)
1248 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001249}
1250
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001251func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1252 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1253}
1254
1255func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1256 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1257}
1258
Colin Cross1b16b0e2019-02-12 14:41:32 -08001259// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001260func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001261 module := &AndroidApp{}
1262
Liz Kammera7a64f32020-07-09 15:16:41 -07001263 module.Module.dexProperties.Optimize.EnabledByDefault = true
1264 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001265 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001266
Colin Crossae5caf52018-05-22 11:11:52 -07001267 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001268 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001269 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001270
Colin Crossce6734e2020-06-15 16:09:53 -07001271 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001272 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001273 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001274 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001275 &module.overridableAppProperties,
1276 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001277
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001278 module.usesLibrary.enforce = true
1279
Colin Crossa4f08812018-10-02 22:03:40 -07001280 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1281 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001282 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001283 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001284
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001285 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1286 a := ctx.Module().(*AndroidApp)
1287
1288 characteristics := ctx.Config().ProductAAPTCharacteristics()
1289 if characteristics == "default" || characteristics == "" {
1290 module.appProperties.Generate_product_characteristics_rro = nil
1291 // no need to create RRO
1292 return
1293 }
1294
1295 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1296 return
1297 }
1298
1299 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1300 rroManifestName := rroPackageName + "_manifest"
1301
1302 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1303 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1304
1305 rroManifestProperties := struct {
1306 Name *string
1307 Tools []string
1308 Out []string
1309 Srcs []string
1310 Cmd *string
1311 }{
1312 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001313 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001314 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001315 Srcs: []string{":" + a.Name() + "{.apk}"},
1316 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001317 }
1318 ctx.CreateModule(genrule.GenRuleFactory, &rroManifestProperties)
1319
1320 rroProperties := struct {
1321 Name *string
1322 Filter_product *string
1323 Aaptflags []string
1324 Manifest *string
1325 Resource_dirs []string
1326 }{
1327 Name: proptools.StringPtr(rroPackageName),
1328 Filter_product: proptools.StringPtr(characteristics),
1329 Aaptflags: []string{"--auto-add-overlay"},
1330 Manifest: proptools.StringPtr(":" + rroManifestName),
1331 Resource_dirs: a.aaptProperties.Resource_dirs,
1332 }
优秀d75e9982024-05-09 07:15:55 +00001333 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1334 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1335 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1336 }
1337 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001338 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1339 })
1340
Colin Cross36242852017-06-23 15:06:31 -07001341 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001342}
Colin Crossae5caf52018-05-22 11:11:52 -07001343
Alix96ea88452023-08-31 15:48:23 +00001344// A dictionary of values to be overridden in the manifest.
1345type Manifest_values struct {
1346 // Overrides the value of package_name in the manifest
1347 ApplicationId *string
1348}
1349
Colin Crossae5caf52018-05-22 11:11:52 -07001350type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001351 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001352 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001353
Seth Moorec6f4b532023-02-02 13:22:26 -08001354 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001355 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001356
1357 // If specified, the mainline module package name in the test config is overwritten by it.
1358 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001359
1360 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001361}
1362
1363type AndroidTest struct {
1364 AndroidApp
1365
1366 appTestProperties appTestProperties
1367
1368 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001369
Dan Shi95d19422020-08-15 12:24:26 -07001370 testConfig android.Path
1371 extraTestConfigs android.Paths
1372 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001373}
1374
Jaewoong Jung0949f312019-09-11 10:25:18 -07001375func (a *AndroidTest) InstallInTestcases() bool {
1376 return true
1377}
1378
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001379type androidTestApp interface {
1380 includedInTestSuite(searchPrefix string) bool
1381}
1382
1383func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1384 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1385}
1386
1387func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1388 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1389}
1390
Colin Crossae5caf52018-05-22 11:11:52 -07001391func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001392 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001393 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001394 if a.appTestProperties.Instrumentation_target_package != nil {
1395 a.additionalAaptFlags = append(a.additionalAaptFlags,
1396 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1397 } else if a.appTestProperties.Instrumentation_for != nil {
1398 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001399 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1400 if overridden {
1401 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1402 }
1403 }
Alix96ea88452023-08-31 15:48:23 +00001404 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1405 if applicationId != nil {
1406 if a.overridableAppProperties.Package_name != nil {
1407 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1408 }
1409 a.aapt.manifestValues.applicationId = *applicationId
1410 }
Colin Crossae5caf52018-05-22 11:11:52 -07001411 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001412
easoncylee5bcff5d2020-04-30 14:57:06 +08001413 for _, module := range a.testProperties.Test_mainline_modules {
1414 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1415 }
1416
Jaewoong Jung39982342020-01-14 10:27:18 -08001417 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
easoncylee5bcff5d2020-04-30 14:57:06 +08001418 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
Jaewoong Jung39982342020-01-14 10:27:18 -08001419 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001420 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001421 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Colin Cross40213022023-12-13 15:19:49 -08001422 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001423 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1424 InstalledFiles: a.data,
1425 OutputFile: a.OutputFile(),
1426 TestConfig: a.testConfig,
1427 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001428 TestSuites: a.testProperties.Test_suites,
1429 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001430 LocalCertificate: a.certificate.AndroidMkString(),
1431 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001432 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001433 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1434 TestOnly: true,
1435 TopLevelTarget: true,
1436 })
1437
Colin Cross303e21f2018-08-07 16:49:25 -07001438}
1439
Jaewoong Jung39982342020-01-14 10:27:18 -08001440func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1441 if testConfig == nil {
1442 return nil
1443 }
1444
1445 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001446 rule := android.NewRuleBuilder(pctx, ctx)
1447 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001448 fixNeeded := false
1449
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001450 // 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 -08001451 if ctx.ModuleName() != a.installApkName {
1452 fixNeeded = true
1453 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1454 }
1455
1456 if a.overridableAppProperties.Package_name != nil {
1457 fixNeeded = true
1458 command.FlagWithInput("--manifest ", a.manifestPath).
1459 FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
1460 }
1461
Seth Moorec6f4b532023-02-02 13:22:26 -08001462 if a.appTestProperties.Mainline_package_name != nil {
1463 fixNeeded = true
1464 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1465 }
1466
Jaewoong Jung39982342020-01-14 10:27:18 -08001467 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001468 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001469 return fixedConfig
1470 }
1471 return testConfig
1472}
1473
Yihan Dong8be09c22024-08-29 15:32:13 +08001474func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1475 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1476 // Instrument the android_test_helper target to log potential API calls at the run time.
1477 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1478 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1479 a.setApiMapper(true)
1480 }
1481 a.AndroidApp.DepsMutator(ctx)
1482}
1483
Colin Cross303e21f2018-08-07 16:49:25 -07001484func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001485 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1486 // Instrument the android_test_helper target to log potential API calls at the run time.
1487 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1488 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1489 a.setApiMapper(true)
1490 }
Colin Cross303e21f2018-08-07 16:49:25 -07001491 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001492}
1493
1494func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1495 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001496 if a.appTestProperties.Instrumentation_for != nil {
1497 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1498 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1499 // use instrumentationForTag instead of libTag.
1500 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1501 }
Colin Crossae5caf52018-05-22 11:11:52 -07001502}
1503
Colin Cross1b16b0e2019-02-12 14:41:32 -08001504// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1505// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001506func AndroidTestFactory() android.Module {
1507 module := &AndroidTest{}
1508
Jared Duke63a3da92022-06-02 19:11:14 +00001509 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001510
1511 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001512 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001513 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001514 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1515 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001516 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001517 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001518
Colin Crossce6734e2020-06-15 16:09:53 -07001519 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001520 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001521 &module.aaptProperties,
1522 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001523 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001524 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001525 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001526
Colin Crossa4f08812018-10-02 22:03:40 -07001527 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1528 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001529 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001530
Colin Crossae5caf52018-05-22 11:11:52 -07001531 return module
1532}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001533
Colin Cross252fc6f2018-10-04 15:22:03 -07001534type appTestHelperAppProperties struct {
1535 // list of compatibility suites (for example "cts", "vts") that the module should be
1536 // installed into.
1537 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001538
1539 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1540 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1541 // explicitly.
1542 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001543
1544 // Install the test into a folder named for the module in all test suites.
1545 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001546
1547 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001548}
1549
1550type AndroidTestHelperApp struct {
1551 AndroidApp
1552
1553 appTestHelperAppProperties appTestHelperAppProperties
1554}
1555
Jaewoong Jung326a9412019-11-21 10:41:00 -08001556func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1557 return true
1558}
1559
Colin Cross1b16b0e2019-02-12 14:41:32 -08001560// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1561// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1562// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001563func AndroidTestHelperAppFactory() android.Module {
1564 module := &AndroidTestHelperApp{}
1565
Jared Duke63a3da92022-06-02 19:11:14 +00001566 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001567 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001568
1569 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001570 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1571 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001572 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001573 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001574
Colin Crossce6734e2020-06-15 16:09:53 -07001575 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001576 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001577 &module.aaptProperties,
1578 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001579 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001580 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001581
1582 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1583 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001584 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001585 return module
1586}
1587
Colin Crossbd01e2a2018-10-04 15:21:03 -07001588type AndroidAppCertificate struct {
1589 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001590
Colin Crossbd01e2a2018-10-04 15:21:03 -07001591 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001592 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001593}
1594
1595type AndroidAppCertificateProperties struct {
1596 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1597 Certificate *string
1598}
1599
Colin Cross1b16b0e2019-02-12 14:41:32 -08001600// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1601// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001602func AndroidAppCertificateFactory() android.Module {
1603 module := &AndroidAppCertificate{}
1604 module.AddProperties(&module.properties)
1605 android.InitAndroidModule(module)
1606 return module
1607}
1608
Colin Crossbd01e2a2018-10-04 15:21:03 -07001609func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1610 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001611 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001612 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1613 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001614 }
1615}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001616
1617type OverrideAndroidApp struct {
1618 android.ModuleBase
1619 android.OverrideModuleBase
1620}
1621
Sasha Smundak613cbb12020-06-05 10:27:23 -07001622func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001623 // All the overrides happen in the base module.
1624 // TODO(jungjw): Check the base module type.
1625}
1626
1627// override_android_app is used to create an android_app module based on another android_app by overriding
1628// some of its properties.
1629func OverrideAndroidAppModuleFactory() android.Module {
1630 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001631 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001632 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001633 &overridableAppProperties{},
1634 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001635
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001636 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001637 android.InitOverrideModule(m)
1638 return m
1639}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001640
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001641type OverrideAndroidTest struct {
1642 android.ModuleBase
1643 android.OverrideModuleBase
1644}
1645
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001646func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001647 // All the overrides happen in the base module.
1648 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001649 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1650 TestOnly: true,
1651 TopLevelTarget: true,
1652 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001653}
1654
1655// override_android_test is used to create an android_app module based on another android_test by overriding
1656// some of its properties.
1657func OverrideAndroidTestModuleFactory() android.Module {
1658 m := &OverrideAndroidTest{}
1659 m.AddProperties(&overridableAppProperties{})
1660 m.AddProperties(&appTestProperties{})
1661
1662 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1663 android.InitOverrideModule(m)
1664 return m
1665}
1666
Colin Cross50ddcc42019-05-16 12:28:22 -07001667type UsesLibraryProperties struct {
1668 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
1669 Uses_libs []string
1670
1671 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1672 // required=false.
1673 Optional_uses_libs []string
1674
1675 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1676 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1677 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001678
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001679 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1680 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1681 // normally is the same as the module name, but there are exceptions.
1682 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001683
1684 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1685 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1686 // added to the APK's manifest's <uses-library> elements.
1687 //
1688 // Care must be taken when using this as it could result in runtime errors if the APK actually
1689 // uses classes provided by the library and which are not provided in any other way.
1690 //
1691 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1692 // android.test.base shared library (and related libraries) but which depend on some common
1693 // libraries that depend on the android.test.base library. Without this those tests will end up
1694 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1695 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1696 // test altogether by providing access to classes that the tests were not expecting. Those tests
1697 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1698 // with the classes provided by the android.test.base library.
1699 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001700
1701 // The module names of optional uses-library libraries that are missing from the source tree.
1702 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001703}
1704
1705// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1706// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1707// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1708// with knowledge of their shared libraries.
1709type usesLibrary struct {
1710 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001711
1712 // Whether to enforce verify_uses_library check.
1713 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001714
1715 // Whether dexpreopt should be disabled
1716 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001717}
1718
Colin Cross4a80a152022-12-21 21:51:52 -08001719func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001720 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001721 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001722 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1723 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001724 // Only add these extra dependencies if the module is an app that depends on framework
1725 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001726 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001727 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001728 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1729 // class loader context for dex2oat. Add them as a dependency with a special tag.
1730 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1731 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1732 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001733 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001734 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
1735 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001736 } else {
1737 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
1738 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001739 }
1740}
1741
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001742// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001743func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001744 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool {
1745 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001746 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001747 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1748 }
1749 return exists
1750 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001751 return optionalUsesLibs
1752}
1753
Ulya Trafimovich24446712021-07-15 14:59:34 +01001754// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1755// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001756func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1757 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001758
1759 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1760 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1761 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1762 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001763 }
1764
Ulya Trafimovich24446712021-07-15 14:59:34 +01001765 ctx.VisitDirectDeps(func(m android.Module) {
1766 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1767 if !isUsesLibTag {
1768 return
1769 }
1770
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001771 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001772
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001773 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1774 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1775 // from implementation libraries by their name, which is different as it has a suffix.
1776 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1777 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1778 return
1779 }
1780 }
1781
Spandan Das0727ba72024-02-13 16:37:43 +00001782 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1783 // This will be restricted to optional_uses_libs
1784 if sdklib, ok := m.(SdkLibraryDependency); ok {
1785 if tag == usesLibOptTag && sdklib.DexJarBuildPath(ctx).PathOrNil() == nil {
1786 u.shouldDisableDexpreopt = true
1787 return
1788 }
1789 }
1790
Ulya Trafimovich24446712021-07-15 14:59:34 +01001791 if lib, ok := m.(UsesLibraryDependency); ok {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001792 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001793 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001794 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001795 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001796 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001797 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001798 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001799 } else if ctx.Config().AllowMissingDependencies() {
1800 ctx.AddMissingDependencies([]string{dep})
1801 } else {
1802 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1803 }
1804 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001805 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001806}
1807
1808// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1809// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1810// unconditionally in the future.
1811func (u *usesLibrary) enforceUsesLibraries() bool {
1812 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
1813 len(u.usesLibraryProperties.Optional_uses_libs) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001814 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001815}
1816
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001817// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
1818func (u *usesLibrary) freezeEnforceUsesLibraries() {
1819 enforce := u.enforceUsesLibraries()
1820 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1821}
1822
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001823// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1824// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1825// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1826// extension: APKs are supposed to end with '.apk').
1827func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001828 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001829
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001830 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001831
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001832 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1833 // check is not necessary, and although it is good to have, it is difficult to maintain on
1834 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1835 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001836 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001837 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001838 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001839 }
1840
Colin Crossf1a035e2020-11-16 17:32:30 -08001841 rule := android.NewRuleBuilder(pctx, ctx)
1842 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001843 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001844 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001845 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001846 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001847
1848 if outputFile != nil {
1849 cmd.FlagWithOutput("-o ", outputFile)
1850 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001851
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001852 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1853 cmd.Flag("--enforce-uses-libraries-relax")
1854 }
1855
Jiakai Zhangf98da192024-04-15 11:15:41 +00001856 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1857 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001858 cmd.FlagWithArg("--uses-library ", lib)
1859 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001860 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001861 cmd.FlagWithArg("--optional-uses-library ", lib)
1862 }
1863
Jiakai Zhangf98da192024-04-15 11:15:41 +00001864 // Also add missing optional uses libs, as the manifest check expects them.
1865 // Note that what we add here are the module names of those missing libs, not library names, while
1866 // the manifest check actually expects library names. However, the case where a library is missing
1867 // and the module name != the library name is too rare for us to handle.
1868 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1869 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1870 }
1871
Colin Crossf1a035e2020-11-16 17:32:30 -08001872 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001873 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001874}
Colin Cross50ddcc42019-05-16 12:28:22 -07001875
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001876// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1877// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001878func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1879 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001880 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001881 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001882}
1883
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001884// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1885// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001886func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1887 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1888 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001889}