blob: a634f9c32d62d0de579c6ff3a40a30f69e124215 [file] [log] [blame]
Colin Cross30e076a2015-04-13 13:58:27 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
Jaewoong Jungf9b44652020-12-21 12:29:12 -080017// This file contains the module implementations for android_app, android_test, and some more
18// related module types, including their override variants.
Colin Cross30e076a2015-04-13 13:58:27 -070019
20import (
Jiakai Zhang4f65a032023-06-01 15:16:58 +010021 "fmt"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070022 "path/filepath"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070023 "strings"
Colin Cross30e076a2015-04-13 13:58:27 -070024
Colin Cross50ddcc42019-05-16 12:28:22 -070025 "github.com/google/blueprint"
Colin Crossa14fb6a2024-10-23 16:57:06 -070026 "github.com/google/blueprint/depset"
Colin Cross50ddcc42019-05-16 12:28:22 -070027 "github.com/google/blueprint/proptools"
28
Colin Cross635c3b02016-05-18 15:37:25 -070029 "android/soong/android"
Colin Crossa4f08812018-10-02 22:03:40 -070030 "android/soong/cc"
Ulya Trafimovichd4bcea42020-06-03 14:57:22 +010031 "android/soong/dexpreopt"
Colin Cross303e21f2018-08-07 16:49:25 -070032 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070033)
34
Colin Cross3bc7ffa2017-11-22 16:19:37 -080035func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000036 RegisterAppBuildComponents(android.InitRegistrationContext)
Andrei Onea580636b2022-08-17 16:53:46 +000037 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080038}
39
Andrei Onea580636b2022-08-17 16:53:46 +000040var (
41 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
42 blueprint.RuleParams{
43 Command: "${ModifyAllowlistCmd} $in $packageName $out",
44 CommandDeps: []string{"${ModifyAllowlistCmd}"},
45 }, "packageName")
46)
47
Jihoon Kang9aef7772024-06-14 23:45:06 +000048type FlagsPackages struct {
49 // Paths to the aconfig dump output text files that are consumed by aapt2
50 AconfigTextFiles android.Paths
51}
52
53var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
54
Paul Duffinf9b1da02019-12-18 19:51:55 +000055func RegisterAppBuildComponents(ctx android.RegistrationContext) {
56 ctx.RegisterModuleType("android_app", AndroidAppFactory)
57 ctx.RegisterModuleType("android_test", AndroidTestFactory)
58 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
59 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
60 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
61 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000062}
63
Colin Cross99939e92024-10-01 16:02:46 -070064type AppInfo struct {
65 // Updatable is set to the value of the updatable property
66 Updatable bool
67
68 // TestHelperApp is true if the module is a android_test_helper_app
69 TestHelperApp bool
Colin Crossb614cd42024-10-11 12:52:21 -070070
71 // EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
72 EmbeddedJNILibs android.Paths
Yu Liu7eebf8b2025-01-17 00:23:57 +000073
74 MergedManifestFile android.Path
Colin Cross99939e92024-10-01 16:02:46 -070075}
76
77var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
78
Colin Cross30e076a2015-04-13 13:58:27 -070079// AndroidManifest.xml merging
80// package splits
81
Colin Crossfabb6082018-02-20 17:22:23 -080082type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070083 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070084 Additional_certificates []string
85
86 // If set, create package-export.apk, which other packages can
87 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080088 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070089
Colin Cross16056062017-12-13 22:46:28 -080090 // Specifies that this app should be installed to the priv-app directory,
91 // where the system will grant it additional privileges not available to
92 // normal apps.
93 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070094
95 // list of resource labels to generate individual resource packages
96 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040097
Colin Crossa4f08812018-10-02 22:03:40 -070098 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +000099 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -0700100
Colin Cross7204cf02020-05-06 17:51:39 -0700101 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -0800102 // sdk_version.
103 Jni_uses_platform_apis *bool
104
Colin Cross7204cf02020-05-06 17:51:39 -0700105 // if true, use JNI libraries that link against SDK APIs even if this module does not set
106 // sdk_version.
107 Jni_uses_sdk_apis *bool
108
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700109 // STL library to use for JNI libraries.
110 Stl *string `android:"arch_variant"`
111
Colin Crosse4246ab2019-02-05 21:55:21 -0800112 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900113 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
114 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
115 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
116 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800117 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800118
119 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
120 // they are used from inside the APK at runtime.
121 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700122
Jiyong Parkd044bb42024-05-15 02:09:54 +0900123 // Forces native libraries to always be packaged into the APK,
124 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
125 // True for android_test* modules.
126 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700127
128 // If set, find and merge all NOTICE files that this module and its dependencies have and store
129 // it in the APK as an asset.
130 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700131
132 // cc.Coverage related properties
133 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700134 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100135
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000136 // It can be set to test the behaviour of default target sdk version.
137 // Only required when updatable: false. It is an error if updatable: true and this is false.
138 Enforce_default_target_sdk_version *bool
139
140 // If set, the targetSdkVersion for the target is set to the latest default API level.
141 // This would be by default false, unless updatable: true or
142 // enforce_default_target_sdk_version: true in which case this defaults to true.
143 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
144
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100145 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100146 // additional rules to make sure an app can safely be updated. Default is false.
147 // Prefer using other specific properties if build behaviour must be changed; avoid using this
148 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100149 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000150
151 // Specifies the file that contains the allowlist for this app.
152 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900153
154 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
155 // and install the RRO package to /product partition, instead of passing --product argument
156 // to aapt2. Default is false.
157 // Setting this will make this APK identical to all targets, regardless of
158 // PRODUCT_CHARACTERISTICS.
159 Generate_product_characteristics_rro *bool
160
161 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
162 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700163}
164
Jaewoong Jung525443a2019-02-28 15:35:54 -0800165// android_app properties that can be overridden by override_android_app
166type overridableAppProperties struct {
167 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
168 // or an android_app_certificate module name in the form ":module".
Cole Fausteb9c1482024-11-18 16:49:19 -0800169 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700170
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800171 // Name of the signing certificate lineage file or filegroup module.
172 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700173
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400174 // For overriding the --rotation-min-sdk-version property of apksig
175 RotationMinSdkVersion *string
176
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700177 // the package name of this app. The package name in the manifest file is used if one was not given.
Cole Faust258b96f2024-10-04 10:48:24 -0700178 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800179
180 // the logging parent of this app.
181 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000182
183 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
184 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000185
186 // Names of modules to be overridden. Listed modules can only be other binaries
187 // (in Make or Soong).
188 // This does not completely prevent installation of the overridden binaries, but if both
189 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
190 // from PRODUCT_PACKAGES.
191 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800192}
193
Colin Cross30e076a2015-04-13 13:58:27 -0700194type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700195 Library
196 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800197 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700198
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900199 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700200
Colin Crossfabb6082018-02-20 17:22:23 -0800201 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700202
Jaewoong Jung525443a2019-02-28 15:35:54 -0800203 overridableAppProperties overridableAppProperties
204
Colin Cross403cc152020-07-06 14:15:24 -0700205 jniLibs []jniLib
206 installPathForJNISymbols android.Path
207 embeddedJniLibs bool
208 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700209
210 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800211
212 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
213 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800214
Colin Cross70dda7e2019-10-01 22:05:35 -0700215 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700216
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700217 onDeviceDir string
218
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800219 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700220
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900221 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100222
223 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000224
225 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000226
227 privAppAllowlist android.OptionalPath
Spandan Dasde588a32024-12-03 22:52:24 +0000228
229 requiredModuleNames []string
Colin Crosse1731a52017-12-14 11:22:55 -0800230}
231
Martin Stjernholm6d415272020-01-31 17:10:36 +0000232func (a *AndroidApp) IsInstallable() bool {
233 return Bool(a.properties.Installable)
234}
235
Colin Crossa14fb6a2024-10-23 16:57:06 -0700236func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000237 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700238}
239
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900240func (a *AndroidApp) OutputFile() android.Path {
241 return a.outputFile
242}
243
Colin Cross503c1d02020-01-28 14:00:53 -0800244func (a *AndroidApp) Certificate() Certificate {
245 return a.certificate
246}
247
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700248func (a *AndroidApp) JniCoverageOutputs() android.Paths {
249 return a.jniCoverageOutputs
250}
251
Andrei Onea580636b2022-08-17 16:53:46 +0000252func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
253 return a.privAppAllowlist
254}
255
Colin Crossa97c5d32018-03-28 14:58:31 -0700256var _ AndroidLibraryDependency = (*AndroidApp)(nil)
257
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900258type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800259 Pem, Key android.Path
260 presigned bool
261}
262
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700263var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800264
265func (c Certificate) AndroidMkString() string {
266 if c.presigned {
267 return "PRESIGNED"
268 } else {
269 return c.Pem.String()
270 }
Colin Cross30e076a2015-04-13 13:58:27 -0700271}
272
Colin Cross46c9b8b2017-06-22 16:51:17 -0700273func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900274 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700275 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
276 }
277
Jiyong Parkf1691d22021-03-29 20:11:58 +0900278 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000279 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
280 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100281 if sdkDep.hasFrameworkLibs() {
282 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700283 }
Colin Crossa4f08812018-10-02 22:03:40 -0700284
Jiyong Park92315372021-04-02 08:45:46 +0900285 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700286
287 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
288 ctx.PropertyErrorf("jni_uses_sdk_apis",
289 "can only be set for modules that do not set sdk_version")
290 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
291 ctx.PropertyErrorf("jni_uses_platform_apis",
292 "can only be set for modules that set sdk_version")
293 }
294
Colin Crossa4f08812018-10-02 22:03:40 -0700295 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700296 variation := append(jniTarget.Variations(),
297 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000298
Jiyong Park92d84042024-05-17 22:58:54 +0000299 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
300 // Many factors are considered here.
301 // 1. Basically, the selection follows whether the app has sdk_version set or not.
302 jniUsesSdkVariant := usesSDK
303 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
304 if Bool(a.appProperties.Jni_uses_sdk_apis) {
305 jniUsesSdkVariant = true
306 }
307 if Bool(a.appProperties.Jni_uses_platform_apis) {
308 jniUsesSdkVariant = false
309 }
310 // 3. Then the use of SDK variant is again prohibited for the following cases:
311 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
312 // partition (not only the app) is considered unbudled, there's no need to use the
313 // SDK variant.
314 // 3.2. the app doesn't support embedding the JNI libs
315 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
316 jniUsesSdkVariant = false
317 }
318 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000319 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
320 }
Jiyong Park92d84042024-05-17 22:58:54 +0000321
322 // Use the installable dep tag when the JNIs are not embedded
323 var tag dependencyTag
324 if a.shouldEmbedJnis(ctx) {
325 tag = jniLibTag
326 } else {
327 tag = jniInstallTag
328 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000329 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700330 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000331 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
332 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
333 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700334}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700335
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700336func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800337 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700338 if cert != "" {
339 ctx.AddDependency(ctx.Module(), certificateTag, cert)
340 }
341
Andrei Onea580636b2022-08-17 16:53:46 +0000342 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000343 // There are a few uids that are explicitly considered privileged regardless of their
344 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
345 // but for now, allow it not to be in priv-app.
346 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
347 if !privilegedBecauseOfUid {
348 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
349 }
Andrei Onea580636b2022-08-17 16:53:46 +0000350 }
351
Colin Crossbd01e2a2018-10-04 15:21:03 -0700352 for _, cert := range a.appProperties.Additional_certificates {
353 cert = android.SrcIsModule(cert)
354 if cert != "" {
355 ctx.AddDependency(ctx.Module(), certificateTag, cert)
356 } else {
357 ctx.PropertyErrorf("additional_certificates",
358 `must be names of android_app_certificate modules in the form ":module"`)
359 }
360 }
Colin Cross30e076a2015-04-13 13:58:27 -0700361}
362
Spandan Dasb0410872024-06-25 03:30:03 +0000363// TODO(b/156476221): Remove this allowlist
364var (
365 missingMinSdkVersionMtsAllowlist = []string{
366 "CellBroadcastReceiverGoogleUnitTests",
367 "CellBroadcastReceiverUnitTests",
368 "CtsBatterySavingTestCases",
369 "CtsDeviceAndProfileOwnerApp23",
370 "CtsDeviceAndProfileOwnerApp30",
371 "CtsIntentSenderApp",
372 "CtsJobSchedulerTestCases",
373 "CtsMimeMapTestCases",
374 "CtsTareTestCases",
375 "LibStatsPullTests",
376 "MediaProviderClientTests",
377 "TeleServiceTests",
378 "TestExternalImsServiceApp",
379 "TestSmsRetrieverApp",
380 "TetheringPrivilegedTests",
381 }
382)
383
384func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
385 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
386 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
387 }
388}
389
Jeongik Cha538c0d02019-07-11 15:54:27 +0900390func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000391 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000392 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
393 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700394 packageName := a.overridableAppProperties.Package_name.Get(ctx)
395 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000396 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
397 }
398 a.aapt.manifestValues.applicationId = *applicationId
399 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900400 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700401 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
402 TestOnly: true,
403 })
Colin Cross99939e92024-10-01 16:02:46 -0700404 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
405 Updatable: Bool(a.appProperties.Updatable),
406 TestHelperApp: true,
407 })
Cole Faust866ab392025-01-23 12:56:20 -0800408
409 moduleInfoJSON := ctx.ModuleInfoJSON()
410 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
411 if len(a.appTestHelperAppProperties.Test_suites) > 0 {
412 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...)
413 } else {
414 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
415 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900416}
417
Colin Cross46c9b8b2017-06-22 16:51:17 -0700418func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100419 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000420 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700421 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000422 a.generateJavaUsedByApex(ctx)
Colin Crossb614cd42024-10-11 12:52:21 -0700423
424 var embeddedJniLibs []android.Path
425
426 if a.embeddedJniLibs {
427 for _, jni := range a.jniLibs {
428 embeddedJniLibs = append(embeddedJniLibs, jni.path)
429 }
430 }
Colin Cross99939e92024-10-01 16:02:46 -0700431 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
Yu Liu7eebf8b2025-01-17 00:23:57 +0000432 Updatable: Bool(a.appProperties.Updatable),
433 TestHelperApp: false,
434 EmbeddedJNILibs: embeddedJniLibs,
435 MergedManifestFile: a.mergedManifest,
Colin Cross99939e92024-10-01 16:02:46 -0700436 })
Spandan Dasde588a32024-12-03 22:52:24 +0000437
438 a.requiredModuleNames = a.getRequiredModuleNames(ctx)
439}
440
441func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
442 var required []string
443 if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
444 required = []string{a.productCharacteristicsRROPackageName()}
445 }
446 // Install the vendor overlay variant if this app is installed.
447 if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
448 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
449 }
450 // Install the product overlay variant if this app is installed.
451 if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
452 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
453 }
454 return required
Colin Crossae5caf52018-05-22 11:11:52 -0700455}
456
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100457func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100458 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900459 if !a.SdkVersion(ctx).Stable() {
460 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100461 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000462 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100463 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
464 }
Jooyung Han749dc692020-04-15 11:03:39 +0900465
Jiyong Park92315372021-04-02 08:45:46 +0900466 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900467 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000468 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900469 } else {
470 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
471 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000472
473 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
474 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
475 }
476 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
477 if a.deviceProperties.Target_sdk_version == nil {
478 a.SetEnforceDefaultTargetSdkVersion(true)
479 }
480 }
481
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100482 a.checkPlatformAPI(ctx)
483 a.checkSdkVersions(ctx)
484}
485
Jiyong Park970c5242024-05-17 22:58:54 +0000486// Ensures that use_embedded_native_libs are set for apk-in-apex
487func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
488 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
489 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000490 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000491
492 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
493 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
494 }
495}
496
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900497// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
498// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900499func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900500 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
Yu Liufc8d5c12025-01-09 00:19:06 +0000501 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900502 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
503 return
504 }
Yu Liufc8d5c12025-01-09 00:19:06 +0000505 if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
506 panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
507 }
508 commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
509 if !ok {
510 panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
511 }
Jooyung Han652d5b32020-05-20 17:12:13 +0900512 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900513 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
514 // handled properly regardless of sdk finalization.
Yu Liu5d3a2cf2025-02-06 00:25:22 +0000515 ver := ""
516 if !commonInfo.MinSdkVersion.IsPlatform {
517 ver = commonInfo.MinSdkVersion.ApiLevel.String()
518 }
519 jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900520 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Yu Liufc8d5c12025-01-09 00:19:06 +0000521 ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
Yu Liu5d3a2cf2025-02-06 00:25:22 +0000522 ver, minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900523 return
524 }
525
526 })
527}
528
Sasha Smundak6ad77252019-05-01 13:16:22 -0700529// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800530// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700531func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900532 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800533 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900534 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800535 }
536
Jiyong Parkd044bb42024-05-15 02:09:54 +0900537 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
538 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
539 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800540}
541
Colin Cross43f08db2018-11-12 10:13:39 -0800542// Returns whether this module should have the dex file stored uncompressed in the APK.
543func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800544 if Bool(a.appProperties.Use_embedded_dex) {
545 return true
546 }
547
Colin Cross53a87f52019-06-25 13:35:30 -0700548 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
549 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900550 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000551 return true
552 }
553
Colin Cross53a87f52019-06-25 13:35:30 -0700554 if ctx.Config().UnbundledBuild() {
555 return false
556 }
557
Spandan Dase21a8d42024-01-23 23:56:29 +0000558 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700559}
560
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700561func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900562 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000563 Bool(a.appProperties.Updatable) ||
564 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000565}
566
Liz Kammer9f9fd022020-06-18 19:44:06 +0000567func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
568 aaptFlags := []string{"--rename-manifest-package " + packageName}
569 if renameResourcesPackage {
570 // Required to rename the package name in the resources table.
571 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
572 }
573 return aaptFlags
574}
575
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900576func (a *AndroidApp) OverriddenManifestPackageName() string {
577 return a.overriddenManifestPackageName
578}
579
Liz Kammer9f9fd022020-06-18 19:44:06 +0000580func (a *AndroidApp) renameResourcesPackage() bool {
581 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
582}
583
Jihoon Kang9049c272024-03-19 21:57:36 +0000584func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Yu Liu460cf372025-01-10 00:34:06 +0000585 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000586 tag := ctx.OtherModuleDependencyTag(dep)
587 switch tag {
588 case staticLibTag:
589 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
590 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
591 }
592
593 case aconfigDeclarationTag:
594 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
595 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
596 } else {
597 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
598 "flags_packages property, but %s is not aconfig_declarations module type",
599 dep.Name(),
600 )
601 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000602 }
603 })
604
Jihoon Kang9aef7772024-06-14 23:45:06 +0000605 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000606}
607
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800608func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900609 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900610 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900611 usePlatformAPI = true
612 }
613 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000614
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700615 // Ask manifest_fixer to add or update the application element indicating this app has no code.
616 a.aapt.hasNoCode = !a.hasCode(ctx)
617
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800618 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800619
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800620 // 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 +0900621 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800622 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900623 characteristics := ctx.Config().ProductAAPTCharacteristics()
624 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
625 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700626 }
627
Dan Willemsen72be5902018-10-24 20:24:57 -0700628 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
629 // Product AAPT config
630 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800631 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700632 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700633
Dan Willemsen72be5902018-10-24 20:24:57 -0700634 // Product AAPT preferred config
635 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800636 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700637 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700638 }
639
Jiyong Park7f67f482019-01-05 12:57:48 +0900640 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700641 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
642 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700643 // The product override variable has a priority over the package_name property.
644 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700645 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700646 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000647 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900648 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900649 }
650
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800651 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
652
Colin Crosse560c4a2019-03-19 16:03:11 -0700653 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800654 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100655 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000656 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
657 a.aapt.defaultManifestVersion = override
658 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000659 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000660 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100661 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000662
Rico Winda2fa2632024-03-13 13:09:17 +0100663 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200664 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000665
666 aconfigTextFilePaths := getAconfigFilePaths(ctx)
667
Alixf7a10272023-09-27 16:47:56 +0000668 a.aapt.buildActions(ctx,
669 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000670 sdkContext: android.SdkContext(a),
671 classLoaderContexts: a.classLoaderContexts,
672 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
673 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100674 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000675 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000676 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000677 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000678 },
679 )
Colin Cross30e076a2015-04-13 13:58:27 -0700680
Colin Cross46c9b8b2017-06-22 16:51:17 -0700681 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700682 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000683
684 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
685 AconfigTextFiles: aconfigTextFilePaths,
686 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800687}
Colin Cross30e076a2015-04-13 13:58:27 -0700688
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800689func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700690 var staticLibProguardFlagFiles android.Paths
Yu Liu80b68c42025-01-15 18:14:34 +0000691 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Colin Cross313aa542023-12-13 13:47:44 -0800692 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400693 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
694 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
695 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700696 }
697 })
698
699 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
700
Colin Cross312634e2023-11-21 15:13:56 -0800701 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200702 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100703 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
704 // live for code references and (transitively) mark these as live.
705 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
706 // dead code alive)
707 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
708 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800709}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800710
Colin Cross403cc152020-07-06 14:15:24 -0700711func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800712 var installDir string
713 if ctx.ModuleName() == "framework-res" {
714 // framework-res.apk is installed as system/framework/framework-res.apk
715 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900716 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800717 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800718 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800719 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800720 }
Colin Cross403cc152020-07-06 14:15:24 -0700721
722 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
723}
724
Yu Liu7eebf8b2025-01-17 00:23:57 +0000725func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) {
Colin Cross403cc152020-07-06 14:15:24 -0700726 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000727 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700728 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100729 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700730 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100731 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700732 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700733 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100734 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700735 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800736 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700737
Rico Wind98e7fa82023-11-27 09:44:03 +0100738 var packageResources = a.exportPackage
739
Yu Liu460cf372025-01-10 00:34:06 +0000740 javaInfo := &JavaInfo{}
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800741 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200742 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100743 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
744 aapt2Convert(ctx, protoFile, packageResources, "proto")
745 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
746 }
747
Colin Cross4eae06d2023-06-20 22:40:02 -0700748 var extraSrcJars android.Paths
749 var extraClasspathJars android.Paths
750 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800751 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700752 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
753 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
754 // classpath when compiling everything else, and add it to the final classes jar.
755 extraClasspathJars = android.Paths{a.aapt.rJar}
756 extraCombinedJars = android.Paths{a.aapt.rJar}
757 } else {
758 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
759 // R.java files for the app's package and the packages from all transitive static android_library
760 // dependencies. Compile the srcjar alongside the rest of the sources.
761 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
762 }
763
Yu Liu460cf372025-01-10 00:34:06 +0000764 javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200765 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100766 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
767 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
768 packageResources = binaryResources
769 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800770 }
Colin Cross30e076a2015-04-13 13:58:27 -0700771
Yu Liu7eebf8b2025-01-17 00:23:57 +0000772 return a.dexJarFile.PathOrNil(), packageResources, javaInfo
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800773}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800774
Sam Delmerico82602492022-06-10 17:05:42 +0000775func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700776 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000777 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700778 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700779 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700780 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800781 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000782 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700783 for _, jni := range jniLibs {
784 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700785 // Only collect coverage for the first target arch if this is a multilib target.
786 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
787 // data file path collisions since the current coverage file path format doesn't contain
788 // arch-related strings. This is fine for now though; the code coverage team doesn't use
789 // multi-arch targets such as test_suite_* for coverage collections yet.
790 //
791 // Work with the team to come up with a new format that handles multilib modules properly
792 // and change this.
793 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700794 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700795 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
796 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700797 }
798 }
Colin Cross403cc152020-07-06 14:15:24 -0700799 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700800 }
801 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800802 return jniJarFile
803}
Colin Crossa4f08812018-10-02 22:03:40 -0700804
Colin Cross403cc152020-07-06 14:15:24 -0700805func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
806 var jniSymbols android.RuleBuilderInstalls
807 for _, jniLib := range a.jniLibs {
808 if jniLib.unstrippedFile != nil {
809 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
810 From: jniLib.unstrippedFile,
811 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
812 })
813 }
814 }
815 return jniSymbols
816}
817
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700818// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
819// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700820func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
821 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700822 if android.SrcIsModule(certPropValue) == "" {
823 var mainCert Certificate
824 if certPropValue != "" {
825 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
826 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800827 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
828 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700829 }
830 } else {
831 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800832 mainCert = Certificate{
833 Pem: pem,
834 Key: key,
835 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700836 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700837 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700838 }
839
Colin Crossbc2c8a72022-09-14 12:45:42 -0700840 if len(certificates) > 0 {
841 mainCertificate = certificates[0]
842 } else {
843 // This can be reached with an empty certificate list if AllowMissingDependencies is set
844 // and the certificate property for this module is a module reference to a missing module.
845 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
846 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
847 }
848 // Set a certificate to avoid panics later when accessing it.
849 mainCertificate = Certificate{
850 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000851 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700852 }
853 }
854
Zyan Wub7550aa2023-05-18 15:46:31 +0800855 if !m.Platform() {
856 certPath := mainCertificate.Pem.String()
857 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
858 if strings.HasPrefix(certPath, systemCertPath) {
859 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
860 allowed := ctx.Config().EnforceSystemCertificateAllowList()
861
862 if enforceSystemCert && !inList(m.Name(), allowed) {
863 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
864 }
865 }
866 }
867
Colin Crossbc2c8a72022-09-14 12:45:42 -0700868 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800869}
870
Jooyung Han39ee1192020-03-23 20:21:11 +0900871func (a *AndroidApp) InstallApkName() string {
872 return a.installApkName
873}
874
Sam Delmerico15809f82023-05-15 17:21:47 -0400875func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000876 if a.appProperties.Privapp_allowlist == nil {
877 return nil
878 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400879
880 isOverrideApp := a.GetOverriddenBy() != ""
881 if !isOverrideApp {
882 // if this is not an override, we don't need to rewrite the existing privapp allowlist
883 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
884 }
885
Cole Faust258b96f2024-10-04 10:48:24 -0700886 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
887 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000888 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
889 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400890
Cole Faust258b96f2024-10-04 10:48:24 -0700891 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000892 fileName := "privapp_allowlist_" + packageName + ".xml"
Cole Faust4e9f5922024-11-13 16:09:23 -0800893 outPath := android.PathForModuleOut(ctx, fileName)
Andrei Onea580636b2022-08-17 16:53:46 +0000894 ctx.Build(pctx, android.BuildParams{
895 Rule: modifyAllowlist,
896 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
897 Output: outPath,
898 Args: map[string]string{
899 "packageName": packageName,
900 },
901 })
Cole Faust4e9f5922024-11-13 16:09:23 -0800902 return outPath
Andrei Onea580636b2022-08-17 16:53:46 +0000903}
904
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800905func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700906 var apkDeps android.Paths
907
Colin Crossff694a82023-12-13 15:54:49 -0800908 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
909 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700910 a.hideApexVariantFromMake = true
911 }
912
Jeongik Cha538c0d02019-07-11 15:54:27 +0900913 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
914 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
915
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000916 // Unlike installApkName, a.stem should respect base module name for override_android_app.
917 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000918 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000919
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800920 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000921 // Both android_app and override_android_app module are expected to possess
922 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
923 // from the base module. Therefore, use a.Name() which represents
924 // the module name for both android_app and override_android_app.
925 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000926 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800927
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700928 if ctx.ModuleName() == "framework-res" {
929 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700930 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900931 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700932 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
933 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800934 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700935 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700936 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700937 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700938 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700939
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100940 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000941 if a.usesLibrary.shouldDisableDexpreopt {
942 a.dexpreopter.disableDexpreopt()
943 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000944
Colin Cross61fb62e2022-06-23 10:46:28 -0700945 var noticeAssetPath android.WritablePath
946 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
947 // The rule to create the notice file can't be generated yet, as the final output path
948 // for the apk isn't known yet. Add the path where the notice file will be generated to the
949 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
950 // be generated later.
951 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
952 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
953 }
954
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000955 // For apps targeting latest target_sdk_version
956 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
957 a.SetEnforceDefaultTargetSdkVersion(true)
958 }
959
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800960 // Process all building blocks, from AAPT to certificates.
961 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100962 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700963 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100964
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100965 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700966 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000967 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
968 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700969 apkDeps = append(apkDeps, manifestCheckFile)
970 }
971
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800972 a.proguardBuildActions(ctx)
973
Colin Cross014489c2020-06-02 20:09:13 -0700974 a.linter.mergedManifest = a.aapt.mergedManifestFile
975 a.linter.manifest = a.aapt.manifestPath
976 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700977 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700978
Yu Liu7eebf8b2025-01-17 00:23:57 +0000979 dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800980
Jiyong Park92d84042024-05-17 22:58:54 +0000981 // No need to check the SDK version of the JNI deps unless we embed them
982 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
983 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000984 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800985
986 if ctx.Failed() {
987 return
988 }
989
Colin Crossbc2c8a72022-09-14 12:45:42 -0700990 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800991
992 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800993 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700994 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
995 var v4SignatureFile android.WritablePath = nil
996 if v4SigningRequested {
997 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
998 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700999 var lineageFile android.Path
1000 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
1001 lineageFile = android.PathForModuleSrc(ctx, lineage)
1002 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04001003 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
1004
Rico Wind98e7fa82023-11-27 09:44:03 +01001005 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001006 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -07001007 if v4SigningRequested {
1008 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1009 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001010
Colin Cross61fb62e2022-06-23 10:46:28 -07001011 if a.aapt.noticeFile.Valid() {
1012 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -07001013 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -07001014 android.BuildNoticeHtmlOutputFromLicenseMetadata(
1015 ctx, noticeFile, "", "",
1016 []string{
1017 a.installDir.String() + "/",
1018 android.PathForModuleInstall(ctx).String() + "/",
1019 a.outputFile.String(),
1020 })
Bob Badoureef4c1c2022-05-16 12:20:04 -07001021 builder := android.NewRuleBuilder(pctx, ctx)
1022 builder.Command().Text("cp").
1023 Input(noticeFile).
1024 Output(noticeAssetPath)
1025 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -07001026 }
1027
Colin Crosse560c4a2019-03-19 16:03:11 -07001028 for _, split := range a.aapt.splits {
1029 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -08001030 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001031 if v4SigningRequested {
1032 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
1033 }
Rico Wind98e7fa82023-11-27 09:44:03 +01001034 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -07001035 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -07001036 if v4SigningRequested {
1037 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1038 }
Colin Crosse560c4a2019-03-19 16:03:11 -07001039 }
1040
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001041 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -07001042 bundleFile := android.PathForModuleOut(ctx, "base.zip")
1043 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1044 a.bundleFile = bundleFile
1045
Andrei Onea580636b2022-08-17 16:53:46 +00001046 allowlist := a.createPrivappAllowlist(ctx)
1047 if allowlist != nil {
1048 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1049 }
1050
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001051 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001052 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1053 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001054 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001055 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1056 allowlistInstallFilename := a.installApkName + ".xml"
1057 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001058 }
1059
Colin Cross09ad3a62023-11-15 12:29:33 -08001060 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001061 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001062 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1063 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001064 }
Jiyong Park25b92222024-05-17 22:58:54 +00001065 // If we don't embed jni libs, make sure that those are installed along with the
1066 // app, and also place symlinks to the installed paths under the lib/<arch>
1067 // directory of the app installation directory. ex:
1068 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1069 if !a.embeddedJniLibs {
1070 for _, jniLib := range jniLibs {
1071 archStr := jniLib.target.Arch.ArchType.String()
1072 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1073 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001074 // install the symlink itself
1075 symlinkName := installedLib.Base()
1076 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1077 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1078 }
1079 }
1080 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001081 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001082 }
Artur Satayev1111b842020-04-27 19:05:28 +01001083
Colin Crossa6182ab2024-08-21 10:47:44 -07001084 ctx.CheckbuildFile(a.outputFile)
1085
Artur Satayev1111b842020-04-27 19:05:28 +01001086 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001087
1088 providePrebuiltInfo(ctx,
1089 prebuiltInfoProps{
1090 baseModuleName: a.BaseModuleName(),
1091 isPrebuilt: false,
1092 },
1093 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001094
Yu Liu7eebf8b2025-01-17 00:23:57 +00001095 if javaInfo != nil {
1096 javaInfo.OutputFile = a.outputFile
1097 setExtraJavaInfo(ctx, a, javaInfo)
1098 android.SetProvider(ctx, JavaInfoProvider, javaInfo)
1099 }
1100
Cole Faust866ab392025-01-23 12:56:20 -08001101 moduleInfoJSON := ctx.ModuleInfoJSON()
1102 moduleInfoJSON.Class = []string{"APPS"}
1103 if !a.embeddedJniLibs {
1104 for _, jniLib := range a.jniLibs {
1105 moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name)
1106 }
1107 }
1108
mrziwang9f7b9f42024-07-10 12:18:06 -07001109 a.setOutputFiles(ctx)
Wei Li986fe742025-01-30 15:14:42 -08001110
1111 buildComplianceMetadata(ctx)
mrziwang9f7b9f42024-07-10 12:18:06 -07001112}
1113
1114func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1115 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1116 if a.aaptSrcJar != nil {
1117 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1118 }
1119 if a.rJar != nil {
1120 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1121 }
1122 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1123 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1124 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1125 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001126}
1127
Colin Crossc2d24052020-05-13 11:05:02 -07001128type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001129 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001130 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001131 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1132}
1133
1134func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1135 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001136 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001137
Colin Crossc2d24052020-05-13 11:05:02 -07001138 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001139 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1140 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001141 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001142 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
Yu Liuf6f85492025-01-13 21:02:36 +00001143 checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool {
Spandan Das10c41362024-12-03 01:33:09 +00001144 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
Yu Liuf6f85492025-01-13 21:02:36 +00001145 childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
1146 parentIsLinkable := false
1147 if ctx.EqualModules(ctx.Module(), parent) {
1148 parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
1149 parentIsLinkable = parentLinkable != nil
1150 } else {
1151 _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider)
1152 }
1153 useStubsOfDep := childLinkable.IsStubs
1154 if apkInApex && parentIsLinkable {
Spandan Das10c41362024-12-03 01:33:09 +00001155 // APK-in-APEX
1156 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
Yu Liuf6f85492025-01-13 21:02:36 +00001157 useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child))
Spandan Das10c41362024-12-03 01:33:09 +00001158 }
Yu Liuf6f85492025-01-13 21:02:36 +00001159 return !childLinkable.IsNdk && !useStubsOfDep
Spandan Das10c41362024-12-03 01:33:09 +00001160 })
Makoto Onuki2ca84272024-02-10 00:15:21 +00001161
1162 var certificates []Certificate
1163
Colin Crossb614cd42024-10-11 12:52:21 -07001164 var directImplementationDeps android.Paths
1165 var transitiveImplementationDeps []depset.DepSet[android.Path]
Yu Liu728da7c2025-01-11 00:54:32 +00001166 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001167 otherName := ctx.OtherModuleName(module)
1168 tag := ctx.OtherModuleDependencyTag(module)
1169
1170 if tag == certificateTag {
Yu Liu728da7c2025-01-11 00:54:32 +00001171 if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001172 certificates = append(certificates, dep.Certificate)
1173 } else {
1174 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1175 }
1176 }
Colin Crossb614cd42024-10-11 12:52:21 -07001177
1178 if IsJniDepTag(tag) {
1179 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1180 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1181 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1182 }
1183 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001184 })
Colin Crossb614cd42024-10-11 12:52:21 -07001185 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1186 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1187 })
1188
Makoto Onuki2ca84272024-02-10 00:15:21 +00001189 return jniLib, prebuiltJniPackages, certificates
1190}
1191
1192func collectJniDeps(ctx android.ModuleContext,
1193 shouldCollectRecursiveNativeDeps bool,
1194 checkNativeSdkVersion bool,
Yu Liuf6f85492025-01-13 21:02:36 +00001195 filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001196 var jniLibs []jniLib
1197 var prebuiltJniPackages android.Paths
1198 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001199
Yu Liuf6f85492025-01-13 21:02:36 +00001200 ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
Yu Liub732c842025-01-16 00:15:54 +00001201 if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
1202 return false
1203 }
Colin Crossa4f08812018-10-02 22:03:40 -07001204 otherName := ctx.OtherModuleName(module)
1205 tag := ctx.OtherModuleDependencyTag(module)
1206
Colin Crossf0913fb2020-07-29 12:59:39 -07001207 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Yu Liuf6f85492025-01-13 21:02:36 +00001208 if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
Spandan Das10c41362024-12-03 01:33:09 +00001209 if filter != nil && !filter(parent, module) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001210 return false
1211 }
1212
Yu Liuf6f85492025-01-13 21:02:36 +00001213 lib := dep.OutputFile
Colin Crossa4f08812018-10-02 22:03:40 -07001214 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001215 path := lib.Path()
1216 if seenModulePaths[path.String()] {
1217 return false
1218 }
1219 seenModulePaths[path.String()] = true
1220
Yu Liuf6f85492025-01-13 21:02:36 +00001221 commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
1222 if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
Cole Faust64cb7c92021-09-14 17:32:49 -07001223 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1224 otherName)
1225 }
1226
Colin Crossa4f08812018-10-02 22:03:40 -07001227 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001228 name: ctx.OtherModuleName(module),
1229 path: path,
Yu Liuf6f85492025-01-13 21:02:36 +00001230 target: commonInfo.Target,
1231 coverageFile: dep.CoverageOutputFile,
1232 unstrippedFile: dep.UnstrippedOutputFile,
1233 partition: dep.Partition,
1234 installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001235 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001236 } else if ctx.Config().AllowMissingDependencies() {
1237 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001238 } else {
1239 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1240 }
1241 } else {
1242 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001243 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001244
1245 return shouldCollectRecursiveNativeDeps
1246 }
1247
Colin Cross313aa542023-12-13 13:47:44 -08001248 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001249 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1250 }
1251
Peter Collingbournead84f972019-12-17 16:46:18 -08001252 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001253 })
1254
Makoto Onuki2ca84272024-02-10 00:15:21 +00001255 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001256}
1257
Colin Cross8bf14fc2024-09-25 16:41:31 -07001258func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001259 ctx.WalkDeps(func(child, parent android.Module) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001260 // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
1261 // heuristics to every transitive dependency, when it should probably be using the heuristics of the
1262 // immediate parent.
Yu Liuf1806032025-02-07 00:23:34 +00001263 isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
Artur Satayev1111b842020-04-27 19:05:28 +01001264 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001265 if !do(ctx, parent, am, isExternal) {
1266 return false
1267 }
Artur Satayev1111b842020-04-27 19:05:28 +01001268 }
1269 return !isExternal
1270 })
1271}
1272
1273func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1274 if ctx.Host() {
1275 return
1276 }
1277
1278 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross9cf55a52024-12-05 14:26:03 -08001279 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001280 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001281
1282 // Skip dependencies that are only available to APEXes; they are developed with updatability
1283 // in mind and don't need manual approval.
1284 if to.(android.ApexModule).NotAvailableForPlatform() {
1285 return true
1286 }
1287
Artur Satayev1111b842020-04-27 19:05:28 +01001288 if info, exist := depsInfo[depName]; exist {
1289 info.From = append(info.From, from.Name())
1290 info.IsExternal = info.IsExternal && externalDep
1291 depsInfo[depName] = info
1292 } else {
1293 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001294 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001295 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001296 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001297 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1298 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001299 }
Jiyong Park92315372021-04-02 08:45:46 +09001300 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1301 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1302 // string
1303 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001304 toMinSdkVersion = v
1305 }
Artur Satayev1111b842020-04-27 19:05:28 +01001306 }
1307 depsInfo[depName] = android.ApexModuleDepInfo{
1308 To: depName,
1309 From: []string{from.Name()},
1310 IsExternal: externalDep,
1311 MinSdkVersion: toMinSdkVersion,
1312 }
1313 }
Jooyung Han749dc692020-04-15 11:03:39 +09001314 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001315 })
1316
Jiyong Park92315372021-04-02 08:45:46 +09001317 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001318}
1319
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001320func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1321 return a.appProperties.EnforceDefaultTargetSdkVersion
1322}
1323
1324func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1325 a.appProperties.EnforceDefaultTargetSdkVersion = val
1326}
1327
Artur Satayev849f8442020-04-28 14:57:42 +01001328func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001329 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001330}
1331
Colin Cross0ea8ba82019-06-06 14:33:29 -07001332func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001333 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1334 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001335 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001336 }
Cole Fausteb9c1482024-11-18 16:49:19 -08001337 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001338}
1339
Yu Liuf1806032025-02-07 00:23:34 +00001340func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker {
1341 return AppDepInSameApexChecker{}
1342}
1343
1344type AppDepInSameApexChecker struct {
1345 android.BaseDepInSameApexChecker
1346}
1347
1348func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001349 if IsJniDepTag(tag) {
Jiyong Park0f80c182020-01-31 02:49:53 +09001350 return true
1351 }
Yu Liuf1806032025-02-07 00:23:34 +00001352 return depIsInSameApex(tag)
Jiyong Park0f80c182020-01-31 02:49:53 +09001353}
1354
Jiyong Parkf7487312019-10-17 12:54:30 +09001355func (a *AndroidApp) Privileged() bool {
1356 return Bool(a.appProperties.Privileged)
1357}
1358
Colin Crosse1a85552024-06-14 12:17:37 -07001359func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001360 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001361}
1362
Ivan Lozanod7586b62021-04-01 09:49:36 -04001363func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001364 a.appProperties.PreventInstall = true
1365}
1366
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001367func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1368 a.appProperties.IsCoverageVariant = coverage
1369}
1370
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001371func (a *AndroidApp) EnableCoverageIfNeeded() {}
1372
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001373var _ cc.Coverage = (*AndroidApp)(nil)
1374
Cole Faustb36d31d2024-08-27 16:04:28 -07001375func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1376 a.Library.IDEInfo(ctx, dpInfo)
1377 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001378}
1379
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001380func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1381 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1382}
1383
1384func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1385 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1386}
1387
Colin Cross1b16b0e2019-02-12 14:41:32 -08001388// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001389func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001390 module := &AndroidApp{}
1391
Liz Kammera7a64f32020-07-09 15:16:41 -07001392 module.Module.dexProperties.Optimize.EnabledByDefault = true
1393 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001394 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001395
Colin Crossae5caf52018-05-22 11:11:52 -07001396 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001397 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001398 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001399
Colin Crossce6734e2020-06-15 16:09:53 -07001400 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001401 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001402 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001403 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001404 &module.overridableAppProperties,
1405 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001406
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001407 module.usesLibrary.enforce = true
1408
Colin Crossa4f08812018-10-02 22:03:40 -07001409 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1410 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001411 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001412 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001413
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001414 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1415 a := ctx.Module().(*AndroidApp)
1416
1417 characteristics := ctx.Config().ProductAAPTCharacteristics()
1418 if characteristics == "default" || characteristics == "" {
1419 module.appProperties.Generate_product_characteristics_rro = nil
1420 // no need to create RRO
1421 return
1422 }
1423
1424 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1425 return
1426 }
1427
1428 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1429 rroManifestName := rroPackageName + "_manifest"
1430
1431 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1432 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1433
1434 rroManifestProperties := struct {
1435 Name *string
1436 Tools []string
1437 Out []string
1438 Srcs []string
1439 Cmd *string
1440 }{
1441 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001442 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001443 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001444 Srcs: []string{":" + a.Name() + "{.apk}"},
1445 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001446 }
Cole Fauste19d3352024-10-17 10:30:57 -07001447 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001448
1449 rroProperties := struct {
1450 Name *string
1451 Filter_product *string
1452 Aaptflags []string
1453 Manifest *string
Cole Faust5b989772024-11-06 11:03:16 -08001454 Resource_dirs proptools.Configurable[[]string]
Jihoon Kangf62f4222024-10-21 23:06:41 +00001455 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001456 }{
1457 Name: proptools.StringPtr(rroPackageName),
1458 Filter_product: proptools.StringPtr(characteristics),
1459 Aaptflags: []string{"--auto-add-overlay"},
1460 Manifest: proptools.StringPtr(":" + rroManifestName),
1461 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001462 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001463 }
优秀d75e9982024-05-09 07:15:55 +00001464 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1465 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1466 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1467 }
1468 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001469 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
Spandan Dasde588a32024-12-03 22:52:24 +00001470
1471 })
1472
1473 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1474 createInternalRuntimeOverlays(ctx, module.ModuleBase)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001475 })
1476
Colin Cross36242852017-06-23 15:06:31 -07001477 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001478}
Colin Crossae5caf52018-05-22 11:11:52 -07001479
Spandan Das71be42d2024-11-20 18:34:16 +00001480func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1481 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1482}
1483
Spandan Dasde588a32024-12-03 22:52:24 +00001484type createModuleContext interface {
1485 android.EarlyModuleContext
1486 CreateModule(android.ModuleFactory, ...interface{}) android.Module
1487}
1488
1489func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
1490 if !ctx.Config().HasDeviceProduct() {
1491 return
1492 }
1493 // vendor
1494 vendorOverlayProps := struct {
1495 Name *string
1496 Base *string
1497 Vendor *bool
1498 Product_specific *bool
1499 System_ext_specific *bool
1500 Manifest *string
1501 Sdk_version *string
1502 Compile_multilib *string
1503 Enabled proptools.Configurable[bool]
1504 }{
1505 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")),
1506 Base: proptools.StringPtr(a.Name()),
1507 Vendor: proptools.BoolPtr(true),
1508 Product_specific: proptools.BoolPtr(false),
1509 System_ext_specific: proptools.BoolPtr(false),
1510 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1511 Sdk_version: proptools.StringPtr("current"),
1512 Compile_multilib: proptools.StringPtr("first"),
1513 Enabled: a.EnabledProperty().Clone(),
1514 }
1515 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
1516
1517 // product
1518 productOverlayProps := struct {
1519 Name *string
1520 Base *string
1521 Vendor *bool
1522 Proprietary *bool
1523 Soc_specific *bool
1524 Product_specific *bool
1525 System_ext_specific *bool
1526 Manifest *string
1527 Sdk_version *string
1528 Compile_multilib *string
1529 Enabled proptools.Configurable[bool]
1530 }{
1531 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
1532 Base: proptools.StringPtr(a.Name()),
1533 Vendor: proptools.BoolPtr(false),
1534 Proprietary: proptools.BoolPtr(false),
1535 Soc_specific: proptools.BoolPtr(false),
1536 Product_specific: proptools.BoolPtr(true),
1537 System_ext_specific: proptools.BoolPtr(false),
1538 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1539 Sdk_version: proptools.StringPtr("current"),
1540 Compile_multilib: proptools.StringPtr("first"),
1541 Enabled: a.EnabledProperty().Clone(),
1542 }
1543 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
1544}
1545
Alix96ea88452023-08-31 15:48:23 +00001546// A dictionary of values to be overridden in the manifest.
1547type Manifest_values struct {
1548 // Overrides the value of package_name in the manifest
1549 ApplicationId *string
1550}
1551
Colin Crossae5caf52018-05-22 11:11:52 -07001552type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001553 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001554 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001555
Seth Moorec6f4b532023-02-02 13:22:26 -08001556 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001557 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001558
1559 // If specified, the mainline module package name in the test config is overwritten by it.
1560 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001561
1562 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001563}
1564
1565type AndroidTest struct {
1566 AndroidApp
1567
1568 appTestProperties appTestProperties
1569
1570 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001571
Dan Shi95d19422020-08-15 12:24:26 -07001572 testConfig android.Path
1573 extraTestConfigs android.Paths
1574 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001575}
1576
Jaewoong Jung0949f312019-09-11 10:25:18 -07001577func (a *AndroidTest) InstallInTestcases() bool {
1578 return true
1579}
1580
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001581type androidTestApp interface {
1582 includedInTestSuite(searchPrefix string) bool
1583}
1584
1585func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1586 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1587}
1588
1589func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1590 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1591}
1592
Colin Crossae5caf52018-05-22 11:11:52 -07001593func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001594 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001595 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001596 if a.appTestProperties.Instrumentation_target_package != nil {
1597 a.additionalAaptFlags = append(a.additionalAaptFlags,
1598 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1599 } else if a.appTestProperties.Instrumentation_for != nil {
1600 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001601 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1602 if overridden {
1603 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1604 }
1605 }
Alix96ea88452023-08-31 15:48:23 +00001606 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1607 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001608 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1609 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001610 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1611 }
1612 a.aapt.manifestValues.applicationId = *applicationId
1613 }
Colin Crossae5caf52018-05-22 11:11:52 -07001614 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001615
Jiyong Parkf528b702024-12-30 16:01:58 +09001616 for _, c := range a.testProperties.Test_options.Tradefed_options {
1617 configs = append(configs, c)
1618 }
easoncylee5bcff5d2020-04-30 14:57:06 +08001619 for _, module := range a.testProperties.Test_mainline_modules {
1620 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1621 }
1622
Jaewoong Jung39982342020-01-14 10:27:18 -08001623 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001624 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1625 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001626 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001627 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001628 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001629 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1630 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001631 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001632
Spandan Dasa65d1e02025-01-28 19:34:04 +00001633 // Install test deps
1634 if !ctx.Config().KatiEnabled() {
1635 pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name())
1636 if a.testConfig != nil {
1637 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig)
1638 }
1639 testDeps := append(a.data, a.extraTestConfigs...)
1640 for _, data := range android.SortedUniquePaths(testDeps) {
1641 dataPath := android.DataPath{SrcPath: data}
1642 ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
1643 }
1644 }
1645
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001646 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001647 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001648 OutputFile: a.OutputFile(),
1649 TestConfig: a.testConfig,
1650 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001651 TestSuites: a.testProperties.Test_suites,
1652 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001653 LocalCertificate: a.certificate.AndroidMkString(),
1654 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001655 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1656 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001657 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001658 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1659 TestOnly: true,
1660 TopLevelTarget: true,
1661 })
1662
Cole Faust866ab392025-01-23 12:56:20 -08001663 moduleInfoJSON := ctx.ModuleInfoJSON()
1664 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
1665 if a.testConfig != nil {
1666 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String())
1667 }
1668 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...)
1669 if len(a.testProperties.Test_suites) > 0 {
1670 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...)
1671 } else {
1672 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
1673 }
1674
1675 if _, ok := testConfig.(android.WritablePath); ok {
1676 moduleInfoJSON.AutoTestConfig = []string{"true"}
1677 }
1678 moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
Colin Cross303e21f2018-08-07 16:49:25 -07001679}
1680
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001681func testcaseRel(paths android.Paths) []string {
1682 relPaths := []string{}
1683 for _, p := range paths {
1684 relPaths = append(relPaths, p.Rel())
1685 }
1686 return relPaths
1687}
1688
Jaewoong Jung39982342020-01-14 10:27:18 -08001689func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1690 if testConfig == nil {
1691 return nil
1692 }
1693
1694 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001695 rule := android.NewRuleBuilder(pctx, ctx)
1696 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001697 fixNeeded := false
1698
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001699 // 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 -08001700 if ctx.ModuleName() != a.installApkName {
1701 fixNeeded = true
1702 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1703 }
1704
Cole Faust258b96f2024-10-04 10:48:24 -07001705 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1706 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001707 fixNeeded = true
1708 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001709 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001710 }
1711
Seth Moorec6f4b532023-02-02 13:22:26 -08001712 if a.appTestProperties.Mainline_package_name != nil {
1713 fixNeeded = true
1714 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1715 }
1716
Jaewoong Jung39982342020-01-14 10:27:18 -08001717 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001718 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001719 return fixedConfig
1720 }
1721 return testConfig
1722}
1723
Yihan Dong8be09c22024-08-29 15:32:13 +08001724func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1725 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1726 // Instrument the android_test_helper target to log potential API calls at the run time.
1727 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1728 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1729 a.setApiMapper(true)
1730 }
1731 a.AndroidApp.DepsMutator(ctx)
1732}
1733
Colin Cross303e21f2018-08-07 16:49:25 -07001734func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001735 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1736 // Instrument the android_test_helper target to log potential API calls at the run time.
1737 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1738 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1739 a.setApiMapper(true)
1740 }
Colin Cross303e21f2018-08-07 16:49:25 -07001741 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001742}
1743
1744func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1745 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001746 if a.appTestProperties.Instrumentation_for != nil {
1747 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1748 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1749 // use instrumentationForTag instead of libTag.
1750 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1751 }
Colin Crossae5caf52018-05-22 11:11:52 -07001752}
1753
Colin Cross1b16b0e2019-02-12 14:41:32 -08001754// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1755// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001756func AndroidTestFactory() android.Module {
1757 module := &AndroidTest{}
1758
Jared Duke63a3da92022-06-02 19:11:14 +00001759 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001760
1761 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001762 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001763 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001764 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1765 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001766 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001767 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001768
Colin Crossce6734e2020-06-15 16:09:53 -07001769 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001770 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001771 &module.aaptProperties,
1772 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001773 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001774 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001775 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001776
Colin Crossa4f08812018-10-02 22:03:40 -07001777 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1778 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001779 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001780
Colin Crossae5caf52018-05-22 11:11:52 -07001781 return module
1782}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001783
Colin Cross252fc6f2018-10-04 15:22:03 -07001784type appTestHelperAppProperties struct {
1785 // list of compatibility suites (for example "cts", "vts") that the module should be
1786 // installed into.
1787 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001788
1789 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1790 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1791 // explicitly.
1792 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001793
1794 // Install the test into a folder named for the module in all test suites.
1795 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001796
1797 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001798}
1799
1800type AndroidTestHelperApp struct {
1801 AndroidApp
1802
1803 appTestHelperAppProperties appTestHelperAppProperties
1804}
1805
Jaewoong Jung326a9412019-11-21 10:41:00 -08001806func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1807 return true
1808}
1809
Colin Cross1b16b0e2019-02-12 14:41:32 -08001810// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1811// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1812// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001813func AndroidTestHelperAppFactory() android.Module {
1814 module := &AndroidTestHelperApp{}
1815
Jared Duke63a3da92022-06-02 19:11:14 +00001816 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001817 module.Module.dexProperties.Optimize.EnabledByDefault = true
Christoffer Adamsenc8fd1f12025-01-06 19:04:03 +01001818 module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
1819 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross252fc6f2018-10-04 15:22:03 -07001820
1821 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001822 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1823 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001824 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001825 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001826
Colin Crossce6734e2020-06-15 16:09:53 -07001827 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001828 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001829 &module.aaptProperties,
1830 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001831 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001832 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001833
1834 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1835 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001836 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001837 return module
1838}
1839
Colin Crossbd01e2a2018-10-04 15:21:03 -07001840type AndroidAppCertificate struct {
1841 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001842
Colin Crossbd01e2a2018-10-04 15:21:03 -07001843 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001844 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001845}
1846
1847type AndroidAppCertificateProperties struct {
1848 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1849 Certificate *string
1850}
1851
Yu Liu728da7c2025-01-11 00:54:32 +00001852type AndroidAppCertificateInfo struct {
1853 Certificate Certificate
1854}
1855
1856var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]()
1857
Colin Cross1b16b0e2019-02-12 14:41:32 -08001858// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1859// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001860func AndroidAppCertificateFactory() android.Module {
1861 module := &AndroidAppCertificate{}
1862 module.AddProperties(&module.properties)
1863 android.InitAndroidModule(module)
1864 return module
1865}
1866
Colin Crossbd01e2a2018-10-04 15:21:03 -07001867func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1868 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001869 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001870 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1871 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001872 }
Yu Liu728da7c2025-01-11 00:54:32 +00001873
1874 android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{
1875 Certificate: c.Certificate,
1876 })
Colin Crossbd01e2a2018-10-04 15:21:03 -07001877}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001878
1879type OverrideAndroidApp struct {
1880 android.ModuleBase
1881 android.OverrideModuleBase
1882}
1883
Sasha Smundak613cbb12020-06-05 10:27:23 -07001884func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001885 // All the overrides happen in the base module.
1886 // TODO(jungjw): Check the base module type.
1887}
1888
1889// override_android_app is used to create an android_app module based on another android_app by overriding
1890// some of its properties.
1891func OverrideAndroidAppModuleFactory() android.Module {
1892 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001893 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001894 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001895 &overridableAppProperties{},
1896 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001897
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001898 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001899 android.InitOverrideModule(m)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001900 android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) {
Spandan Dasde588a32024-12-03 22:52:24 +00001901 createInternalRuntimeOverlays(ctx, m.ModuleBase)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001902 }, 1) // Run after soong config load hoook
Spandan Dasde588a32024-12-03 22:52:24 +00001903
Jaewoong Jung525443a2019-02-28 15:35:54 -08001904 return m
1905}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001906
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001907type OverrideAndroidTest struct {
1908 android.ModuleBase
1909 android.OverrideModuleBase
1910}
1911
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001912func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001913 // All the overrides happen in the base module.
1914 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001915 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1916 TestOnly: true,
1917 TopLevelTarget: true,
1918 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001919}
1920
1921// override_android_test is used to create an android_app module based on another android_test by overriding
1922// some of its properties.
1923func OverrideAndroidTestModuleFactory() android.Module {
1924 m := &OverrideAndroidTest{}
1925 m.AddProperties(&overridableAppProperties{})
1926 m.AddProperties(&appTestProperties{})
1927
1928 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1929 android.InitOverrideModule(m)
1930 return m
1931}
1932
Colin Cross50ddcc42019-05-16 12:28:22 -07001933type UsesLibraryProperties struct {
1934 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
Cole Faust64f2d842024-10-17 13:28:34 -07001935 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001936
1937 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1938 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001939 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001940
1941 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1942 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1943 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001944
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001945 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1946 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1947 // normally is the same as the module name, but there are exceptions.
1948 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001949
1950 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1951 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1952 // added to the APK's manifest's <uses-library> elements.
1953 //
1954 // Care must be taken when using this as it could result in runtime errors if the APK actually
1955 // uses classes provided by the library and which are not provided in any other way.
1956 //
1957 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1958 // android.test.base shared library (and related libraries) but which depend on some common
1959 // libraries that depend on the android.test.base library. Without this those tests will end up
1960 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1961 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1962 // test altogether by providing access to classes that the tests were not expecting. Those tests
1963 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1964 // with the classes provided by the android.test.base library.
1965 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001966
1967 // The module names of optional uses-library libraries that are missing from the source tree.
1968 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001969}
1970
1971// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1972// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1973// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1974// with knowledge of their shared libraries.
1975type usesLibrary struct {
1976 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001977
1978 // Whether to enforce verify_uses_library check.
1979 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001980
1981 // Whether dexpreopt should be disabled
1982 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001983}
1984
Colin Cross4a80a152022-12-21 21:51:52 -08001985func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001986 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07001987 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001988 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1989 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001990 // Only add these extra dependencies if the module is an app that depends on framework
1991 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001992 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001993 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001994 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1995 // class loader context for dex2oat. Add them as a dependency with a special tag.
1996 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1997 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1998 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001999 }
Cole Faust64f2d842024-10-17 13:28:34 -07002000 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00002001 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002002 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07002003 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002004 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07002005 }
2006}
2007
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002008// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07002009func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07002010 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002011 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01002012 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002013 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
2014 }
2015 return exists
2016 })
Colin Cross50ddcc42019-05-16 12:28:22 -07002017 return optionalUsesLibs
2018}
2019
Ulya Trafimovich24446712021-07-15 14:59:34 +01002020// Returns a map of module names of shared library dependencies to the paths to their dex jars on
2021// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002022func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
2023 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002024
2025 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
2026 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
2027 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
2028 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002029 }
2030
Yu Liu27b74aa2025-01-11 00:04:41 +00002031 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Ulya Trafimovich24446712021-07-15 14:59:34 +01002032 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
2033 if !isUsesLibTag {
2034 return
2035 }
2036
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002037 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01002038
Yu Liu27b74aa2025-01-11 00:04:41 +00002039 javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
2040 if !ok {
2041 return
2042 }
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002043 // Skip stub libraries. A dependency on the implementation library has been added earlier,
2044 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
2045 // from implementation libraries by their name, which is different as it has a suffix.
Yu Liu27b74aa2025-01-11 00:04:41 +00002046 if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
2047 if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002048 return
2049 }
2050 }
2051
Yu Liu27b74aa2025-01-11 00:04:41 +00002052 if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002053 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
2054 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
2055 // This will be restricted to optional_uses_libs
Yu Liu27b74aa2025-01-11 00:04:41 +00002056 if tag == usesLibOptTag && lib.DexJarBuildPath.PathOrNil() == nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002057 u.shouldDisableDexpreopt = true
2058 return
2059 }
2060 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002061 libName := dep
Yu Liu27b74aa2025-01-11 00:04:41 +00002062 if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil {
2063 libName = *ulib.ProvidesUsesLib
Ulya Trafimovich24446712021-07-15 14:59:34 +01002064 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002065 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Yu Liu27b74aa2025-01-11 00:04:41 +00002066 lib.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath,
2067 lib.ClassLoaderContexts)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002068 } else if ctx.Config().AllowMissingDependencies() {
2069 ctx.AddMissingDependencies([]string{dep})
2070 } else {
2071 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
2072 }
2073 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002074 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002075}
2076
2077// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
2078// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
2079// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07002080func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
2081 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
2082 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002083 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002084}
2085
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002086// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
Cole Faust64f2d842024-10-17 13:28:34 -07002087func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
2088 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002089 u.usesLibraryProperties.Enforce_uses_libs = &enforce
2090}
2091
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002092// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
2093// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
2094// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
2095// extension: APKs are supposed to end with '.apk').
2096func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00002097 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002098
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002099 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07002100
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002101 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
2102 // check is not necessary, and although it is good to have, it is difficult to maintain on
2103 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
2104 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01002105 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00002106 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002107 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002108 }
2109
Colin Crossf1a035e2020-11-16 17:32:30 -08002110 rule := android.NewRuleBuilder(pctx, ctx)
2111 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07002112 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002113 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002114 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00002115 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002116
2117 if outputFile != nil {
2118 cmd.FlagWithOutput("-o ", outputFile)
2119 }
Colin Cross50ddcc42019-05-16 12:28:22 -07002120
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002121 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
2122 cmd.Flag("--enforce-uses-libraries-relax")
2123 }
2124
Jiakai Zhangf98da192024-04-15 11:15:41 +00002125 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
2126 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002127 cmd.FlagWithArg("--uses-library ", lib)
2128 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00002129 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002130 cmd.FlagWithArg("--optional-uses-library ", lib)
2131 }
2132
Jiakai Zhangf98da192024-04-15 11:15:41 +00002133 // Also add missing optional uses libs, as the manifest check expects them.
2134 // Note that what we add here are the module names of those missing libs, not library names, while
2135 // the manifest check actually expects library names. However, the case where a library is missing
2136 // and the module name != the library name is too rare for us to handle.
2137 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
2138 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
2139 }
2140
Colin Crossf1a035e2020-11-16 17:32:30 -08002141 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002142 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002143}
Colin Cross50ddcc42019-05-16 12:28:22 -07002144
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002145// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
2146// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002147func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
2148 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002149 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00002150 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07002151}
2152
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002153// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
2154// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002155func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
2156 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
2157 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07002158}