blob: 13f1568095b87e097f070cd74fda71394c87f3eb [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 Ketpreechasawat02774e82024-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"
Rashed Abdel-Tawab5b948ab2018-08-09 14:08:53 -0700646 } else if ctx.ModuleName() == "omnirom-res" {
647 // omnirom-res.apk is installed as system/framework/omnirom-res.apk
648 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900649 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800650 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800651 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800652 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800653 }
Colin Cross403cc152020-07-06 14:15:24 -0700654
655 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
656}
657
Rico Wind98e7fa82023-11-27 09:44:03 +0100658func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700659 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000660 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700661 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100662 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700663 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100664 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700665 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Colin Cross50ddcc42019-05-16 12:28:22 -0700666 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100667 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700668 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800669 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700670
Rico Wind98e7fa82023-11-27 09:44:03 +0100671 var packageResources = a.exportPackage
672
Rashed Abdel-Tawab5b948ab2018-08-09 14:08:53 -0700673 if ctx.ModuleName() != "framework-res" && ctx.ModuleName() != "omnirom-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200674 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100675 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
676 aapt2Convert(ctx, protoFile, packageResources, "proto")
677 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
678 }
679
Colin Cross4eae06d2023-06-20 22:40:02 -0700680 var extraSrcJars android.Paths
681 var extraClasspathJars android.Paths
682 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800683 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700684 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
685 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
686 // classpath when compiling everything else, and add it to the final classes jar.
687 extraClasspathJars = android.Paths{a.aapt.rJar}
688 extraCombinedJars = android.Paths{a.aapt.rJar}
689 } else {
690 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
691 // R.java files for the app's package and the packages from all transitive static android_library
692 // dependencies. Compile the srcjar alongside the rest of the sources.
693 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
694 }
695
Colin Crossfdaa6722024-08-23 11:58:08 -0700696 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200697 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100698 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
699 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
700 packageResources = binaryResources
701 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800702 }
Colin Cross30e076a2015-04-13 13:58:27 -0700703
Rico Wind98e7fa82023-11-27 09:44:03 +0100704 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800705}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800706
Sam Delmerico82602492022-06-10 17:05:42 +0000707func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700708 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000709 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700710 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700711 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700712 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800713 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000714 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700715 for _, jni := range jniLibs {
716 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700717 // Only collect coverage for the first target arch if this is a multilib target.
718 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
719 // data file path collisions since the current coverage file path format doesn't contain
720 // arch-related strings. This is fine for now though; the code coverage team doesn't use
721 // multi-arch targets such as test_suite_* for coverage collections yet.
722 //
723 // Work with the team to come up with a new format that handles multilib modules properly
724 // and change this.
725 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700726 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700727 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
728 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700729 }
730 }
Colin Cross403cc152020-07-06 14:15:24 -0700731 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700732 }
733 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800734 return jniJarFile
735}
Colin Crossa4f08812018-10-02 22:03:40 -0700736
Colin Cross403cc152020-07-06 14:15:24 -0700737func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
738 var jniSymbols android.RuleBuilderInstalls
739 for _, jniLib := range a.jniLibs {
740 if jniLib.unstrippedFile != nil {
741 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
742 From: jniLib.unstrippedFile,
743 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
744 })
745 }
746 }
747 return jniSymbols
748}
749
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700750// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
751// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700752func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
753 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700754 if android.SrcIsModule(certPropValue) == "" {
755 var mainCert Certificate
756 if certPropValue != "" {
757 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
758 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800759 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
760 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700761 }
762 } else {
763 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800764 mainCert = Certificate{
765 Pem: pem,
766 Key: key,
767 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700768 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700769 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700770 }
771
Colin Crossbc2c8a72022-09-14 12:45:42 -0700772 if len(certificates) > 0 {
773 mainCertificate = certificates[0]
774 } else {
775 // This can be reached with an empty certificate list if AllowMissingDependencies is set
776 // and the certificate property for this module is a module reference to a missing module.
777 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
778 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
779 }
780 // Set a certificate to avoid panics later when accessing it.
781 mainCertificate = Certificate{
782 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000783 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700784 }
785 }
786
Zyan Wub7550aa2023-05-18 15:46:31 +0800787 if !m.Platform() {
788 certPath := mainCertificate.Pem.String()
789 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
790 if strings.HasPrefix(certPath, systemCertPath) {
791 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
792 allowed := ctx.Config().EnforceSystemCertificateAllowList()
793
794 if enforceSystemCert && !inList(m.Name(), allowed) {
795 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
796 }
797 }
798 }
799
Colin Crossbc2c8a72022-09-14 12:45:42 -0700800 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800801}
802
Jooyung Han39ee1192020-03-23 20:21:11 +0900803func (a *AndroidApp) InstallApkName() string {
804 return a.installApkName
805}
806
Sam Delmerico15809f82023-05-15 17:21:47 -0400807func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000808 if a.appProperties.Privapp_allowlist == nil {
809 return nil
810 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400811
812 isOverrideApp := a.GetOverriddenBy() != ""
813 if !isOverrideApp {
814 // if this is not an override, we don't need to rewrite the existing privapp allowlist
815 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
816 }
817
Andrei Onea580636b2022-08-17 16:53:46 +0000818 if a.overridableAppProperties.Package_name == nil {
819 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
820 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400821
Andrei Onea580636b2022-08-17 16:53:46 +0000822 packageName := *a.overridableAppProperties.Package_name
823 fileName := "privapp_allowlist_" + packageName + ".xml"
824 outPath := android.PathForModuleOut(ctx, fileName).OutputPath
825 ctx.Build(pctx, android.BuildParams{
826 Rule: modifyAllowlist,
827 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
828 Output: outPath,
829 Args: map[string]string{
830 "packageName": packageName,
831 },
832 })
833 return &outPath
834}
835
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800836func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700837 var apkDeps android.Paths
838
Colin Crossff694a82023-12-13 15:54:49 -0800839 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
840 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700841 a.hideApexVariantFromMake = true
842 }
843
Jeongik Cha538c0d02019-07-11 15:54:27 +0900844 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
845 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
846
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000847 // Unlike installApkName, a.stem should respect base module name for override_android_app.
848 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000849 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000850
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800851 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000852 // Both android_app and override_android_app module are expected to possess
853 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
854 // from the base module. Therefore, use a.Name() which represents
855 // the module name for both android_app and override_android_app.
856 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000857 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800858
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700859 if ctx.ModuleName() == "framework-res" {
860 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700861 a.installDir = android.PathForModuleInstall(ctx, "framework")
Rashed Abdel-Tawab5b948ab2018-08-09 14:08:53 -0700862 } else if ctx.ModuleName() == "omnirom-res" {
863 // omnirom-res.apk is installed as system/framework/omnirom-res.apk
864 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900865 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700866 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
867 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800868 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700869 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700870 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700871 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700872 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700873
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100874 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000875 if a.usesLibrary.shouldDisableDexpreopt {
876 a.dexpreopter.disableDexpreopt()
877 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000878
Colin Cross61fb62e2022-06-23 10:46:28 -0700879 var noticeAssetPath android.WritablePath
880 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
881 // The rule to create the notice file can't be generated yet, as the final output path
882 // for the apk isn't known yet. Add the path where the notice file will be generated to the
883 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
884 // be generated later.
885 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
886 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
887 }
888
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000889 // For apps targeting latest target_sdk_version
890 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
891 a.SetEnforceDefaultTargetSdkVersion(true)
892 }
893
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800894 // Process all building blocks, from AAPT to certificates.
895 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100896 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
897 a.usesLibrary.freezeEnforceUsesLibraries()
898
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100899 // Check that the <uses-library> list is coherent with the manifest.
Colin Cross50ddcc42019-05-16 12:28:22 -0700900 if a.usesLibrary.enforceUsesLibraries() {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000901 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
902 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700903 apkDeps = append(apkDeps, manifestCheckFile)
904 }
905
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800906 a.proguardBuildActions(ctx)
907
Colin Cross014489c2020-06-02 20:09:13 -0700908 a.linter.mergedManifest = a.aapt.mergedManifestFile
909 a.linter.manifest = a.aapt.manifestPath
910 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700911 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700912
Rico Wind98e7fa82023-11-27 09:44:03 +0100913 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800914
Jiyong Park92d84042024-05-17 22:58:54 +0000915 // No need to check the SDK version of the JNI deps unless we embed them
916 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
917 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000918 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800919
920 if ctx.Failed() {
921 return
922 }
923
Colin Crossbc2c8a72022-09-14 12:45:42 -0700924 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800925
926 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800927 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700928 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
929 var v4SignatureFile android.WritablePath = nil
930 if v4SigningRequested {
931 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
932 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700933 var lineageFile android.Path
934 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
935 lineageFile = android.PathForModuleSrc(ctx, lineage)
936 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400937 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
938
Rico Wind98e7fa82023-11-27 09:44:03 +0100939 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800940 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700941 if v4SigningRequested {
942 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
943 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800944
Colin Cross61fb62e2022-06-23 10:46:28 -0700945 if a.aapt.noticeFile.Valid() {
946 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -0700947 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -0700948 android.BuildNoticeHtmlOutputFromLicenseMetadata(
949 ctx, noticeFile, "", "",
950 []string{
951 a.installDir.String() + "/",
952 android.PathForModuleInstall(ctx).String() + "/",
953 a.outputFile.String(),
954 })
Bob Badoureef4c1c2022-05-16 12:20:04 -0700955 builder := android.NewRuleBuilder(pctx, ctx)
956 builder.Command().Text("cp").
957 Input(noticeFile).
958 Output(noticeAssetPath)
959 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -0700960 }
961
Colin Crosse560c4a2019-03-19 16:03:11 -0700962 for _, split := range a.aapt.splits {
963 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -0800964 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700965 if v4SigningRequested {
966 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
967 }
Rico Wind98e7fa82023-11-27 09:44:03 +0100968 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -0700969 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -0700970 if v4SigningRequested {
971 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
972 }
Colin Crosse560c4a2019-03-19 16:03:11 -0700973 }
974
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800975 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -0700976 bundleFile := android.PathForModuleOut(ctx, "base.zip")
977 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
978 a.bundleFile = bundleFile
979
Andrei Onea580636b2022-08-17 16:53:46 +0000980 allowlist := a.createPrivappAllowlist(ctx)
981 if allowlist != nil {
982 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
983 }
984
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800985 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +0000986 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
987 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -0400988 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +0000989 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
990 allowlistInstallFilename := a.installApkName + ".xml"
991 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -0400992 }
993
Colin Cross09ad3a62023-11-15 12:29:33 -0800994 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +0900995 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -0700996 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
997 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +0900998 }
Jiyong Park25b92222024-05-17 22:58:54 +0000999 // If we don't embed jni libs, make sure that those are installed along with the
1000 // app, and also place symlinks to the installed paths under the lib/<arch>
1001 // directory of the app installation directory. ex:
1002 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1003 if !a.embeddedJniLibs {
1004 for _, jniLib := range jniLibs {
1005 archStr := jniLib.target.Arch.ArchType.String()
1006 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1007 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001008 // install the symlink itself
1009 symlinkName := installedLib.Base()
1010 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1011 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1012 }
1013 }
1014 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001015 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001016 }
Artur Satayev1111b842020-04-27 19:05:28 +01001017
Colin Crossa6182ab2024-08-21 10:47:44 -07001018 ctx.CheckbuildFile(a.outputFile)
1019
Artur Satayev1111b842020-04-27 19:05:28 +01001020 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001021
1022 providePrebuiltInfo(ctx,
1023 prebuiltInfoProps{
1024 baseModuleName: a.BaseModuleName(),
1025 isPrebuilt: false,
1026 },
1027 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001028
1029 a.setOutputFiles(ctx)
1030}
1031
1032func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1033 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1034 if a.aaptSrcJar != nil {
1035 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1036 }
1037 if a.rJar != nil {
1038 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1039 }
1040 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1041 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1042 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1043 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001044}
1045
Colin Crossc2d24052020-05-13 11:05:02 -07001046type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001047 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001048 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001049 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1050}
1051
1052func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1053 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001054 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001055
Colin Crossc2d24052020-05-13 11:05:02 -07001056 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001057 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1058 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001059 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001060 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1061 checkNativeSdkVersion, func(dep cc.LinkableInterface) bool {
1062 return !dep.IsNdk(ctx.Config()) && !dep.IsStubs()
1063 })
1064
1065 var certificates []Certificate
1066
1067 ctx.VisitDirectDeps(func(module android.Module) {
1068 otherName := ctx.OtherModuleName(module)
1069 tag := ctx.OtherModuleDependencyTag(module)
1070
1071 if tag == certificateTag {
1072 if dep, ok := module.(*AndroidAppCertificate); ok {
1073 certificates = append(certificates, dep.Certificate)
1074 } else {
1075 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1076 }
1077 }
1078 })
1079 return jniLib, prebuiltJniPackages, certificates
1080}
1081
1082func collectJniDeps(ctx android.ModuleContext,
1083 shouldCollectRecursiveNativeDeps bool,
1084 checkNativeSdkVersion bool,
1085 filter func(cc.LinkableInterface) bool) ([]jniLib, android.Paths) {
1086 var jniLibs []jniLib
1087 var prebuiltJniPackages android.Paths
1088 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001089
Peter Collingbournead84f972019-12-17 16:46:18 -08001090 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001091 otherName := ctx.OtherModuleName(module)
1092 tag := ctx.OtherModuleDependencyTag(module)
1093
Colin Crossf0913fb2020-07-29 12:59:39 -07001094 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001095 if dep, ok := module.(cc.LinkableInterface); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001096 if filter != nil && !filter(dep) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001097 return false
1098 }
1099
Colin Crossa4f08812018-10-02 22:03:40 -07001100 lib := dep.OutputFile()
1101 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001102 path := lib.Path()
1103 if seenModulePaths[path.String()] {
1104 return false
1105 }
1106 seenModulePaths[path.String()] = true
1107
1108 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1109 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1110 otherName)
1111 }
1112
Colin Crossa4f08812018-10-02 22:03:40 -07001113 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001114 name: ctx.OtherModuleName(module),
1115 path: path,
1116 target: module.Target(),
1117 coverageFile: dep.CoverageOutputFile(),
1118 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001119 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001120 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001121 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001122 } else if ctx.Config().AllowMissingDependencies() {
1123 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001124 } else {
1125 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1126 }
1127 } else {
1128 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001129 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001130
1131 return shouldCollectRecursiveNativeDeps
1132 }
1133
Colin Cross313aa542023-12-13 13:47:44 -08001134 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001135 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1136 }
1137
Peter Collingbournead84f972019-12-17 16:46:18 -08001138 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001139 })
1140
Makoto Onuki2ca84272024-02-10 00:15:21 +00001141 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001142}
1143
Jooyung Han749dc692020-04-15 11:03:39 +09001144func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001145 ctx.WalkDeps(func(child, parent android.Module) bool {
1146 isExternal := !a.DepIsInSameApex(ctx, child)
1147 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001148 if !do(ctx, parent, am, isExternal) {
1149 return false
1150 }
Artur Satayev1111b842020-04-27 19:05:28 +01001151 }
1152 return !isExternal
1153 })
1154}
1155
1156func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1157 if ctx.Host() {
1158 return
1159 }
1160
1161 depsInfo := android.DepNameToDepInfoMap{}
Jooyung Han749dc692020-04-15 11:03:39 +09001162 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001163 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001164
1165 // Skip dependencies that are only available to APEXes; they are developed with updatability
1166 // in mind and don't need manual approval.
1167 if to.(android.ApexModule).NotAvailableForPlatform() {
1168 return true
1169 }
1170
Artur Satayev1111b842020-04-27 19:05:28 +01001171 if info, exist := depsInfo[depName]; exist {
1172 info.From = append(info.From, from.Name())
1173 info.IsExternal = info.IsExternal && externalDep
1174 depsInfo[depName] = info
1175 } else {
1176 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001177 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001178 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001179 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001180 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1181 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001182 }
Jiyong Park92315372021-04-02 08:45:46 +09001183 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1184 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1185 // string
1186 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001187 toMinSdkVersion = v
1188 }
Artur Satayev1111b842020-04-27 19:05:28 +01001189 }
1190 depsInfo[depName] = android.ApexModuleDepInfo{
1191 To: depName,
1192 From: []string{from.Name()},
1193 IsExternal: externalDep,
1194 MinSdkVersion: toMinSdkVersion,
1195 }
1196 }
Jooyung Han749dc692020-04-15 11:03:39 +09001197 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001198 })
1199
Jiyong Park92315372021-04-02 08:45:46 +09001200 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001201}
1202
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001203func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1204 return a.appProperties.EnforceDefaultTargetSdkVersion
1205}
1206
1207func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1208 a.appProperties.EnforceDefaultTargetSdkVersion = val
1209}
1210
Artur Satayev849f8442020-04-28 14:57:42 +01001211func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001212 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001213}
1214
Spandan Das42e89502022-05-06 22:12:55 +00001215func (a *AndroidApp) SetUpdatable(val bool) {
1216 a.appProperties.Updatable = &val
1217}
1218
Colin Cross0ea8ba82019-06-06 14:33:29 -07001219func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001220 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1221 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001222 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001223 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001224 return String(a.overridableAppProperties.Certificate)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001225}
1226
Jiyong Park0f80c182020-01-31 02:49:53 +09001227func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1228 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1229 return true
1230 }
1231 return a.Library.DepIsInSameApex(ctx, dep)
1232}
1233
Jiyong Parkf7487312019-10-17 12:54:30 +09001234func (a *AndroidApp) Privileged() bool {
1235 return Bool(a.appProperties.Privileged)
1236}
1237
Colin Crosse1a85552024-06-14 12:17:37 -07001238func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001239 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001240}
1241
Ivan Lozanod7586b62021-04-01 09:49:36 -04001242func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001243 a.appProperties.PreventInstall = true
1244}
1245
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001246func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1247 a.appProperties.IsCoverageVariant = coverage
1248}
1249
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001250func (a *AndroidApp) EnableCoverageIfNeeded() {}
1251
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001252var _ cc.Coverage = (*AndroidApp)(nil)
1253
Cole Faustb36d31d2024-08-27 16:04:28 -07001254func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1255 a.Library.IDEInfo(ctx, dpInfo)
1256 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001257}
1258
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001259func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1260 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1261}
1262
1263func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1264 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1265}
1266
Colin Cross1b16b0e2019-02-12 14:41:32 -08001267// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001268func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001269 module := &AndroidApp{}
1270
Liz Kammera7a64f32020-07-09 15:16:41 -07001271 module.Module.dexProperties.Optimize.EnabledByDefault = true
1272 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001273 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001274
Colin Crossae5caf52018-05-22 11:11:52 -07001275 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001276 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001277 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001278
Colin Crossce6734e2020-06-15 16:09:53 -07001279 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001280 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001281 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001282 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001283 &module.overridableAppProperties,
1284 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001285
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001286 module.usesLibrary.enforce = true
1287
Colin Crossa4f08812018-10-02 22:03:40 -07001288 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1289 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001290 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001291 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001292
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001293 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1294 a := ctx.Module().(*AndroidApp)
1295
1296 characteristics := ctx.Config().ProductAAPTCharacteristics()
1297 if characteristics == "default" || characteristics == "" {
1298 module.appProperties.Generate_product_characteristics_rro = nil
1299 // no need to create RRO
1300 return
1301 }
1302
1303 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1304 return
1305 }
1306
1307 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1308 rroManifestName := rroPackageName + "_manifest"
1309
1310 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1311 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1312
1313 rroManifestProperties := struct {
1314 Name *string
1315 Tools []string
1316 Out []string
1317 Srcs []string
1318 Cmd *string
1319 }{
1320 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001321 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001322 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001323 Srcs: []string{":" + a.Name() + "{.apk}"},
1324 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001325 }
1326 ctx.CreateModule(genrule.GenRuleFactory, &rroManifestProperties)
1327
1328 rroProperties := struct {
1329 Name *string
1330 Filter_product *string
1331 Aaptflags []string
1332 Manifest *string
1333 Resource_dirs []string
1334 }{
1335 Name: proptools.StringPtr(rroPackageName),
1336 Filter_product: proptools.StringPtr(characteristics),
1337 Aaptflags: []string{"--auto-add-overlay"},
1338 Manifest: proptools.StringPtr(":" + rroManifestName),
1339 Resource_dirs: a.aaptProperties.Resource_dirs,
1340 }
优秀d75e9982024-05-09 07:15:55 +00001341 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1342 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1343 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1344 }
1345 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001346 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1347 })
1348
Colin Cross36242852017-06-23 15:06:31 -07001349 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001350}
Colin Crossae5caf52018-05-22 11:11:52 -07001351
Alix96ea88452023-08-31 15:48:23 +00001352// A dictionary of values to be overridden in the manifest.
1353type Manifest_values struct {
1354 // Overrides the value of package_name in the manifest
1355 ApplicationId *string
1356}
1357
Colin Crossae5caf52018-05-22 11:11:52 -07001358type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001359 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001360 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001361
Seth Moorec6f4b532023-02-02 13:22:26 -08001362 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001363 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001364
1365 // If specified, the mainline module package name in the test config is overwritten by it.
1366 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001367
1368 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001369}
1370
1371type AndroidTest struct {
1372 AndroidApp
1373
1374 appTestProperties appTestProperties
1375
1376 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001377
Dan Shi95d19422020-08-15 12:24:26 -07001378 testConfig android.Path
1379 extraTestConfigs android.Paths
1380 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001381}
1382
Jaewoong Jung0949f312019-09-11 10:25:18 -07001383func (a *AndroidTest) InstallInTestcases() bool {
1384 return true
1385}
1386
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001387type androidTestApp interface {
1388 includedInTestSuite(searchPrefix string) bool
1389}
1390
1391func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1392 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1393}
1394
1395func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1396 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1397}
1398
Colin Crossae5caf52018-05-22 11:11:52 -07001399func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001400 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001401 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001402 if a.appTestProperties.Instrumentation_target_package != nil {
1403 a.additionalAaptFlags = append(a.additionalAaptFlags,
1404 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1405 } else if a.appTestProperties.Instrumentation_for != nil {
1406 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001407 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1408 if overridden {
1409 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1410 }
1411 }
Alix96ea88452023-08-31 15:48:23 +00001412 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1413 if applicationId != nil {
1414 if a.overridableAppProperties.Package_name != nil {
1415 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1416 }
1417 a.aapt.manifestValues.applicationId = *applicationId
1418 }
Colin Crossae5caf52018-05-22 11:11:52 -07001419 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001420
easoncylee5bcff5d2020-04-30 14:57:06 +08001421 for _, module := range a.testProperties.Test_mainline_modules {
1422 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1423 }
1424
Jaewoong Jung39982342020-01-14 10:27:18 -08001425 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
easoncylee5bcff5d2020-04-30 14:57:06 +08001426 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
Jaewoong Jung39982342020-01-14 10:27:18 -08001427 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001428 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001429 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Colin Cross40213022023-12-13 15:19:49 -08001430 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001431 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1432 InstalledFiles: a.data,
1433 OutputFile: a.OutputFile(),
1434 TestConfig: a.testConfig,
1435 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001436 TestSuites: a.testProperties.Test_suites,
1437 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001438 LocalCertificate: a.certificate.AndroidMkString(),
1439 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001440 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001441 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1442 TestOnly: true,
1443 TopLevelTarget: true,
1444 })
1445
Colin Cross303e21f2018-08-07 16:49:25 -07001446}
1447
Jaewoong Jung39982342020-01-14 10:27:18 -08001448func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1449 if testConfig == nil {
1450 return nil
1451 }
1452
1453 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001454 rule := android.NewRuleBuilder(pctx, ctx)
1455 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001456 fixNeeded := false
1457
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001458 // 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 -08001459 if ctx.ModuleName() != a.installApkName {
1460 fixNeeded = true
1461 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1462 }
1463
1464 if a.overridableAppProperties.Package_name != nil {
1465 fixNeeded = true
1466 command.FlagWithInput("--manifest ", a.manifestPath).
1467 FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
1468 }
1469
Seth Moorec6f4b532023-02-02 13:22:26 -08001470 if a.appTestProperties.Mainline_package_name != nil {
1471 fixNeeded = true
1472 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1473 }
1474
Jaewoong Jung39982342020-01-14 10:27:18 -08001475 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001476 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001477 return fixedConfig
1478 }
1479 return testConfig
1480}
1481
Yihan Dong8be09c22024-08-29 15:32:13 +08001482func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1483 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1484 // Instrument the android_test_helper target to log potential API calls at the run time.
1485 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1486 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1487 a.setApiMapper(true)
1488 }
1489 a.AndroidApp.DepsMutator(ctx)
1490}
1491
Colin Cross303e21f2018-08-07 16:49:25 -07001492func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001493 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1494 // Instrument the android_test_helper target to log potential API calls at the run time.
1495 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1496 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1497 a.setApiMapper(true)
1498 }
Colin Cross303e21f2018-08-07 16:49:25 -07001499 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001500}
1501
1502func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1503 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001504 if a.appTestProperties.Instrumentation_for != nil {
1505 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1506 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1507 // use instrumentationForTag instead of libTag.
1508 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1509 }
Colin Crossae5caf52018-05-22 11:11:52 -07001510}
1511
Colin Cross1b16b0e2019-02-12 14:41:32 -08001512// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1513// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001514func AndroidTestFactory() android.Module {
1515 module := &AndroidTest{}
1516
Jared Duke63a3da92022-06-02 19:11:14 +00001517 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001518
1519 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001520 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001521 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001522 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1523 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001524 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001525 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001526
Colin Crossce6734e2020-06-15 16:09:53 -07001527 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001528 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001529 &module.aaptProperties,
1530 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001531 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001532 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001533 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001534
Colin Crossa4f08812018-10-02 22:03:40 -07001535 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1536 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001537 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001538
Colin Crossae5caf52018-05-22 11:11:52 -07001539 return module
1540}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001541
Colin Cross252fc6f2018-10-04 15:22:03 -07001542type appTestHelperAppProperties struct {
1543 // list of compatibility suites (for example "cts", "vts") that the module should be
1544 // installed into.
1545 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001546
1547 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1548 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1549 // explicitly.
1550 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001551
1552 // Install the test into a folder named for the module in all test suites.
1553 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001554
1555 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001556}
1557
1558type AndroidTestHelperApp struct {
1559 AndroidApp
1560
1561 appTestHelperAppProperties appTestHelperAppProperties
1562}
1563
Jaewoong Jung326a9412019-11-21 10:41:00 -08001564func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1565 return true
1566}
1567
Colin Cross1b16b0e2019-02-12 14:41:32 -08001568// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1569// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1570// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001571func AndroidTestHelperAppFactory() android.Module {
1572 module := &AndroidTestHelperApp{}
1573
Jared Duke63a3da92022-06-02 19:11:14 +00001574 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001575 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001576
1577 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001578 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1579 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001580 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001581 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001582
Colin Crossce6734e2020-06-15 16:09:53 -07001583 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001584 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001585 &module.aaptProperties,
1586 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001587 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001588 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001589
1590 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1591 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001592 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001593 return module
1594}
1595
Colin Crossbd01e2a2018-10-04 15:21:03 -07001596type AndroidAppCertificate struct {
1597 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001598
Colin Crossbd01e2a2018-10-04 15:21:03 -07001599 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001600 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001601}
1602
1603type AndroidAppCertificateProperties struct {
1604 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1605 Certificate *string
1606}
1607
Colin Cross1b16b0e2019-02-12 14:41:32 -08001608// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1609// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001610func AndroidAppCertificateFactory() android.Module {
1611 module := &AndroidAppCertificate{}
1612 module.AddProperties(&module.properties)
1613 android.InitAndroidModule(module)
1614 return module
1615}
1616
Colin Crossbd01e2a2018-10-04 15:21:03 -07001617func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1618 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001619 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001620 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1621 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001622 }
1623}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001624
1625type OverrideAndroidApp struct {
1626 android.ModuleBase
1627 android.OverrideModuleBase
1628}
1629
Sasha Smundak613cbb12020-06-05 10:27:23 -07001630func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001631 // All the overrides happen in the base module.
1632 // TODO(jungjw): Check the base module type.
1633}
1634
1635// override_android_app is used to create an android_app module based on another android_app by overriding
1636// some of its properties.
1637func OverrideAndroidAppModuleFactory() android.Module {
1638 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001639 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001640 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001641 &overridableAppProperties{},
1642 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001643
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001644 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001645 android.InitOverrideModule(m)
1646 return m
1647}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001648
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001649type OverrideAndroidTest struct {
1650 android.ModuleBase
1651 android.OverrideModuleBase
1652}
1653
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001654func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001655 // All the overrides happen in the base module.
1656 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001657 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1658 TestOnly: true,
1659 TopLevelTarget: true,
1660 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001661}
1662
1663// override_android_test is used to create an android_app module based on another android_test by overriding
1664// some of its properties.
1665func OverrideAndroidTestModuleFactory() android.Module {
1666 m := &OverrideAndroidTest{}
1667 m.AddProperties(&overridableAppProperties{})
1668 m.AddProperties(&appTestProperties{})
1669
1670 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1671 android.InitOverrideModule(m)
1672 return m
1673}
1674
Colin Cross50ddcc42019-05-16 12:28:22 -07001675type UsesLibraryProperties struct {
1676 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
1677 Uses_libs []string
1678
1679 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1680 // required=false.
1681 Optional_uses_libs []string
1682
1683 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1684 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1685 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001686
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001687 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1688 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1689 // normally is the same as the module name, but there are exceptions.
1690 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001691
1692 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1693 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1694 // added to the APK's manifest's <uses-library> elements.
1695 //
1696 // Care must be taken when using this as it could result in runtime errors if the APK actually
1697 // uses classes provided by the library and which are not provided in any other way.
1698 //
1699 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1700 // android.test.base shared library (and related libraries) but which depend on some common
1701 // libraries that depend on the android.test.base library. Without this those tests will end up
1702 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1703 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1704 // test altogether by providing access to classes that the tests were not expecting. Those tests
1705 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1706 // with the classes provided by the android.test.base library.
1707 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001708
1709 // The module names of optional uses-library libraries that are missing from the source tree.
1710 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001711}
1712
1713// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1714// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1715// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1716// with knowledge of their shared libraries.
1717type usesLibrary struct {
1718 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001719
1720 // Whether to enforce verify_uses_library check.
1721 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001722
1723 // Whether dexpreopt should be disabled
1724 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001725}
1726
Colin Cross4a80a152022-12-21 21:51:52 -08001727func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001728 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001729 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001730 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1731 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001732 // Only add these extra dependencies if the module is an app that depends on framework
1733 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001734 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001735 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001736 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1737 // class loader context for dex2oat. Add them as a dependency with a special tag.
1738 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1739 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1740 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001741 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001742 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
1743 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001744 } else {
1745 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
1746 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001747 }
1748}
1749
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001750// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001751func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001752 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool {
1753 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001754 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001755 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1756 }
1757 return exists
1758 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001759 return optionalUsesLibs
1760}
1761
Ulya Trafimovich24446712021-07-15 14:59:34 +01001762// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1763// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001764func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1765 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001766
1767 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1768 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1769 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1770 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001771 }
1772
Ulya Trafimovich24446712021-07-15 14:59:34 +01001773 ctx.VisitDirectDeps(func(m android.Module) {
1774 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1775 if !isUsesLibTag {
1776 return
1777 }
1778
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001779 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001780
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001781 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1782 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1783 // from implementation libraries by their name, which is different as it has a suffix.
1784 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1785 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1786 return
1787 }
1788 }
1789
Spandan Das0727ba72024-02-13 16:37:43 +00001790 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1791 // This will be restricted to optional_uses_libs
1792 if sdklib, ok := m.(SdkLibraryDependency); ok {
1793 if tag == usesLibOptTag && sdklib.DexJarBuildPath(ctx).PathOrNil() == nil {
1794 u.shouldDisableDexpreopt = true
1795 return
1796 }
1797 }
1798
Ulya Trafimovich24446712021-07-15 14:59:34 +01001799 if lib, ok := m.(UsesLibraryDependency); ok {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001800 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001801 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001802 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001803 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001804 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001805 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001806 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001807 } else if ctx.Config().AllowMissingDependencies() {
1808 ctx.AddMissingDependencies([]string{dep})
1809 } else {
1810 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1811 }
1812 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001813 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001814}
1815
1816// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1817// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1818// unconditionally in the future.
1819func (u *usesLibrary) enforceUsesLibraries() bool {
1820 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
1821 len(u.usesLibraryProperties.Optional_uses_libs) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001822 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001823}
1824
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001825// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
1826func (u *usesLibrary) freezeEnforceUsesLibraries() {
1827 enforce := u.enforceUsesLibraries()
1828 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1829}
1830
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001831// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1832// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1833// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1834// extension: APKs are supposed to end with '.apk').
1835func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001836 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001837
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001838 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001839
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001840 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1841 // check is not necessary, and although it is good to have, it is difficult to maintain on
1842 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1843 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001844 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001845 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001846 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001847 }
1848
Colin Crossf1a035e2020-11-16 17:32:30 -08001849 rule := android.NewRuleBuilder(pctx, ctx)
1850 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001851 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001852 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001853 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001854 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001855
1856 if outputFile != nil {
1857 cmd.FlagWithOutput("-o ", outputFile)
1858 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001859
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001860 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1861 cmd.Flag("--enforce-uses-libraries-relax")
1862 }
1863
Jiakai Zhangf98da192024-04-15 11:15:41 +00001864 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1865 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001866 cmd.FlagWithArg("--uses-library ", lib)
1867 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001868 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001869 cmd.FlagWithArg("--optional-uses-library ", lib)
1870 }
1871
Jiakai Zhangf98da192024-04-15 11:15:41 +00001872 // Also add missing optional uses libs, as the manifest check expects them.
1873 // Note that what we add here are the module names of those missing libs, not library names, while
1874 // the manifest check actually expects library names. However, the case where a library is missing
1875 // and the module name != the library name is too rare for us to handle.
1876 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1877 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1878 }
1879
Colin Crossf1a035e2020-11-16 17:32:30 -08001880 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001881 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001882}
Colin Cross50ddcc42019-05-16 12:28:22 -07001883
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001884// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1885// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001886func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1887 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001888 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001889 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001890}
1891
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001892// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1893// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001894func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1895 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1896 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001897}