blob: f35e4c3d47aad89a2f090b2bb09badb9e0076e3b [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() {
586 a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
587 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000588
Rico Winda2fa2632024-03-13 13:09:17 +0100589 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200590 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000591
592 aconfigTextFilePaths := getAconfigFilePaths(ctx)
593
Alixf7a10272023-09-27 16:47:56 +0000594 a.aapt.buildActions(ctx,
595 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000596 sdkContext: android.SdkContext(a),
597 classLoaderContexts: a.classLoaderContexts,
598 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
599 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100600 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000601 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000602 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000603 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000604 },
605 )
Colin Cross30e076a2015-04-13 13:58:27 -0700606
Colin Cross46c9b8b2017-06-22 16:51:17 -0700607 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700608 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000609
610 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
611 AconfigTextFiles: aconfigTextFilePaths,
612 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800613}
Colin Cross30e076a2015-04-13 13:58:27 -0700614
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800615func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700616 var staticLibProguardFlagFiles android.Paths
617 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800618 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400619 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
620 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
621 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700622 }
623 })
624
625 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
626
Colin Cross312634e2023-11-21 15:13:56 -0800627 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200628 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100629 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
630 // live for code references and (transitively) mark these as live.
631 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
632 // dead code alive)
633 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
634 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800635}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800636
Colin Cross403cc152020-07-06 14:15:24 -0700637func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800638 var installDir string
639 if ctx.ModuleName() == "framework-res" {
640 // framework-res.apk is installed as system/framework/framework-res.apk
641 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900642 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800643 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800644 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800645 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800646 }
Colin Cross403cc152020-07-06 14:15:24 -0700647
648 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
649}
650
Rico Wind98e7fa82023-11-27 09:44:03 +0100651func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700652 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000653 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700654 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100655 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700656 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100657 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700658 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Colin Cross50ddcc42019-05-16 12:28:22 -0700659 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100660 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700661 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800662 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700663
Rico Wind98e7fa82023-11-27 09:44:03 +0100664 var packageResources = a.exportPackage
665
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800666 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200667 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100668 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
669 aapt2Convert(ctx, protoFile, packageResources, "proto")
670 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
671 }
672
Colin Cross4eae06d2023-06-20 22:40:02 -0700673 var extraSrcJars android.Paths
674 var extraClasspathJars android.Paths
675 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800676 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700677 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
678 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
679 // classpath when compiling everything else, and add it to the final classes jar.
680 extraClasspathJars = android.Paths{a.aapt.rJar}
681 extraCombinedJars = android.Paths{a.aapt.rJar}
682 } else {
683 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
684 // R.java files for the app's package and the packages from all transitive static android_library
685 // dependencies. Compile the srcjar alongside the rest of the sources.
686 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
687 }
688
689 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
Rico Wind936754c2024-05-07 09:08:31 +0200690 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100691 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
692 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
693 packageResources = binaryResources
694 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800695 }
Colin Cross30e076a2015-04-13 13:58:27 -0700696
Rico Wind98e7fa82023-11-27 09:44:03 +0100697 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800698}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800699
Sam Delmerico82602492022-06-10 17:05:42 +0000700func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700701 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000702 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700703 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700704 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700705 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800706 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000707 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700708 for _, jni := range jniLibs {
709 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700710 // Only collect coverage for the first target arch if this is a multilib target.
711 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
712 // data file path collisions since the current coverage file path format doesn't contain
713 // arch-related strings. This is fine for now though; the code coverage team doesn't use
714 // multi-arch targets such as test_suite_* for coverage collections yet.
715 //
716 // Work with the team to come up with a new format that handles multilib modules properly
717 // and change this.
718 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700719 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700720 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
721 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700722 }
723 }
Colin Cross403cc152020-07-06 14:15:24 -0700724 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700725 }
726 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800727 return jniJarFile
728}
Colin Crossa4f08812018-10-02 22:03:40 -0700729
Colin Cross403cc152020-07-06 14:15:24 -0700730func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
731 var jniSymbols android.RuleBuilderInstalls
732 for _, jniLib := range a.jniLibs {
733 if jniLib.unstrippedFile != nil {
734 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
735 From: jniLib.unstrippedFile,
736 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
737 })
738 }
739 }
740 return jniSymbols
741}
742
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700743// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
744// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700745func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
746 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700747 if android.SrcIsModule(certPropValue) == "" {
748 var mainCert Certificate
749 if certPropValue != "" {
750 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
751 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800752 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
753 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700754 }
755 } else {
756 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800757 mainCert = Certificate{
758 Pem: pem,
759 Key: key,
760 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700761 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700762 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700763 }
764
Colin Crossbc2c8a72022-09-14 12:45:42 -0700765 if len(certificates) > 0 {
766 mainCertificate = certificates[0]
767 } else {
768 // This can be reached with an empty certificate list if AllowMissingDependencies is set
769 // and the certificate property for this module is a module reference to a missing module.
770 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
771 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
772 }
773 // Set a certificate to avoid panics later when accessing it.
774 mainCertificate = Certificate{
775 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000776 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700777 }
778 }
779
Zyan Wub7550aa2023-05-18 15:46:31 +0800780 if !m.Platform() {
781 certPath := mainCertificate.Pem.String()
782 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
783 if strings.HasPrefix(certPath, systemCertPath) {
784 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
785 allowed := ctx.Config().EnforceSystemCertificateAllowList()
786
787 if enforceSystemCert && !inList(m.Name(), allowed) {
788 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
789 }
790 }
791 }
792
Colin Crossbc2c8a72022-09-14 12:45:42 -0700793 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800794}
795
Jooyung Han39ee1192020-03-23 20:21:11 +0900796func (a *AndroidApp) InstallApkName() string {
797 return a.installApkName
798}
799
Sam Delmerico15809f82023-05-15 17:21:47 -0400800func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000801 if a.appProperties.Privapp_allowlist == nil {
802 return nil
803 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400804
805 isOverrideApp := a.GetOverriddenBy() != ""
806 if !isOverrideApp {
807 // if this is not an override, we don't need to rewrite the existing privapp allowlist
808 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
809 }
810
Andrei Onea580636b2022-08-17 16:53:46 +0000811 if a.overridableAppProperties.Package_name == nil {
812 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
813 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400814
Andrei Onea580636b2022-08-17 16:53:46 +0000815 packageName := *a.overridableAppProperties.Package_name
816 fileName := "privapp_allowlist_" + packageName + ".xml"
817 outPath := android.PathForModuleOut(ctx, fileName).OutputPath
818 ctx.Build(pctx, android.BuildParams{
819 Rule: modifyAllowlist,
820 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
821 Output: outPath,
822 Args: map[string]string{
823 "packageName": packageName,
824 },
825 })
826 return &outPath
827}
828
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800829func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700830 var apkDeps android.Paths
831
Colin Crossff694a82023-12-13 15:54:49 -0800832 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
833 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700834 a.hideApexVariantFromMake = true
835 }
836
Jeongik Cha538c0d02019-07-11 15:54:27 +0900837 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
838 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
839
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000840 // Unlike installApkName, a.stem should respect base module name for override_android_app.
841 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000842 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000843
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800844 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000845 // Both android_app and override_android_app module are expected to possess
846 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
847 // from the base module. Therefore, use a.Name() which represents
848 // the module name for both android_app and override_android_app.
849 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000850 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800851
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700852 if ctx.ModuleName() == "framework-res" {
853 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700854 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900855 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700856 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
857 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800858 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700859 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700860 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700861 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700862 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700863
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100864 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000865 if a.usesLibrary.shouldDisableDexpreopt {
866 a.dexpreopter.disableDexpreopt()
867 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000868
Colin Cross61fb62e2022-06-23 10:46:28 -0700869 var noticeAssetPath android.WritablePath
870 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
871 // The rule to create the notice file can't be generated yet, as the final output path
872 // for the apk isn't known yet. Add the path where the notice file will be generated to the
873 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
874 // be generated later.
875 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
876 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
877 }
878
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000879 // For apps targeting latest target_sdk_version
880 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
881 a.SetEnforceDefaultTargetSdkVersion(true)
882 }
883
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800884 // Process all building blocks, from AAPT to certificates.
885 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100886 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
887 a.usesLibrary.freezeEnforceUsesLibraries()
888
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100889 // Check that the <uses-library> list is coherent with the manifest.
Colin Cross50ddcc42019-05-16 12:28:22 -0700890 if a.usesLibrary.enforceUsesLibraries() {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000891 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
892 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700893 apkDeps = append(apkDeps, manifestCheckFile)
894 }
895
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800896 a.proguardBuildActions(ctx)
897
Colin Cross014489c2020-06-02 20:09:13 -0700898 a.linter.mergedManifest = a.aapt.mergedManifestFile
899 a.linter.manifest = a.aapt.manifestPath
900 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700901 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700902
Rico Wind98e7fa82023-11-27 09:44:03 +0100903 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800904
Jiyong Park92d84042024-05-17 22:58:54 +0000905 // No need to check the SDK version of the JNI deps unless we embed them
906 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
907 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000908 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800909
910 if ctx.Failed() {
911 return
912 }
913
Colin Crossbc2c8a72022-09-14 12:45:42 -0700914 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800915
916 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800917 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700918 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
919 var v4SignatureFile android.WritablePath = nil
920 if v4SigningRequested {
921 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
922 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700923 var lineageFile android.Path
924 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
925 lineageFile = android.PathForModuleSrc(ctx, lineage)
926 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400927 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
928
Rico Wind98e7fa82023-11-27 09:44:03 +0100929 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800930 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700931 if v4SigningRequested {
932 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
933 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800934
Colin Cross61fb62e2022-06-23 10:46:28 -0700935 if a.aapt.noticeFile.Valid() {
936 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -0700937 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -0700938 android.BuildNoticeHtmlOutputFromLicenseMetadata(
939 ctx, noticeFile, "", "",
940 []string{
941 a.installDir.String() + "/",
942 android.PathForModuleInstall(ctx).String() + "/",
943 a.outputFile.String(),
944 })
Bob Badoureef4c1c2022-05-16 12:20:04 -0700945 builder := android.NewRuleBuilder(pctx, ctx)
946 builder.Command().Text("cp").
947 Input(noticeFile).
948 Output(noticeAssetPath)
949 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -0700950 }
951
Colin Crosse560c4a2019-03-19 16:03:11 -0700952 for _, split := range a.aapt.splits {
953 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -0800954 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700955 if v4SigningRequested {
956 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
957 }
Rico Wind98e7fa82023-11-27 09:44:03 +0100958 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -0700959 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -0700960 if v4SigningRequested {
961 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
962 }
Colin Crosse560c4a2019-03-19 16:03:11 -0700963 }
964
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800965 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -0700966 bundleFile := android.PathForModuleOut(ctx, "base.zip")
967 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
968 a.bundleFile = bundleFile
969
Andrei Onea580636b2022-08-17 16:53:46 +0000970 allowlist := a.createPrivappAllowlist(ctx)
971 if allowlist != nil {
972 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
973 }
974
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800975 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +0000976 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
977 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -0400978 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +0000979 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
980 allowlistInstallFilename := a.installApkName + ".xml"
981 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -0400982 }
983
Colin Cross09ad3a62023-11-15 12:29:33 -0800984 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +0900985 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -0700986 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
987 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +0900988 }
Jiyong Park25b92222024-05-17 22:58:54 +0000989 // If we don't embed jni libs, make sure that those are installed along with the
990 // app, and also place symlinks to the installed paths under the lib/<arch>
991 // directory of the app installation directory. ex:
992 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
993 if !a.embeddedJniLibs {
994 for _, jniLib := range jniLibs {
995 archStr := jniLib.target.Arch.ArchType.String()
996 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
997 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +0000998 // install the symlink itself
999 symlinkName := installedLib.Base()
1000 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1001 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1002 }
1003 }
1004 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001005 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001006 }
Artur Satayev1111b842020-04-27 19:05:28 +01001007
1008 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001009
1010 providePrebuiltInfo(ctx,
1011 prebuiltInfoProps{
1012 baseModuleName: a.BaseModuleName(),
1013 isPrebuilt: false,
1014 },
1015 )
Colin Cross30e076a2015-04-13 13:58:27 -07001016}
1017
Colin Crossc2d24052020-05-13 11:05:02 -07001018type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001019 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001020 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001021 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1022}
1023
1024func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1025 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001026 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001027
Colin Crossc2d24052020-05-13 11:05:02 -07001028 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001029 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1030 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001031 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001032 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1033 checkNativeSdkVersion, func(dep cc.LinkableInterface) bool {
1034 return !dep.IsNdk(ctx.Config()) && !dep.IsStubs()
1035 })
1036
1037 var certificates []Certificate
1038
1039 ctx.VisitDirectDeps(func(module android.Module) {
1040 otherName := ctx.OtherModuleName(module)
1041 tag := ctx.OtherModuleDependencyTag(module)
1042
1043 if tag == certificateTag {
1044 if dep, ok := module.(*AndroidAppCertificate); ok {
1045 certificates = append(certificates, dep.Certificate)
1046 } else {
1047 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1048 }
1049 }
1050 })
1051 return jniLib, prebuiltJniPackages, certificates
1052}
1053
1054func collectJniDeps(ctx android.ModuleContext,
1055 shouldCollectRecursiveNativeDeps bool,
1056 checkNativeSdkVersion bool,
1057 filter func(cc.LinkableInterface) bool) ([]jniLib, android.Paths) {
1058 var jniLibs []jniLib
1059 var prebuiltJniPackages android.Paths
1060 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001061
Peter Collingbournead84f972019-12-17 16:46:18 -08001062 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001063 otherName := ctx.OtherModuleName(module)
1064 tag := ctx.OtherModuleDependencyTag(module)
1065
Colin Crossf0913fb2020-07-29 12:59:39 -07001066 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001067 if dep, ok := module.(cc.LinkableInterface); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001068 if filter != nil && !filter(dep) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001069 return false
1070 }
1071
Colin Crossa4f08812018-10-02 22:03:40 -07001072 lib := dep.OutputFile()
1073 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001074 path := lib.Path()
1075 if seenModulePaths[path.String()] {
1076 return false
1077 }
1078 seenModulePaths[path.String()] = true
1079
1080 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1081 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1082 otherName)
1083 }
1084
Colin Crossa4f08812018-10-02 22:03:40 -07001085 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001086 name: ctx.OtherModuleName(module),
1087 path: path,
1088 target: module.Target(),
1089 coverageFile: dep.CoverageOutputFile(),
1090 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001091 partition: dep.Partition(),
Jiyong Park25b92222024-05-17 22:58:54 +00001092 installPaths: dep.FilesToInstall(),
Colin Crossa4f08812018-10-02 22:03:40 -07001093 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001094 } else if ctx.Config().AllowMissingDependencies() {
1095 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001096 } else {
1097 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1098 }
1099 } else {
1100 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001101 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001102
1103 return shouldCollectRecursiveNativeDeps
1104 }
1105
Colin Cross313aa542023-12-13 13:47:44 -08001106 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001107 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1108 }
1109
Peter Collingbournead84f972019-12-17 16:46:18 -08001110 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001111 })
1112
Makoto Onuki2ca84272024-02-10 00:15:21 +00001113 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001114}
1115
Jooyung Han749dc692020-04-15 11:03:39 +09001116func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001117 ctx.WalkDeps(func(child, parent android.Module) bool {
1118 isExternal := !a.DepIsInSameApex(ctx, child)
1119 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001120 if !do(ctx, parent, am, isExternal) {
1121 return false
1122 }
Artur Satayev1111b842020-04-27 19:05:28 +01001123 }
1124 return !isExternal
1125 })
1126}
1127
1128func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1129 if ctx.Host() {
1130 return
1131 }
1132
1133 depsInfo := android.DepNameToDepInfoMap{}
Jooyung Han749dc692020-04-15 11:03:39 +09001134 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001135 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001136
1137 // Skip dependencies that are only available to APEXes; they are developed with updatability
1138 // in mind and don't need manual approval.
1139 if to.(android.ApexModule).NotAvailableForPlatform() {
1140 return true
1141 }
1142
Artur Satayev1111b842020-04-27 19:05:28 +01001143 if info, exist := depsInfo[depName]; exist {
1144 info.From = append(info.From, from.Name())
1145 info.IsExternal = info.IsExternal && externalDep
1146 depsInfo[depName] = info
1147 } else {
1148 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001149 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001150 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001151 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001152 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1153 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001154 }
Jiyong Park92315372021-04-02 08:45:46 +09001155 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1156 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1157 // string
1158 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001159 toMinSdkVersion = v
1160 }
Artur Satayev1111b842020-04-27 19:05:28 +01001161 }
1162 depsInfo[depName] = android.ApexModuleDepInfo{
1163 To: depName,
1164 From: []string{from.Name()},
1165 IsExternal: externalDep,
1166 MinSdkVersion: toMinSdkVersion,
1167 }
1168 }
Jooyung Han749dc692020-04-15 11:03:39 +09001169 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001170 })
1171
Jiyong Park92315372021-04-02 08:45:46 +09001172 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001173}
1174
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001175func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1176 return a.appProperties.EnforceDefaultTargetSdkVersion
1177}
1178
1179func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1180 a.appProperties.EnforceDefaultTargetSdkVersion = val
1181}
1182
Artur Satayev849f8442020-04-28 14:57:42 +01001183func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001184 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001185}
1186
Spandan Das42e89502022-05-06 22:12:55 +00001187func (a *AndroidApp) SetUpdatable(val bool) {
1188 a.appProperties.Updatable = &val
1189}
1190
Colin Cross0ea8ba82019-06-06 14:33:29 -07001191func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001192 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1193 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001194 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001195 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001196 return String(a.overridableAppProperties.Certificate)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001197}
1198
Jiyong Park0f80c182020-01-31 02:49:53 +09001199func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1200 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1201 return true
1202 }
1203 return a.Library.DepIsInSameApex(ctx, dep)
1204}
1205
Jiyong Parkb7c639e2019-08-19 14:56:02 +09001206// For OutputFileProducer interface
1207func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) {
1208 switch tag {
Jared Duke34b080d2023-03-30 16:40:24 -07001209 // In some instances, it can be useful to reference the aapt-generated flags from another
1210 // target, e.g., system server implements services declared in the framework-res manifest.
1211 case ".aapt.proguardOptionsFile":
1212 return []android.Path{a.proguardOptionsFile}, nil
Jiyong Parkb7c639e2019-08-19 14:56:02 +09001213 case ".aapt.srcjar":
Colin Crossf3b7bad2023-08-02 15:49:00 -07001214 if a.aaptSrcJar != nil {
1215 return []android.Path{a.aaptSrcJar}, nil
1216 }
1217 case ".aapt.jar":
1218 if a.rJar != nil {
1219 return []android.Path{a.rJar}, nil
1220 }
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001221 case ".apk":
1222 return []android.Path{a.outputFile}, nil
Anton Hansson092aca42020-08-13 19:37:22 +01001223 case ".export-package.apk":
1224 return []android.Path{a.exportPackage}, nil
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001225 case ".manifest.xml":
1226 return []android.Path{a.aapt.manifestPath}, nil
Jiyong Parkb7c639e2019-08-19 14:56:02 +09001227 }
1228 return a.Library.OutputFiles(tag)
1229}
1230
Jiyong Parkf7487312019-10-17 12:54:30 +09001231func (a *AndroidApp) Privileged() bool {
1232 return Bool(a.appProperties.Privileged)
1233}
1234
Colin Crossf5f4ad32024-01-19 15:41:48 -08001235func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001236 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001237}
1238
Ivan Lozanod7586b62021-04-01 09:49:36 -04001239func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001240 a.appProperties.PreventInstall = true
1241}
1242
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001243func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1244 a.appProperties.IsCoverageVariant = coverage
1245}
1246
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001247func (a *AndroidApp) EnableCoverageIfNeeded() {}
1248
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001249var _ cc.Coverage = (*AndroidApp)(nil)
1250
Colin Cross95b53b82023-10-17 13:21:02 -07001251func (a *AndroidApp) IDEInfo(dpInfo *android.IdeInfo) {
1252 a.Library.IDEInfo(dpInfo)
1253 a.aapt.IDEInfo(dpInfo)
1254}
1255
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001256func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1257 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1258}
1259
1260func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1261 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1262}
1263
Colin Cross1b16b0e2019-02-12 14:41:32 -08001264// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001265func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001266 module := &AndroidApp{}
1267
Liz Kammera7a64f32020-07-09 15:16:41 -07001268 module.Module.dexProperties.Optimize.EnabledByDefault = true
1269 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001270 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001271
Colin Crossae5caf52018-05-22 11:11:52 -07001272 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001273 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001274 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001275
Colin Crossce6734e2020-06-15 16:09:53 -07001276 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001277 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001278 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001279 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001280 &module.overridableAppProperties,
1281 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001282
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001283 module.usesLibrary.enforce = true
1284
Colin Crossa4f08812018-10-02 22:03:40 -07001285 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1286 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001287 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001288 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001289
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001290 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1291 a := ctx.Module().(*AndroidApp)
1292
1293 characteristics := ctx.Config().ProductAAPTCharacteristics()
1294 if characteristics == "default" || characteristics == "" {
1295 module.appProperties.Generate_product_characteristics_rro = nil
1296 // no need to create RRO
1297 return
1298 }
1299
1300 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1301 return
1302 }
1303
1304 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1305 rroManifestName := rroPackageName + "_manifest"
1306
1307 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1308 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1309
1310 rroManifestProperties := struct {
1311 Name *string
1312 Tools []string
1313 Out []string
1314 Srcs []string
1315 Cmd *string
1316 }{
1317 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001318 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001319 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001320 Srcs: []string{":" + a.Name() + "{.apk}"},
1321 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001322 }
1323 ctx.CreateModule(genrule.GenRuleFactory, &rroManifestProperties)
1324
1325 rroProperties := struct {
1326 Name *string
1327 Filter_product *string
1328 Aaptflags []string
1329 Manifest *string
1330 Resource_dirs []string
1331 }{
1332 Name: proptools.StringPtr(rroPackageName),
1333 Filter_product: proptools.StringPtr(characteristics),
1334 Aaptflags: []string{"--auto-add-overlay"},
1335 Manifest: proptools.StringPtr(":" + rroManifestName),
1336 Resource_dirs: a.aaptProperties.Resource_dirs,
1337 }
优秀d75e9982024-05-09 07:15:55 +00001338 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1339 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1340 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1341 }
1342 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001343 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1344 })
1345
Colin Cross36242852017-06-23 15:06:31 -07001346 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001347}
Colin Crossae5caf52018-05-22 11:11:52 -07001348
Alix96ea88452023-08-31 15:48:23 +00001349// A dictionary of values to be overridden in the manifest.
1350type Manifest_values struct {
1351 // Overrides the value of package_name in the manifest
1352 ApplicationId *string
1353}
1354
Colin Crossae5caf52018-05-22 11:11:52 -07001355type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001356 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001357 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001358
Seth Moorec6f4b532023-02-02 13:22:26 -08001359 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001360 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001361
1362 // If specified, the mainline module package name in the test config is overwritten by it.
1363 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001364
1365 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001366}
1367
1368type AndroidTest struct {
1369 AndroidApp
1370
1371 appTestProperties appTestProperties
1372
1373 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001374
Dan Shi95d19422020-08-15 12:24:26 -07001375 testConfig android.Path
1376 extraTestConfigs android.Paths
1377 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001378}
1379
Jaewoong Jung0949f312019-09-11 10:25:18 -07001380func (a *AndroidTest) InstallInTestcases() bool {
1381 return true
1382}
1383
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001384type androidTestApp interface {
1385 includedInTestSuite(searchPrefix string) bool
1386}
1387
1388func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1389 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1390}
1391
1392func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1393 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1394}
1395
Colin Crossae5caf52018-05-22 11:11:52 -07001396func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001397 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001398 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001399 if a.appTestProperties.Instrumentation_target_package != nil {
1400 a.additionalAaptFlags = append(a.additionalAaptFlags,
1401 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1402 } else if a.appTestProperties.Instrumentation_for != nil {
1403 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001404 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1405 if overridden {
1406 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1407 }
1408 }
Alix96ea88452023-08-31 15:48:23 +00001409 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1410 if applicationId != nil {
1411 if a.overridableAppProperties.Package_name != nil {
1412 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1413 }
1414 a.aapt.manifestValues.applicationId = *applicationId
1415 }
Colin Crossae5caf52018-05-22 11:11:52 -07001416 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001417
easoncylee5bcff5d2020-04-30 14:57:06 +08001418 for _, module := range a.testProperties.Test_mainline_modules {
1419 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1420 }
1421
Jaewoong Jung39982342020-01-14 10:27:18 -08001422 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
easoncylee5bcff5d2020-04-30 14:57:06 +08001423 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
Jaewoong Jung39982342020-01-14 10:27:18 -08001424 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001425 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001426 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Colin Cross40213022023-12-13 15:19:49 -08001427 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001428 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1429 InstalledFiles: a.data,
1430 OutputFile: a.OutputFile(),
1431 TestConfig: a.testConfig,
1432 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001433 TestSuites: a.testProperties.Test_suites,
1434 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001435 LocalCertificate: a.certificate.AndroidMkString(),
1436 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001437 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001438 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1439 TestOnly: true,
1440 TopLevelTarget: true,
1441 })
1442
Colin Cross303e21f2018-08-07 16:49:25 -07001443}
1444
Jaewoong Jung39982342020-01-14 10:27:18 -08001445func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1446 if testConfig == nil {
1447 return nil
1448 }
1449
1450 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001451 rule := android.NewRuleBuilder(pctx, ctx)
1452 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001453 fixNeeded := false
1454
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001455 // 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 -08001456 if ctx.ModuleName() != a.installApkName {
1457 fixNeeded = true
1458 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1459 }
1460
1461 if a.overridableAppProperties.Package_name != nil {
1462 fixNeeded = true
1463 command.FlagWithInput("--manifest ", a.manifestPath).
1464 FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
1465 }
1466
Seth Moorec6f4b532023-02-02 13:22:26 -08001467 if a.appTestProperties.Mainline_package_name != nil {
1468 fixNeeded = true
1469 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1470 }
1471
Jaewoong Jung39982342020-01-14 10:27:18 -08001472 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001473 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001474 return fixedConfig
1475 }
1476 return testConfig
1477}
1478
Colin Cross303e21f2018-08-07 16:49:25 -07001479func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Colin Cross303e21f2018-08-07 16:49:25 -07001480 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001481}
1482
1483func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1484 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001485 if a.appTestProperties.Instrumentation_for != nil {
1486 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1487 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1488 // use instrumentationForTag instead of libTag.
1489 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1490 }
Colin Crossae5caf52018-05-22 11:11:52 -07001491}
1492
Colin Cross1b16b0e2019-02-12 14:41:32 -08001493// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1494// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001495func AndroidTestFactory() android.Module {
1496 module := &AndroidTest{}
1497
Jared Duke63a3da92022-06-02 19:11:14 +00001498 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001499
1500 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001501 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001502 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001503 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1504 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001505 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001506 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001507
Colin Crossce6734e2020-06-15 16:09:53 -07001508 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001509 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001510 &module.aaptProperties,
1511 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001512 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001513 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001514 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001515
Colin Crossa4f08812018-10-02 22:03:40 -07001516 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1517 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001518 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001519
Colin Crossae5caf52018-05-22 11:11:52 -07001520 return module
1521}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001522
Colin Cross252fc6f2018-10-04 15:22:03 -07001523type appTestHelperAppProperties struct {
1524 // list of compatibility suites (for example "cts", "vts") that the module should be
1525 // installed into.
1526 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001527
1528 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1529 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1530 // explicitly.
1531 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001532
1533 // Install the test into a folder named for the module in all test suites.
1534 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001535
1536 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001537}
1538
1539type AndroidTestHelperApp struct {
1540 AndroidApp
1541
1542 appTestHelperAppProperties appTestHelperAppProperties
1543}
1544
Jaewoong Jung326a9412019-11-21 10:41:00 -08001545func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1546 return true
1547}
1548
Colin Cross1b16b0e2019-02-12 14:41:32 -08001549// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1550// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1551// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001552func AndroidTestHelperAppFactory() android.Module {
1553 module := &AndroidTestHelperApp{}
1554
Jared Duke63a3da92022-06-02 19:11:14 +00001555 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001556 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001557
1558 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001559 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1560 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001561 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001562 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001563
Colin Crossce6734e2020-06-15 16:09:53 -07001564 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001565 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001566 &module.aaptProperties,
1567 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001568 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001569 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001570
1571 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1572 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001573 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001574 return module
1575}
1576
Colin Crossbd01e2a2018-10-04 15:21:03 -07001577type AndroidAppCertificate struct {
1578 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001579
Colin Crossbd01e2a2018-10-04 15:21:03 -07001580 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001581 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001582}
1583
1584type AndroidAppCertificateProperties struct {
1585 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1586 Certificate *string
1587}
1588
Colin Cross1b16b0e2019-02-12 14:41:32 -08001589// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1590// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001591func AndroidAppCertificateFactory() android.Module {
1592 module := &AndroidAppCertificate{}
1593 module.AddProperties(&module.properties)
1594 android.InitAndroidModule(module)
1595 return module
1596}
1597
Colin Crossbd01e2a2018-10-04 15:21:03 -07001598func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1599 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001600 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001601 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1602 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001603 }
1604}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001605
1606type OverrideAndroidApp struct {
1607 android.ModuleBase
1608 android.OverrideModuleBase
1609}
1610
Sasha Smundak613cbb12020-06-05 10:27:23 -07001611func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001612 // All the overrides happen in the base module.
1613 // TODO(jungjw): Check the base module type.
1614}
1615
1616// override_android_app is used to create an android_app module based on another android_app by overriding
1617// some of its properties.
1618func OverrideAndroidAppModuleFactory() android.Module {
1619 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001620 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001621 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001622 &overridableAppProperties{},
1623 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001624
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001625 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001626 android.InitOverrideModule(m)
1627 return m
1628}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001629
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001630type OverrideAndroidTest struct {
1631 android.ModuleBase
1632 android.OverrideModuleBase
1633}
1634
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001635func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001636 // All the overrides happen in the base module.
1637 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001638 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1639 TestOnly: true,
1640 TopLevelTarget: true,
1641 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001642}
1643
1644// override_android_test is used to create an android_app module based on another android_test by overriding
1645// some of its properties.
1646func OverrideAndroidTestModuleFactory() android.Module {
1647 m := &OverrideAndroidTest{}
1648 m.AddProperties(&overridableAppProperties{})
1649 m.AddProperties(&appTestProperties{})
1650
1651 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1652 android.InitOverrideModule(m)
1653 return m
1654}
1655
Colin Cross50ddcc42019-05-16 12:28:22 -07001656type UsesLibraryProperties struct {
1657 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
1658 Uses_libs []string
1659
1660 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1661 // required=false.
1662 Optional_uses_libs []string
1663
1664 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1665 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1666 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001667
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001668 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1669 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1670 // normally is the same as the module name, but there are exceptions.
1671 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001672
1673 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1674 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1675 // added to the APK's manifest's <uses-library> elements.
1676 //
1677 // Care must be taken when using this as it could result in runtime errors if the APK actually
1678 // uses classes provided by the library and which are not provided in any other way.
1679 //
1680 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1681 // android.test.base shared library (and related libraries) but which depend on some common
1682 // libraries that depend on the android.test.base library. Without this those tests will end up
1683 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1684 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1685 // test altogether by providing access to classes that the tests were not expecting. Those tests
1686 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1687 // with the classes provided by the android.test.base library.
1688 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001689
1690 // The module names of optional uses-library libraries that are missing from the source tree.
1691 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001692}
1693
1694// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1695// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1696// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1697// with knowledge of their shared libraries.
1698type usesLibrary struct {
1699 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001700
1701 // Whether to enforce verify_uses_library check.
1702 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001703
1704 // Whether dexpreopt should be disabled
1705 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001706}
1707
Colin Cross4a80a152022-12-21 21:51:52 -08001708func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001709 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001710 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001711 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1712 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001713 // Only add these extra dependencies if the module is an app that depends on framework
1714 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001715 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001716 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001717 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1718 // class loader context for dex2oat. Add them as a dependency with a special tag.
1719 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1720 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1721 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001722 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001723 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
1724 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001725 } else {
1726 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
1727 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001728 }
1729}
1730
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001731// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001732func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001733 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool {
1734 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001735 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001736 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1737 }
1738 return exists
1739 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001740 return optionalUsesLibs
1741}
1742
Ulya Trafimovich24446712021-07-15 14:59:34 +01001743// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1744// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001745func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1746 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001747
1748 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1749 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1750 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1751 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001752 }
1753
Ulya Trafimovich24446712021-07-15 14:59:34 +01001754 ctx.VisitDirectDeps(func(m android.Module) {
1755 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1756 if !isUsesLibTag {
1757 return
1758 }
1759
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001760 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001761
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001762 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1763 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1764 // from implementation libraries by their name, which is different as it has a suffix.
1765 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1766 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1767 return
1768 }
1769 }
1770
Spandan Das0727ba72024-02-13 16:37:43 +00001771 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1772 // This will be restricted to optional_uses_libs
1773 if sdklib, ok := m.(SdkLibraryDependency); ok {
1774 if tag == usesLibOptTag && sdklib.DexJarBuildPath(ctx).PathOrNil() == nil {
1775 u.shouldDisableDexpreopt = true
1776 return
1777 }
1778 }
1779
Ulya Trafimovich24446712021-07-15 14:59:34 +01001780 if lib, ok := m.(UsesLibraryDependency); ok {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001781 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001782 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001783 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001784 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001785 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001786 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001787 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001788 } else if ctx.Config().AllowMissingDependencies() {
1789 ctx.AddMissingDependencies([]string{dep})
1790 } else {
1791 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1792 }
1793 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001794 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001795}
1796
1797// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1798// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1799// unconditionally in the future.
1800func (u *usesLibrary) enforceUsesLibraries() bool {
1801 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
1802 len(u.usesLibraryProperties.Optional_uses_libs) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001803 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001804}
1805
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001806// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
1807func (u *usesLibrary) freezeEnforceUsesLibraries() {
1808 enforce := u.enforceUsesLibraries()
1809 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1810}
1811
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001812// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1813// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1814// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1815// extension: APKs are supposed to end with '.apk').
1816func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001817 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001818
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001819 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001820
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001821 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1822 // check is not necessary, and although it is good to have, it is difficult to maintain on
1823 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1824 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001825 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001826 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001827 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001828 }
1829
Colin Crossf1a035e2020-11-16 17:32:30 -08001830 rule := android.NewRuleBuilder(pctx, ctx)
1831 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001832 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001833 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001834 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001835 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001836
1837 if outputFile != nil {
1838 cmd.FlagWithOutput("-o ", outputFile)
1839 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001840
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001841 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1842 cmd.Flag("--enforce-uses-libraries-relax")
1843 }
1844
Jiakai Zhangf98da192024-04-15 11:15:41 +00001845 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1846 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001847 cmd.FlagWithArg("--uses-library ", lib)
1848 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001849 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001850 cmd.FlagWithArg("--optional-uses-library ", lib)
1851 }
1852
Jiakai Zhangf98da192024-04-15 11:15:41 +00001853 // Also add missing optional uses libs, as the manifest check expects them.
1854 // Note that what we add here are the module names of those missing libs, not library names, while
1855 // the manifest check actually expects library names. However, the case where a library is missing
1856 // and the module name != the library name is too rare for us to handle.
1857 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1858 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1859 }
1860
Colin Crossf1a035e2020-11-16 17:32:30 -08001861 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001862 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001863}
Colin Cross50ddcc42019-05-16 12:28:22 -07001864
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001865// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1866// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001867func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1868 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001869 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001870 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001871}
1872
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001873// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1874// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001875func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1876 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1877 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001878}