blob: 7707a7e76d7a3620413e6aa852cd3632b9666b00 [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
Colin Crossfdaa6722024-08-23 11:58:08 -0700693 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
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
Colin Crossa6182ab2024-08-21 10:47:44 -07001012 ctx.CheckbuildFile(a.outputFile)
1013
Artur Satayev1111b842020-04-27 19:05:28 +01001014 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001015
1016 providePrebuiltInfo(ctx,
1017 prebuiltInfoProps{
1018 baseModuleName: a.BaseModuleName(),
1019 isPrebuilt: false,
1020 },
1021 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001022
1023 a.setOutputFiles(ctx)
1024}
1025
1026func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1027 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1028 if a.aaptSrcJar != nil {
1029 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1030 }
1031 if a.rJar != nil {
1032 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1033 }
1034 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1035 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1036 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1037 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001038}
1039
Colin Crossc2d24052020-05-13 11:05:02 -07001040type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001041 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001042 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001043 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1044}
1045
1046func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1047 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001048 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001049
Colin Crossc2d24052020-05-13 11:05:02 -07001050 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001051 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1052 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001053 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001054 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1055 checkNativeSdkVersion, func(dep cc.LinkableInterface) bool {
1056 return !dep.IsNdk(ctx.Config()) && !dep.IsStubs()
1057 })
1058
1059 var certificates []Certificate
1060
1061 ctx.VisitDirectDeps(func(module android.Module) {
1062 otherName := ctx.OtherModuleName(module)
1063 tag := ctx.OtherModuleDependencyTag(module)
1064
1065 if tag == certificateTag {
1066 if dep, ok := module.(*AndroidAppCertificate); ok {
1067 certificates = append(certificates, dep.Certificate)
1068 } else {
1069 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1070 }
1071 }
1072 })
1073 return jniLib, prebuiltJniPackages, certificates
1074}
1075
1076func collectJniDeps(ctx android.ModuleContext,
1077 shouldCollectRecursiveNativeDeps bool,
1078 checkNativeSdkVersion bool,
1079 filter func(cc.LinkableInterface) bool) ([]jniLib, android.Paths) {
1080 var jniLibs []jniLib
1081 var prebuiltJniPackages android.Paths
1082 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001083
Peter Collingbournead84f972019-12-17 16:46:18 -08001084 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001085 otherName := ctx.OtherModuleName(module)
1086 tag := ctx.OtherModuleDependencyTag(module)
1087
Colin Crossf0913fb2020-07-29 12:59:39 -07001088 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001089 if dep, ok := module.(cc.LinkableInterface); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001090 if filter != nil && !filter(dep) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001091 return false
1092 }
1093
Colin Crossa4f08812018-10-02 22:03:40 -07001094 lib := dep.OutputFile()
1095 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001096 path := lib.Path()
1097 if seenModulePaths[path.String()] {
1098 return false
1099 }
1100 seenModulePaths[path.String()] = true
1101
1102 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1103 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1104 otherName)
1105 }
1106
Colin Crossa4f08812018-10-02 22:03:40 -07001107 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001108 name: ctx.OtherModuleName(module),
1109 path: path,
1110 target: module.Target(),
1111 coverageFile: dep.CoverageOutputFile(),
1112 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001113 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001114 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001115 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001116 } else if ctx.Config().AllowMissingDependencies() {
1117 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001118 } else {
1119 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1120 }
1121 } else {
1122 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001123 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001124
1125 return shouldCollectRecursiveNativeDeps
1126 }
1127
Colin Cross313aa542023-12-13 13:47:44 -08001128 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001129 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1130 }
1131
Peter Collingbournead84f972019-12-17 16:46:18 -08001132 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001133 })
1134
Makoto Onuki2ca84272024-02-10 00:15:21 +00001135 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001136}
1137
Jooyung Han749dc692020-04-15 11:03:39 +09001138func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001139 ctx.WalkDeps(func(child, parent android.Module) bool {
1140 isExternal := !a.DepIsInSameApex(ctx, child)
1141 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001142 if !do(ctx, parent, am, isExternal) {
1143 return false
1144 }
Artur Satayev1111b842020-04-27 19:05:28 +01001145 }
1146 return !isExternal
1147 })
1148}
1149
1150func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1151 if ctx.Host() {
1152 return
1153 }
1154
1155 depsInfo := android.DepNameToDepInfoMap{}
Jooyung Han749dc692020-04-15 11:03:39 +09001156 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001157 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001158
1159 // Skip dependencies that are only available to APEXes; they are developed with updatability
1160 // in mind and don't need manual approval.
1161 if to.(android.ApexModule).NotAvailableForPlatform() {
1162 return true
1163 }
1164
Artur Satayev1111b842020-04-27 19:05:28 +01001165 if info, exist := depsInfo[depName]; exist {
1166 info.From = append(info.From, from.Name())
1167 info.IsExternal = info.IsExternal && externalDep
1168 depsInfo[depName] = info
1169 } else {
1170 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001171 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001172 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001173 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001174 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1175 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001176 }
Jiyong Park92315372021-04-02 08:45:46 +09001177 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1178 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1179 // string
1180 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001181 toMinSdkVersion = v
1182 }
Artur Satayev1111b842020-04-27 19:05:28 +01001183 }
1184 depsInfo[depName] = android.ApexModuleDepInfo{
1185 To: depName,
1186 From: []string{from.Name()},
1187 IsExternal: externalDep,
1188 MinSdkVersion: toMinSdkVersion,
1189 }
1190 }
Jooyung Han749dc692020-04-15 11:03:39 +09001191 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001192 })
1193
Jiyong Park92315372021-04-02 08:45:46 +09001194 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001195}
1196
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001197func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1198 return a.appProperties.EnforceDefaultTargetSdkVersion
1199}
1200
1201func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1202 a.appProperties.EnforceDefaultTargetSdkVersion = val
1203}
1204
Artur Satayev849f8442020-04-28 14:57:42 +01001205func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001206 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001207}
1208
Spandan Das42e89502022-05-06 22:12:55 +00001209func (a *AndroidApp) SetUpdatable(val bool) {
1210 a.appProperties.Updatable = &val
1211}
1212
Colin Cross0ea8ba82019-06-06 14:33:29 -07001213func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001214 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1215 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001216 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001217 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001218 return String(a.overridableAppProperties.Certificate)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001219}
1220
Jiyong Park0f80c182020-01-31 02:49:53 +09001221func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1222 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1223 return true
1224 }
1225 return a.Library.DepIsInSameApex(ctx, dep)
1226}
1227
Jiyong Parkf7487312019-10-17 12:54:30 +09001228func (a *AndroidApp) Privileged() bool {
1229 return Bool(a.appProperties.Privileged)
1230}
1231
Colin Crosse1a85552024-06-14 12:17:37 -07001232func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001233 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001234}
1235
Ivan Lozanod7586b62021-04-01 09:49:36 -04001236func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001237 a.appProperties.PreventInstall = true
1238}
1239
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001240func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1241 a.appProperties.IsCoverageVariant = coverage
1242}
1243
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001244func (a *AndroidApp) EnableCoverageIfNeeded() {}
1245
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001246var _ cc.Coverage = (*AndroidApp)(nil)
1247
Cole Faustb36d31d2024-08-27 16:04:28 -07001248func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1249 a.Library.IDEInfo(ctx, dpInfo)
1250 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001251}
1252
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001253func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1254 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1255}
1256
1257func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1258 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1259}
1260
Colin Cross1b16b0e2019-02-12 14:41:32 -08001261// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001262func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001263 module := &AndroidApp{}
1264
Liz Kammera7a64f32020-07-09 15:16:41 -07001265 module.Module.dexProperties.Optimize.EnabledByDefault = true
1266 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001267 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001268
Colin Crossae5caf52018-05-22 11:11:52 -07001269 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001270 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001271 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001272
Colin Crossce6734e2020-06-15 16:09:53 -07001273 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001274 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001275 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001276 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001277 &module.overridableAppProperties,
1278 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001279
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001280 module.usesLibrary.enforce = true
1281
Colin Crossa4f08812018-10-02 22:03:40 -07001282 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1283 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001284 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001285 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001286
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001287 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1288 a := ctx.Module().(*AndroidApp)
1289
1290 characteristics := ctx.Config().ProductAAPTCharacteristics()
1291 if characteristics == "default" || characteristics == "" {
1292 module.appProperties.Generate_product_characteristics_rro = nil
1293 // no need to create RRO
1294 return
1295 }
1296
1297 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1298 return
1299 }
1300
1301 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1302 rroManifestName := rroPackageName + "_manifest"
1303
1304 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1305 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1306
1307 rroManifestProperties := struct {
1308 Name *string
1309 Tools []string
1310 Out []string
1311 Srcs []string
1312 Cmd *string
1313 }{
1314 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001315 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001316 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001317 Srcs: []string{":" + a.Name() + "{.apk}"},
1318 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001319 }
1320 ctx.CreateModule(genrule.GenRuleFactory, &rroManifestProperties)
1321
1322 rroProperties := struct {
1323 Name *string
1324 Filter_product *string
1325 Aaptflags []string
1326 Manifest *string
1327 Resource_dirs []string
1328 }{
1329 Name: proptools.StringPtr(rroPackageName),
1330 Filter_product: proptools.StringPtr(characteristics),
1331 Aaptflags: []string{"--auto-add-overlay"},
1332 Manifest: proptools.StringPtr(":" + rroManifestName),
1333 Resource_dirs: a.aaptProperties.Resource_dirs,
1334 }
优秀d75e9982024-05-09 07:15:55 +00001335 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1336 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1337 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1338 }
1339 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001340 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1341 })
1342
Colin Cross36242852017-06-23 15:06:31 -07001343 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001344}
Colin Crossae5caf52018-05-22 11:11:52 -07001345
Alix96ea88452023-08-31 15:48:23 +00001346// A dictionary of values to be overridden in the manifest.
1347type Manifest_values struct {
1348 // Overrides the value of package_name in the manifest
1349 ApplicationId *string
1350}
1351
Colin Crossae5caf52018-05-22 11:11:52 -07001352type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001353 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001354 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001355
Seth Moorec6f4b532023-02-02 13:22:26 -08001356 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001357 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001358
1359 // If specified, the mainline module package name in the test config is overwritten by it.
1360 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001361
1362 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001363}
1364
1365type AndroidTest struct {
1366 AndroidApp
1367
1368 appTestProperties appTestProperties
1369
1370 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001371
Dan Shi95d19422020-08-15 12:24:26 -07001372 testConfig android.Path
1373 extraTestConfigs android.Paths
1374 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001375}
1376
Jaewoong Jung0949f312019-09-11 10:25:18 -07001377func (a *AndroidTest) InstallInTestcases() bool {
1378 return true
1379}
1380
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001381type androidTestApp interface {
1382 includedInTestSuite(searchPrefix string) bool
1383}
1384
1385func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1386 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1387}
1388
1389func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1390 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1391}
1392
Colin Crossae5caf52018-05-22 11:11:52 -07001393func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001394 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001395 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001396 if a.appTestProperties.Instrumentation_target_package != nil {
1397 a.additionalAaptFlags = append(a.additionalAaptFlags,
1398 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1399 } else if a.appTestProperties.Instrumentation_for != nil {
1400 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001401 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1402 if overridden {
1403 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1404 }
1405 }
Alix96ea88452023-08-31 15:48:23 +00001406 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1407 if applicationId != nil {
1408 if a.overridableAppProperties.Package_name != nil {
1409 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1410 }
1411 a.aapt.manifestValues.applicationId = *applicationId
1412 }
Colin Crossae5caf52018-05-22 11:11:52 -07001413 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001414
easoncylee5bcff5d2020-04-30 14:57:06 +08001415 for _, module := range a.testProperties.Test_mainline_modules {
1416 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1417 }
1418
Jaewoong Jung39982342020-01-14 10:27:18 -08001419 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
easoncylee5bcff5d2020-04-30 14:57:06 +08001420 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
Jaewoong Jung39982342020-01-14 10:27:18 -08001421 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001422 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001423 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Colin Cross40213022023-12-13 15:19:49 -08001424 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001425 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1426 InstalledFiles: a.data,
1427 OutputFile: a.OutputFile(),
1428 TestConfig: a.testConfig,
1429 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001430 TestSuites: a.testProperties.Test_suites,
1431 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001432 LocalCertificate: a.certificate.AndroidMkString(),
1433 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001434 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001435 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1436 TestOnly: true,
1437 TopLevelTarget: true,
1438 })
1439
Colin Cross303e21f2018-08-07 16:49:25 -07001440}
1441
Jaewoong Jung39982342020-01-14 10:27:18 -08001442func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1443 if testConfig == nil {
1444 return nil
1445 }
1446
1447 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001448 rule := android.NewRuleBuilder(pctx, ctx)
1449 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001450 fixNeeded := false
1451
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001452 // 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 -08001453 if ctx.ModuleName() != a.installApkName {
1454 fixNeeded = true
1455 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1456 }
1457
1458 if a.overridableAppProperties.Package_name != nil {
1459 fixNeeded = true
1460 command.FlagWithInput("--manifest ", a.manifestPath).
1461 FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
1462 }
1463
Seth Moorec6f4b532023-02-02 13:22:26 -08001464 if a.appTestProperties.Mainline_package_name != nil {
1465 fixNeeded = true
1466 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1467 }
1468
Jaewoong Jung39982342020-01-14 10:27:18 -08001469 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001470 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001471 return fixedConfig
1472 }
1473 return testConfig
1474}
1475
Yihan Dong8be09c22024-08-29 15:32:13 +08001476func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1477 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1478 // Instrument the android_test_helper target to log potential API calls at the run time.
1479 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1480 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1481 a.setApiMapper(true)
1482 }
1483 a.AndroidApp.DepsMutator(ctx)
1484}
1485
Colin Cross303e21f2018-08-07 16:49:25 -07001486func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001487 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1488 // Instrument the android_test_helper target to log potential API calls at the run time.
1489 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1490 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1491 a.setApiMapper(true)
1492 }
Colin Cross303e21f2018-08-07 16:49:25 -07001493 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001494}
1495
1496func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1497 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001498 if a.appTestProperties.Instrumentation_for != nil {
1499 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1500 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1501 // use instrumentationForTag instead of libTag.
1502 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1503 }
Colin Crossae5caf52018-05-22 11:11:52 -07001504}
1505
Colin Cross1b16b0e2019-02-12 14:41:32 -08001506// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1507// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001508func AndroidTestFactory() android.Module {
1509 module := &AndroidTest{}
1510
Jared Duke63a3da92022-06-02 19:11:14 +00001511 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001512
1513 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001514 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001515 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001516 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1517 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001518 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001519 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001520
Colin Crossce6734e2020-06-15 16:09:53 -07001521 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001522 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001523 &module.aaptProperties,
1524 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001525 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001526 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001527 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001528
Colin Crossa4f08812018-10-02 22:03:40 -07001529 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1530 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001531 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001532
Colin Crossae5caf52018-05-22 11:11:52 -07001533 return module
1534}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001535
Colin Cross252fc6f2018-10-04 15:22:03 -07001536type appTestHelperAppProperties struct {
1537 // list of compatibility suites (for example "cts", "vts") that the module should be
1538 // installed into.
1539 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001540
1541 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1542 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1543 // explicitly.
1544 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001545
1546 // Install the test into a folder named for the module in all test suites.
1547 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001548
1549 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001550}
1551
1552type AndroidTestHelperApp struct {
1553 AndroidApp
1554
1555 appTestHelperAppProperties appTestHelperAppProperties
1556}
1557
Jaewoong Jung326a9412019-11-21 10:41:00 -08001558func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1559 return true
1560}
1561
Colin Cross1b16b0e2019-02-12 14:41:32 -08001562// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1563// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1564// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001565func AndroidTestHelperAppFactory() android.Module {
1566 module := &AndroidTestHelperApp{}
1567
Jared Duke63a3da92022-06-02 19:11:14 +00001568 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001569 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001570
1571 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001572 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1573 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001574 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001575 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001576
Colin Crossce6734e2020-06-15 16:09:53 -07001577 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001578 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001579 &module.aaptProperties,
1580 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001581 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001582 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001583
1584 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1585 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001586 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001587 return module
1588}
1589
Colin Crossbd01e2a2018-10-04 15:21:03 -07001590type AndroidAppCertificate struct {
1591 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001592
Colin Crossbd01e2a2018-10-04 15:21:03 -07001593 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001594 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001595}
1596
1597type AndroidAppCertificateProperties struct {
1598 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1599 Certificate *string
1600}
1601
Colin Cross1b16b0e2019-02-12 14:41:32 -08001602// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1603// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001604func AndroidAppCertificateFactory() android.Module {
1605 module := &AndroidAppCertificate{}
1606 module.AddProperties(&module.properties)
1607 android.InitAndroidModule(module)
1608 return module
1609}
1610
Colin Crossbd01e2a2018-10-04 15:21:03 -07001611func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1612 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001613 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001614 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1615 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001616 }
1617}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001618
1619type OverrideAndroidApp struct {
1620 android.ModuleBase
1621 android.OverrideModuleBase
1622}
1623
Sasha Smundak613cbb12020-06-05 10:27:23 -07001624func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001625 // All the overrides happen in the base module.
1626 // TODO(jungjw): Check the base module type.
1627}
1628
1629// override_android_app is used to create an android_app module based on another android_app by overriding
1630// some of its properties.
1631func OverrideAndroidAppModuleFactory() android.Module {
1632 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001633 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001634 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001635 &overridableAppProperties{},
1636 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001637
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001638 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001639 android.InitOverrideModule(m)
1640 return m
1641}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001642
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001643type OverrideAndroidTest struct {
1644 android.ModuleBase
1645 android.OverrideModuleBase
1646}
1647
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001648func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001649 // All the overrides happen in the base module.
1650 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001651 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1652 TestOnly: true,
1653 TopLevelTarget: true,
1654 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001655}
1656
1657// override_android_test is used to create an android_app module based on another android_test by overriding
1658// some of its properties.
1659func OverrideAndroidTestModuleFactory() android.Module {
1660 m := &OverrideAndroidTest{}
1661 m.AddProperties(&overridableAppProperties{})
1662 m.AddProperties(&appTestProperties{})
1663
1664 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1665 android.InitOverrideModule(m)
1666 return m
1667}
1668
Colin Cross50ddcc42019-05-16 12:28:22 -07001669type UsesLibraryProperties struct {
1670 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
1671 Uses_libs []string
1672
1673 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1674 // required=false.
1675 Optional_uses_libs []string
1676
1677 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1678 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1679 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001680
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001681 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1682 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1683 // normally is the same as the module name, but there are exceptions.
1684 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001685
1686 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1687 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1688 // added to the APK's manifest's <uses-library> elements.
1689 //
1690 // Care must be taken when using this as it could result in runtime errors if the APK actually
1691 // uses classes provided by the library and which are not provided in any other way.
1692 //
1693 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1694 // android.test.base shared library (and related libraries) but which depend on some common
1695 // libraries that depend on the android.test.base library. Without this those tests will end up
1696 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1697 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1698 // test altogether by providing access to classes that the tests were not expecting. Those tests
1699 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1700 // with the classes provided by the android.test.base library.
1701 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001702
1703 // The module names of optional uses-library libraries that are missing from the source tree.
1704 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001705}
1706
1707// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1708// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1709// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1710// with knowledge of their shared libraries.
1711type usesLibrary struct {
1712 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001713
1714 // Whether to enforce verify_uses_library check.
1715 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001716
1717 // Whether dexpreopt should be disabled
1718 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001719}
1720
Colin Cross4a80a152022-12-21 21:51:52 -08001721func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001722 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001723 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001724 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1725 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001726 // Only add these extra dependencies if the module is an app that depends on framework
1727 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001728 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001729 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001730 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1731 // class loader context for dex2oat. Add them as a dependency with a special tag.
1732 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1733 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1734 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001735 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001736 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
1737 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001738 } else {
1739 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
1740 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001741 }
1742}
1743
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001744// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001745func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001746 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool {
1747 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001748 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001749 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1750 }
1751 return exists
1752 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001753 return optionalUsesLibs
1754}
1755
Ulya Trafimovich24446712021-07-15 14:59:34 +01001756// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1757// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001758func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1759 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001760
1761 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1762 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1763 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1764 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001765 }
1766
Ulya Trafimovich24446712021-07-15 14:59:34 +01001767 ctx.VisitDirectDeps(func(m android.Module) {
1768 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1769 if !isUsesLibTag {
1770 return
1771 }
1772
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001773 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001774
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001775 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1776 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1777 // from implementation libraries by their name, which is different as it has a suffix.
1778 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1779 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1780 return
1781 }
1782 }
1783
Ulya Trafimovich24446712021-07-15 14:59:34 +01001784 if lib, ok := m.(UsesLibraryDependency); ok {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001785 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1786 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1787 // This will be restricted to optional_uses_libs
1788 if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
1789 u.shouldDisableDexpreopt = true
1790 return
1791 }
1792 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001793 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001794 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001795 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001796 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001797 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001798 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001799 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001800 } else if ctx.Config().AllowMissingDependencies() {
1801 ctx.AddMissingDependencies([]string{dep})
1802 } else {
1803 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1804 }
1805 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001806 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001807}
1808
1809// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1810// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1811// unconditionally in the future.
1812func (u *usesLibrary) enforceUsesLibraries() bool {
1813 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
1814 len(u.usesLibraryProperties.Optional_uses_libs) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001815 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001816}
1817
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001818// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
1819func (u *usesLibrary) freezeEnforceUsesLibraries() {
1820 enforce := u.enforceUsesLibraries()
1821 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1822}
1823
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001824// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1825// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1826// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1827// extension: APKs are supposed to end with '.apk').
1828func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001829 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001830
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001831 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001832
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001833 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1834 // check is not necessary, and although it is good to have, it is difficult to maintain on
1835 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1836 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001837 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001838 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001839 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001840 }
1841
Colin Crossf1a035e2020-11-16 17:32:30 -08001842 rule := android.NewRuleBuilder(pctx, ctx)
1843 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001844 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001845 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001846 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001847 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001848
1849 if outputFile != nil {
1850 cmd.FlagWithOutput("-o ", outputFile)
1851 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001852
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001853 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1854 cmd.Flag("--enforce-uses-libraries-relax")
1855 }
1856
Jiakai Zhangf98da192024-04-15 11:15:41 +00001857 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1858 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001859 cmd.FlagWithArg("--uses-library ", lib)
1860 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001861 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001862 cmd.FlagWithArg("--optional-uses-library ", lib)
1863 }
1864
Jiakai Zhangf98da192024-04-15 11:15:41 +00001865 // Also add missing optional uses libs, as the manifest check expects them.
1866 // Note that what we add here are the module names of those missing libs, not library names, while
1867 // the manifest check actually expects library names. However, the case where a library is missing
1868 // and the module name != the library name is too rare for us to handle.
1869 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1870 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1871 }
1872
Colin Crossf1a035e2020-11-16 17:32:30 -08001873 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001874 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001875}
Colin Cross50ddcc42019-05-16 12:28:22 -07001876
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001877// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1878// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001879func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1880 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001881 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001882 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001883}
1884
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001885// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1886// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001887func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1888 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1889 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001890}