blob: 560129b6469f01a5eedb61afbf4abc02a106b318 [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
Yu Liu0a37d422025-02-13 02:05:00 +000075
76 Prebuilt bool
77 AppSet bool
78 Privileged bool
79 OutputFile android.Path
80 InstallApkName string
81 JacocoReportClassesFile android.Path
82 Certificate Certificate
83 PrivAppAllowlist android.OptionalPath
84 OverriddenManifestPackageName *string
Colin Cross99939e92024-10-01 16:02:46 -070085}
86
87var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
88
Colin Cross30e076a2015-04-13 13:58:27 -070089// AndroidManifest.xml merging
90// package splits
91
Colin Crossfabb6082018-02-20 17:22:23 -080092type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070093 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070094 Additional_certificates []string
95
96 // If set, create package-export.apk, which other packages can
97 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080098 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070099
Colin Cross16056062017-12-13 22:46:28 -0800100 // Specifies that this app should be installed to the priv-app directory,
101 // where the system will grant it additional privileges not available to
102 // normal apps.
103 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -0700104
105 // list of resource labels to generate individual resource packages
106 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -0400107
Colin Crossa4f08812018-10-02 22:03:40 -0700108 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +0000109 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -0700110
Colin Cross7204cf02020-05-06 17:51:39 -0700111 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -0800112 // sdk_version.
113 Jni_uses_platform_apis *bool
114
Colin Cross7204cf02020-05-06 17:51:39 -0700115 // if true, use JNI libraries that link against SDK APIs even if this module does not set
116 // sdk_version.
117 Jni_uses_sdk_apis *bool
118
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700119 // STL library to use for JNI libraries.
120 Stl *string `android:"arch_variant"`
121
Colin Crosse4246ab2019-02-05 21:55:21 -0800122 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900123 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
124 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
125 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
126 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800127 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800128
129 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
130 // they are used from inside the APK at runtime.
131 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700132
Jiyong Parkd044bb42024-05-15 02:09:54 +0900133 // Forces native libraries to always be packaged into the APK,
134 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
135 // True for android_test* modules.
136 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700137
138 // If set, find and merge all NOTICE files that this module and its dependencies have and store
139 // it in the APK as an asset.
140 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700141
142 // cc.Coverage related properties
143 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700144 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100145
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000146 // It can be set to test the behaviour of default target sdk version.
147 // Only required when updatable: false. It is an error if updatable: true and this is false.
148 Enforce_default_target_sdk_version *bool
149
150 // If set, the targetSdkVersion for the target is set to the latest default API level.
151 // This would be by default false, unless updatable: true or
152 // enforce_default_target_sdk_version: true in which case this defaults to true.
153 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
154
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100155 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100156 // additional rules to make sure an app can safely be updated. Default is false.
157 // Prefer using other specific properties if build behaviour must be changed; avoid using this
158 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100159 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000160
161 // Specifies the file that contains the allowlist for this app.
162 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900163
164 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
165 // and install the RRO package to /product partition, instead of passing --product argument
166 // to aapt2. Default is false.
167 // Setting this will make this APK identical to all targets, regardless of
168 // PRODUCT_CHARACTERISTICS.
169 Generate_product_characteristics_rro *bool
170
171 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
172 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700173}
174
Jaewoong Jung525443a2019-02-28 15:35:54 -0800175// android_app properties that can be overridden by override_android_app
176type overridableAppProperties struct {
177 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
178 // or an android_app_certificate module name in the form ":module".
Cole Fausteb9c1482024-11-18 16:49:19 -0800179 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700180
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800181 // Name of the signing certificate lineage file or filegroup module.
182 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700183
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400184 // For overriding the --rotation-min-sdk-version property of apksig
185 RotationMinSdkVersion *string
186
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700187 // 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 -0700188 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800189
190 // the logging parent of this app.
191 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000192
193 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
194 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000195
196 // Names of modules to be overridden. Listed modules can only be other binaries
197 // (in Make or Soong).
198 // This does not completely prevent installation of the overridden binaries, but if both
199 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
200 // from PRODUCT_PACKAGES.
201 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800202}
203
Colin Cross30e076a2015-04-13 13:58:27 -0700204type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700205 Library
206 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800207 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700208
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900209 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700210
Colin Crossfabb6082018-02-20 17:22:23 -0800211 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700212
Jaewoong Jung525443a2019-02-28 15:35:54 -0800213 overridableAppProperties overridableAppProperties
214
Colin Cross403cc152020-07-06 14:15:24 -0700215 jniLibs []jniLib
216 installPathForJNISymbols android.Path
217 embeddedJniLibs bool
218 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700219
220 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800221
222 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
223 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800224
Colin Cross70dda7e2019-10-01 22:05:35 -0700225 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700226
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700227 onDeviceDir string
228
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800229 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700230
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900231 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100232
233 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000234
235 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000236
237 privAppAllowlist android.OptionalPath
Spandan Dasde588a32024-12-03 22:52:24 +0000238
239 requiredModuleNames []string
Colin Crosse1731a52017-12-14 11:22:55 -0800240}
241
Martin Stjernholm6d415272020-01-31 17:10:36 +0000242func (a *AndroidApp) IsInstallable() bool {
243 return Bool(a.properties.Installable)
244}
245
Colin Crossa14fb6a2024-10-23 16:57:06 -0700246func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000247 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700248}
249
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900250func (a *AndroidApp) OutputFile() android.Path {
251 return a.outputFile
252}
253
Colin Cross503c1d02020-01-28 14:00:53 -0800254func (a *AndroidApp) Certificate() Certificate {
255 return a.certificate
256}
257
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700258func (a *AndroidApp) JniCoverageOutputs() android.Paths {
259 return a.jniCoverageOutputs
260}
261
Andrei Onea580636b2022-08-17 16:53:46 +0000262func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
263 return a.privAppAllowlist
264}
265
Colin Crossa97c5d32018-03-28 14:58:31 -0700266var _ AndroidLibraryDependency = (*AndroidApp)(nil)
267
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900268type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800269 Pem, Key android.Path
270 presigned bool
271}
272
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700273var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800274
275func (c Certificate) AndroidMkString() string {
276 if c.presigned {
277 return "PRESIGNED"
278 } else {
279 return c.Pem.String()
280 }
Colin Cross30e076a2015-04-13 13:58:27 -0700281}
282
Colin Cross46c9b8b2017-06-22 16:51:17 -0700283func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900284 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700285 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
286 }
287
Jiyong Parkf1691d22021-03-29 20:11:58 +0900288 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000289 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
290 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100291 if sdkDep.hasFrameworkLibs() {
292 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700293 }
Colin Crossa4f08812018-10-02 22:03:40 -0700294
Jiyong Park92315372021-04-02 08:45:46 +0900295 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700296
297 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
298 ctx.PropertyErrorf("jni_uses_sdk_apis",
299 "can only be set for modules that do not set sdk_version")
300 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
301 ctx.PropertyErrorf("jni_uses_platform_apis",
302 "can only be set for modules that set sdk_version")
303 }
304
Colin Crossa4f08812018-10-02 22:03:40 -0700305 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700306 variation := append(jniTarget.Variations(),
307 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000308
Jiyong Park92d84042024-05-17 22:58:54 +0000309 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
310 // Many factors are considered here.
311 // 1. Basically, the selection follows whether the app has sdk_version set or not.
312 jniUsesSdkVariant := usesSDK
313 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
314 if Bool(a.appProperties.Jni_uses_sdk_apis) {
315 jniUsesSdkVariant = true
316 }
317 if Bool(a.appProperties.Jni_uses_platform_apis) {
318 jniUsesSdkVariant = false
319 }
320 // 3. Then the use of SDK variant is again prohibited for the following cases:
321 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
322 // partition (not only the app) is considered unbudled, there's no need to use the
323 // SDK variant.
324 // 3.2. the app doesn't support embedding the JNI libs
325 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
326 jniUsesSdkVariant = false
327 }
328 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000329 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
330 }
Jiyong Park92d84042024-05-17 22:58:54 +0000331
332 // Use the installable dep tag when the JNIs are not embedded
333 var tag dependencyTag
334 if a.shouldEmbedJnis(ctx) {
335 tag = jniLibTag
336 } else {
337 tag = jniInstallTag
338 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000339 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700340 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000341 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
342 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
343 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700344}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700345
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700346func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800347 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700348 if cert != "" {
349 ctx.AddDependency(ctx.Module(), certificateTag, cert)
350 }
351
Andrei Onea580636b2022-08-17 16:53:46 +0000352 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000353 // There are a few uids that are explicitly considered privileged regardless of their
354 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
355 // but for now, allow it not to be in priv-app.
356 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
357 if !privilegedBecauseOfUid {
358 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
359 }
Andrei Onea580636b2022-08-17 16:53:46 +0000360 }
361
Colin Crossbd01e2a2018-10-04 15:21:03 -0700362 for _, cert := range a.appProperties.Additional_certificates {
363 cert = android.SrcIsModule(cert)
364 if cert != "" {
365 ctx.AddDependency(ctx.Module(), certificateTag, cert)
366 } else {
367 ctx.PropertyErrorf("additional_certificates",
368 `must be names of android_app_certificate modules in the form ":module"`)
369 }
370 }
Colin Cross30e076a2015-04-13 13:58:27 -0700371}
372
Spandan Dasb0410872024-06-25 03:30:03 +0000373// TODO(b/156476221): Remove this allowlist
374var (
375 missingMinSdkVersionMtsAllowlist = []string{
376 "CellBroadcastReceiverGoogleUnitTests",
377 "CellBroadcastReceiverUnitTests",
378 "CtsBatterySavingTestCases",
379 "CtsDeviceAndProfileOwnerApp23",
380 "CtsDeviceAndProfileOwnerApp30",
381 "CtsIntentSenderApp",
382 "CtsJobSchedulerTestCases",
383 "CtsMimeMapTestCases",
384 "CtsTareTestCases",
385 "LibStatsPullTests",
386 "MediaProviderClientTests",
387 "TeleServiceTests",
388 "TestExternalImsServiceApp",
389 "TestSmsRetrieverApp",
390 "TetheringPrivilegedTests",
391 }
392)
393
394func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
395 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
396 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
397 }
398}
399
Jeongik Cha538c0d02019-07-11 15:54:27 +0900400func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000401 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000402 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
403 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700404 packageName := a.overridableAppProperties.Package_name.Get(ctx)
405 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000406 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
407 }
408 a.aapt.manifestValues.applicationId = *applicationId
409 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900410 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700411 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
412 TestOnly: true,
413 })
Yu Liu0a37d422025-02-13 02:05:00 +0000414 appInfo := &AppInfo{
Colin Cross99939e92024-10-01 16:02:46 -0700415 Updatable: Bool(a.appProperties.Updatable),
416 TestHelperApp: true,
Yu Liu0a37d422025-02-13 02:05:00 +0000417 }
418 setCommonAppInfo(appInfo, a)
419 android.SetProvider(ctx, AppInfoProvider, appInfo)
Cole Faust866ab392025-01-23 12:56:20 -0800420
421 moduleInfoJSON := ctx.ModuleInfoJSON()
422 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
423 if len(a.appTestHelperAppProperties.Test_suites) > 0 {
424 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...)
425 } else {
426 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
427 }
Cole Faust5e1454a2025-03-11 15:55:59 -0700428
429 android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
430 TestSuites: a.appTestHelperAppProperties.Test_suites,
431 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900432}
433
Colin Cross46c9b8b2017-06-22 16:51:17 -0700434func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100435 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000436 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700437 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000438 a.generateJavaUsedByApex(ctx)
Colin Crossb614cd42024-10-11 12:52:21 -0700439
440 var embeddedJniLibs []android.Path
441
442 if a.embeddedJniLibs {
443 for _, jni := range a.jniLibs {
444 embeddedJniLibs = append(embeddedJniLibs, jni.path)
445 }
446 }
Yu Liu0a37d422025-02-13 02:05:00 +0000447 overriddenName := a.OverriddenManifestPackageName()
448 appInfo := &AppInfo{
449 Updatable: Bool(a.appProperties.Updatable),
450 TestHelperApp: false,
451 EmbeddedJNILibs: embeddedJniLibs,
452 MergedManifestFile: a.mergedManifest,
453 OverriddenManifestPackageName: &overriddenName,
454 }
455 setCommonAppInfo(appInfo, a)
456 android.SetProvider(ctx, AppInfoProvider, appInfo)
Spandan Dasde588a32024-12-03 22:52:24 +0000457
458 a.requiredModuleNames = a.getRequiredModuleNames(ctx)
Cole Faust1dcf9e42025-02-19 17:23:34 -0800459
460 if a.dexer.proguardDictionary.Valid() {
461 android.SetProvider(ctx, ProguardProvider, ProguardInfo{
462 ModuleName: ctx.ModuleName(),
463 Class: "APPS",
464 ProguardDictionary: a.dexer.proguardDictionary.Path(),
465 ProguardUsageZip: a.dexer.proguardUsageZip.Path(),
466 ClassesJar: a.implementationAndResourcesJar,
467 })
468 }
Spandan Dasde588a32024-12-03 22:52:24 +0000469}
470
471func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
472 var required []string
473 if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
474 required = []string{a.productCharacteristicsRROPackageName()}
475 }
476 // Install the vendor overlay variant if this app is installed.
477 if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
478 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
479 }
480 // Install the product overlay variant if this app is installed.
481 if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
482 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
483 }
484 return required
Colin Crossae5caf52018-05-22 11:11:52 -0700485}
486
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100487func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100488 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900489 if !a.SdkVersion(ctx).Stable() {
490 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100491 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000492 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100493 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
494 }
Jooyung Han749dc692020-04-15 11:03:39 +0900495
Jiyong Park92315372021-04-02 08:45:46 +0900496 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900497 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000498 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900499 } else {
500 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
501 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000502
503 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
504 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
505 }
506 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
507 if a.deviceProperties.Target_sdk_version == nil {
508 a.SetEnforceDefaultTargetSdkVersion(true)
509 }
510 }
511
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100512 a.checkPlatformAPI(ctx)
513 a.checkSdkVersions(ctx)
514}
515
Jiyong Park970c5242024-05-17 22:58:54 +0000516// Ensures that use_embedded_native_libs are set for apk-in-apex
517func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
518 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
519 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000520 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000521
522 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
523 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
524 }
525}
526
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900527// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
528// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900529func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900530 // 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 +0000531 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900532 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
533 return
534 }
Yu Liufc8d5c12025-01-09 00:19:06 +0000535 if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
536 panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
537 }
Yu Liuef9e63e2025-03-04 19:01:28 +0000538 commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoProvider)
Yu Liufc8d5c12025-01-09 00:19:06 +0000539 if !ok {
540 panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
541 }
Jooyung Han652d5b32020-05-20 17:12:13 +0900542 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900543 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
544 // handled properly regardless of sdk finalization.
Yu Liu5d3a2cf2025-02-06 00:25:22 +0000545 ver := ""
546 if !commonInfo.MinSdkVersion.IsPlatform {
547 ver = commonInfo.MinSdkVersion.ApiLevel.String()
548 }
549 jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900550 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Yu Liufc8d5c12025-01-09 00:19:06 +0000551 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 +0000552 ver, minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900553 return
554 }
555
556 })
557}
558
Sasha Smundak6ad77252019-05-01 13:16:22 -0700559// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800560// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700561func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900562 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800563 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900564 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800565 }
566
Jiyong Parkd044bb42024-05-15 02:09:54 +0900567 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
568 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
569 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800570}
571
Colin Cross43f08db2018-11-12 10:13:39 -0800572// Returns whether this module should have the dex file stored uncompressed in the APK.
573func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800574 if Bool(a.appProperties.Use_embedded_dex) {
575 return true
576 }
577
Colin Cross53a87f52019-06-25 13:35:30 -0700578 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
579 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900580 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000581 return true
582 }
583
Colin Cross53a87f52019-06-25 13:35:30 -0700584 if ctx.Config().UnbundledBuild() {
585 return false
586 }
587
Spandan Dase21a8d42024-01-23 23:56:29 +0000588 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700589}
590
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700591func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900592 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000593 Bool(a.appProperties.Updatable) ||
594 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000595}
596
Liz Kammer9f9fd022020-06-18 19:44:06 +0000597func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
598 aaptFlags := []string{"--rename-manifest-package " + packageName}
599 if renameResourcesPackage {
600 // Required to rename the package name in the resources table.
601 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
602 }
603 return aaptFlags
604}
605
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900606func (a *AndroidApp) OverriddenManifestPackageName() string {
607 return a.overriddenManifestPackageName
608}
609
Liz Kammer9f9fd022020-06-18 19:44:06 +0000610func (a *AndroidApp) renameResourcesPackage() bool {
611 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
612}
613
Jihoon Kang9049c272024-03-19 21:57:36 +0000614func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Yu Liu460cf372025-01-10 00:34:06 +0000615 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000616 tag := ctx.OtherModuleDependencyTag(dep)
617 switch tag {
Spandan Das13193892025-03-03 21:49:06 +0000618 case staticLibTag, rroDepTag:
Jihoon Kang9aef7772024-06-14 23:45:06 +0000619 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
620 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
621 }
622
623 case aconfigDeclarationTag:
624 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
625 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
626 } else {
627 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
628 "flags_packages property, but %s is not aconfig_declarations module type",
629 dep.Name(),
630 )
631 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000632 }
633 })
634
Jihoon Kang9aef7772024-06-14 23:45:06 +0000635 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000636}
637
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800638func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900639 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900640 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900641 usePlatformAPI = true
642 }
643 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000644
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700645 // Ask manifest_fixer to add or update the application element indicating this app has no code.
646 a.aapt.hasNoCode = !a.hasCode(ctx)
647
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800648 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800649
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800650 // 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 +0900651 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800652 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900653 characteristics := ctx.Config().ProductAAPTCharacteristics()
654 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
655 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700656 }
657
Dan Willemsen72be5902018-10-24 20:24:57 -0700658 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
659 // Product AAPT config
660 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800661 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700662 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700663
Dan Willemsen72be5902018-10-24 20:24:57 -0700664 // Product AAPT preferred config
665 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800666 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700667 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700668 }
669
Jiyong Park7f67f482019-01-05 12:57:48 +0900670 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700671 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
672 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700673 // The product override variable has a priority over the package_name property.
674 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700675 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700676 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000677 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900678 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900679 }
680
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800681 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
682
Colin Crosse560c4a2019-03-19 16:03:11 -0700683 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800684 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100685 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000686 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
687 a.aapt.defaultManifestVersion = override
688 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000689 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000690 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100691 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000692
Rico Winda2fa2632024-03-13 13:09:17 +0100693 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200694 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000695
696 aconfigTextFilePaths := getAconfigFilePaths(ctx)
697
Alixf7a10272023-09-27 16:47:56 +0000698 a.aapt.buildActions(ctx,
699 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000700 sdkContext: android.SdkContext(a),
701 classLoaderContexts: a.classLoaderContexts,
702 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
703 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100704 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000705 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000706 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000707 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000708 },
709 )
Colin Cross30e076a2015-04-13 13:58:27 -0700710
Colin Cross46c9b8b2017-06-22 16:51:17 -0700711 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700712 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000713
714 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
715 AconfigTextFiles: aconfigTextFilePaths,
716 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800717}
Colin Cross30e076a2015-04-13 13:58:27 -0700718
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800719func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700720 var staticLibProguardFlagFiles android.Paths
Yu Liu80b68c42025-01-15 18:14:34 +0000721 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Colin Cross313aa542023-12-13 13:47:44 -0800722 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400723 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
724 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
725 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700726 }
727 })
728
729 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
730
Colin Cross312634e2023-11-21 15:13:56 -0800731 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200732 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100733 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
734 // live for code references and (transitively) mark these as live.
735 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
736 // dead code alive)
737 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
738 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800739}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800740
Colin Cross403cc152020-07-06 14:15:24 -0700741func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800742 var installDir string
743 if ctx.ModuleName() == "framework-res" {
744 // framework-res.apk is installed as system/framework/framework-res.apk
745 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900746 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800747 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800748 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800749 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800750 }
Colin Cross403cc152020-07-06 14:15:24 -0700751
752 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
753}
754
Yu Liu7eebf8b2025-01-17 00:23:57 +0000755func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) {
Colin Cross403cc152020-07-06 14:15:24 -0700756 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000757 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700758 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100759 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700760 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100761 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700762 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700763 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100764 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700765 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800766 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700767
Rico Wind98e7fa82023-11-27 09:44:03 +0100768 var packageResources = a.exportPackage
769
Yu Liu460cf372025-01-10 00:34:06 +0000770 javaInfo := &JavaInfo{}
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800771 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200772 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100773 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
774 aapt2Convert(ctx, protoFile, packageResources, "proto")
775 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
776 }
777
Colin Cross4eae06d2023-06-20 22:40:02 -0700778 var extraSrcJars android.Paths
779 var extraClasspathJars android.Paths
780 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800781 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700782 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
783 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
784 // classpath when compiling everything else, and add it to the final classes jar.
785 extraClasspathJars = android.Paths{a.aapt.rJar}
786 extraCombinedJars = android.Paths{a.aapt.rJar}
787 } else {
788 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
789 // R.java files for the app's package and the packages from all transitive static android_library
790 // dependencies. Compile the srcjar alongside the rest of the sources.
791 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
792 }
793
Yu Liu460cf372025-01-10 00:34:06 +0000794 javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200795 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100796 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
797 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
798 packageResources = binaryResources
799 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800800 }
Colin Cross30e076a2015-04-13 13:58:27 -0700801
Yu Liu7eebf8b2025-01-17 00:23:57 +0000802 return a.dexJarFile.PathOrNil(), packageResources, javaInfo
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800803}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800804
Sam Delmerico82602492022-06-10 17:05:42 +0000805func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700806 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000807 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700808 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700809 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700810 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800811 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000812 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700813 for _, jni := range jniLibs {
814 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700815 // Only collect coverage for the first target arch if this is a multilib target.
816 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
817 // data file path collisions since the current coverage file path format doesn't contain
818 // arch-related strings. This is fine for now though; the code coverage team doesn't use
819 // multi-arch targets such as test_suite_* for coverage collections yet.
820 //
821 // Work with the team to come up with a new format that handles multilib modules properly
822 // and change this.
823 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700824 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700825 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
826 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700827 }
828 }
Colin Cross403cc152020-07-06 14:15:24 -0700829 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700830 }
831 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800832 return jniJarFile
833}
Colin Crossa4f08812018-10-02 22:03:40 -0700834
Colin Cross403cc152020-07-06 14:15:24 -0700835func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
836 var jniSymbols android.RuleBuilderInstalls
837 for _, jniLib := range a.jniLibs {
838 if jniLib.unstrippedFile != nil {
839 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
840 From: jniLib.unstrippedFile,
841 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
842 })
843 }
844 }
845 return jniSymbols
846}
847
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700848// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
849// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700850func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
851 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700852 if android.SrcIsModule(certPropValue) == "" {
853 var mainCert Certificate
854 if certPropValue != "" {
855 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
856 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800857 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
858 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700859 }
860 } else {
861 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800862 mainCert = Certificate{
863 Pem: pem,
864 Key: key,
865 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700866 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700867 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700868 }
869
Colin Crossbc2c8a72022-09-14 12:45:42 -0700870 if len(certificates) > 0 {
871 mainCertificate = certificates[0]
872 } else {
873 // This can be reached with an empty certificate list if AllowMissingDependencies is set
874 // and the certificate property for this module is a module reference to a missing module.
875 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
876 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
877 }
878 // Set a certificate to avoid panics later when accessing it.
879 mainCertificate = Certificate{
880 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000881 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700882 }
883 }
884
Zyan Wub7550aa2023-05-18 15:46:31 +0800885 if !m.Platform() {
886 certPath := mainCertificate.Pem.String()
887 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
888 if strings.HasPrefix(certPath, systemCertPath) {
889 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
890 allowed := ctx.Config().EnforceSystemCertificateAllowList()
891
892 if enforceSystemCert && !inList(m.Name(), allowed) {
893 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
894 }
895 }
896 }
897
Colin Crossbc2c8a72022-09-14 12:45:42 -0700898 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800899}
900
Jooyung Han39ee1192020-03-23 20:21:11 +0900901func (a *AndroidApp) InstallApkName() string {
902 return a.installApkName
903}
904
Sam Delmerico15809f82023-05-15 17:21:47 -0400905func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000906 if a.appProperties.Privapp_allowlist == nil {
907 return nil
908 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400909
910 isOverrideApp := a.GetOverriddenBy() != ""
911 if !isOverrideApp {
912 // if this is not an override, we don't need to rewrite the existing privapp allowlist
913 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
914 }
915
Cole Faust258b96f2024-10-04 10:48:24 -0700916 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
917 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000918 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
919 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400920
Cole Faust258b96f2024-10-04 10:48:24 -0700921 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000922 fileName := "privapp_allowlist_" + packageName + ".xml"
Cole Faust4e9f5922024-11-13 16:09:23 -0800923 outPath := android.PathForModuleOut(ctx, fileName)
Andrei Onea580636b2022-08-17 16:53:46 +0000924 ctx.Build(pctx, android.BuildParams{
925 Rule: modifyAllowlist,
926 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
927 Output: outPath,
928 Args: map[string]string{
929 "packageName": packageName,
930 },
931 })
Cole Faust4e9f5922024-11-13 16:09:23 -0800932 return outPath
Andrei Onea580636b2022-08-17 16:53:46 +0000933}
934
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800935func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700936 var apkDeps android.Paths
937
Colin Crossff694a82023-12-13 15:54:49 -0800938 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
939 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700940 a.hideApexVariantFromMake = true
941 }
942
Jeongik Cha538c0d02019-07-11 15:54:27 +0900943 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
944 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
945
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000946 // Unlike installApkName, a.stem should respect base module name for override_android_app.
947 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000948 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000949
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800950 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000951 // Both android_app and override_android_app module are expected to possess
952 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
953 // from the base module. Therefore, use a.Name() which represents
954 // the module name for both android_app and override_android_app.
955 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000956 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800957
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700958 if ctx.ModuleName() == "framework-res" {
959 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700960 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900961 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700962 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
963 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800964 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700965 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700966 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700967 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700968 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700969
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100970 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000971 if a.usesLibrary.shouldDisableDexpreopt {
972 a.dexpreopter.disableDexpreopt()
973 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000974
Colin Cross61fb62e2022-06-23 10:46:28 -0700975 var noticeAssetPath android.WritablePath
976 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
977 // The rule to create the notice file can't be generated yet, as the final output path
978 // for the apk isn't known yet. Add the path where the notice file will be generated to the
979 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
980 // be generated later.
981 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
982 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
983 }
984
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000985 // For apps targeting latest target_sdk_version
986 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
987 a.SetEnforceDefaultTargetSdkVersion(true)
988 }
989
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800990 // Process all building blocks, from AAPT to certificates.
991 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100992 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700993 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100994
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100995 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700996 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000997 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
998 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700999 apkDeps = append(apkDeps, manifestCheckFile)
1000 }
1001
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001002 a.proguardBuildActions(ctx)
1003
Colin Cross014489c2020-06-02 20:09:13 -07001004 a.linter.mergedManifest = a.aapt.mergedManifestFile
1005 a.linter.manifest = a.aapt.manifestPath
1006 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -07001007 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -07001008
Yu Liu7eebf8b2025-01-17 00:23:57 +00001009 dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001010
Jiyong Park92d84042024-05-17 22:58:54 +00001011 // No need to check the SDK version of the JNI deps unless we embed them
1012 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
1013 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +00001014 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001015
1016 if ctx.Failed() {
1017 return
1018 }
1019
Colin Crossbc2c8a72022-09-14 12:45:42 -07001020 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001021
1022 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -08001023 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001024 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
1025 var v4SignatureFile android.WritablePath = nil
1026 if v4SigningRequested {
1027 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
1028 }
Liz Kammere2b27f42020-05-07 13:24:05 -07001029 var lineageFile android.Path
1030 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
1031 lineageFile = android.PathForModuleSrc(ctx, lineage)
1032 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04001033 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
1034
Rico Wind98e7fa82023-11-27 09:44:03 +01001035 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001036 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -07001037 if v4SigningRequested {
1038 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1039 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001040
Colin Cross61fb62e2022-06-23 10:46:28 -07001041 if a.aapt.noticeFile.Valid() {
1042 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -07001043 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -07001044 android.BuildNoticeHtmlOutputFromLicenseMetadata(
1045 ctx, noticeFile, "", "",
1046 []string{
1047 a.installDir.String() + "/",
1048 android.PathForModuleInstall(ctx).String() + "/",
1049 a.outputFile.String(),
1050 })
Bob Badoureef4c1c2022-05-16 12:20:04 -07001051 builder := android.NewRuleBuilder(pctx, ctx)
1052 builder.Command().Text("cp").
1053 Input(noticeFile).
1054 Output(noticeAssetPath)
1055 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -07001056 }
1057
Colin Crosse560c4a2019-03-19 16:03:11 -07001058 for _, split := range a.aapt.splits {
1059 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -08001060 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001061 if v4SigningRequested {
1062 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
1063 }
Rico Wind98e7fa82023-11-27 09:44:03 +01001064 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -07001065 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -07001066 if v4SigningRequested {
1067 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1068 }
Colin Crosse560c4a2019-03-19 16:03:11 -07001069 }
1070
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001071 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -07001072 bundleFile := android.PathForModuleOut(ctx, "base.zip")
1073 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1074 a.bundleFile = bundleFile
1075
Andrei Onea580636b2022-08-17 16:53:46 +00001076 allowlist := a.createPrivappAllowlist(ctx)
1077 if allowlist != nil {
1078 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1079 }
1080
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001081 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001082 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1083 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001084 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001085 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1086 allowlistInstallFilename := a.installApkName + ".xml"
1087 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001088 }
1089
Colin Cross09ad3a62023-11-15 12:29:33 -08001090 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001091 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001092 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1093 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001094 }
Jiyong Park25b92222024-05-17 22:58:54 +00001095 // If we don't embed jni libs, make sure that those are installed along with the
1096 // app, and also place symlinks to the installed paths under the lib/<arch>
1097 // directory of the app installation directory. ex:
1098 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1099 if !a.embeddedJniLibs {
1100 for _, jniLib := range jniLibs {
1101 archStr := jniLib.target.Arch.ArchType.String()
1102 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1103 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001104 // install the symlink itself
1105 symlinkName := installedLib.Base()
1106 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1107 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1108 }
1109 }
1110 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001111 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001112 }
Artur Satayev1111b842020-04-27 19:05:28 +01001113
Colin Crossa6182ab2024-08-21 10:47:44 -07001114 ctx.CheckbuildFile(a.outputFile)
1115
Artur Satayev1111b842020-04-27 19:05:28 +01001116 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001117
1118 providePrebuiltInfo(ctx,
1119 prebuiltInfoProps{
1120 baseModuleName: a.BaseModuleName(),
1121 isPrebuilt: false,
1122 },
1123 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001124
Yu Liu7eebf8b2025-01-17 00:23:57 +00001125 if javaInfo != nil {
1126 javaInfo.OutputFile = a.outputFile
1127 setExtraJavaInfo(ctx, a, javaInfo)
1128 android.SetProvider(ctx, JavaInfoProvider, javaInfo)
1129 }
1130
Yu Liu95cef3a2025-02-25 00:54:20 +00001131 android.SetProvider(ctx, android.ApexBundleDepsDataProvider, android.ApexBundleDepsData{
1132 FlatListPath: a.FlatListPath(),
1133 Updatable: a.Updatable(),
1134 })
1135
Cole Faust866ab392025-01-23 12:56:20 -08001136 moduleInfoJSON := ctx.ModuleInfoJSON()
1137 moduleInfoJSON.Class = []string{"APPS"}
1138 if !a.embeddedJniLibs {
1139 for _, jniLib := range a.jniLibs {
1140 moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name)
1141 }
1142 }
1143
mrziwang9f7b9f42024-07-10 12:18:06 -07001144 a.setOutputFiles(ctx)
Wei Li986fe742025-01-30 15:14:42 -08001145
1146 buildComplianceMetadata(ctx)
mrziwang9f7b9f42024-07-10 12:18:06 -07001147}
1148
1149func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1150 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1151 if a.aaptSrcJar != nil {
1152 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1153 }
1154 if a.rJar != nil {
1155 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1156 }
1157 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1158 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1159 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1160 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001161}
1162
Colin Crossc2d24052020-05-13 11:05:02 -07001163type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001164 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001165 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001166 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1167}
1168
1169func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1170 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001171 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001172
Colin Crossc2d24052020-05-13 11:05:02 -07001173 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001174 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1175 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001176 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001177 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
Yu Liuf6f85492025-01-13 21:02:36 +00001178 checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool {
Spandan Das10c41362024-12-03 01:33:09 +00001179 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
Yu Liuf6f85492025-01-13 21:02:36 +00001180 childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
1181 parentIsLinkable := false
Yu Liue472c1d2025-02-26 20:13:04 +00001182 if android.EqualModules(ctx.Module(), parent) {
Yu Liuf6f85492025-01-13 21:02:36 +00001183 parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
1184 parentIsLinkable = parentLinkable != nil
1185 } else {
1186 _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider)
1187 }
1188 useStubsOfDep := childLinkable.IsStubs
1189 if apkInApex && parentIsLinkable {
Spandan Das10c41362024-12-03 01:33:09 +00001190 // APK-in-APEX
1191 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
Yu Liuf6f85492025-01-13 21:02:36 +00001192 useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child))
Spandan Das10c41362024-12-03 01:33:09 +00001193 }
Yu Liuf6f85492025-01-13 21:02:36 +00001194 return !childLinkable.IsNdk && !useStubsOfDep
Spandan Das10c41362024-12-03 01:33:09 +00001195 })
Makoto Onuki2ca84272024-02-10 00:15:21 +00001196
1197 var certificates []Certificate
1198
Colin Crossb614cd42024-10-11 12:52:21 -07001199 var directImplementationDeps android.Paths
1200 var transitiveImplementationDeps []depset.DepSet[android.Path]
Yu Liu728da7c2025-01-11 00:54:32 +00001201 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001202 otherName := ctx.OtherModuleName(module)
1203 tag := ctx.OtherModuleDependencyTag(module)
1204
1205 if tag == certificateTag {
Yu Liu728da7c2025-01-11 00:54:32 +00001206 if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001207 certificates = append(certificates, dep.Certificate)
1208 } else {
1209 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1210 }
1211 }
Colin Crossb614cd42024-10-11 12:52:21 -07001212
1213 if IsJniDepTag(tag) {
1214 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1215 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1216 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1217 }
1218 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001219 })
Colin Crossb614cd42024-10-11 12:52:21 -07001220 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1221 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1222 })
1223
Makoto Onuki2ca84272024-02-10 00:15:21 +00001224 return jniLib, prebuiltJniPackages, certificates
1225}
1226
1227func collectJniDeps(ctx android.ModuleContext,
1228 shouldCollectRecursiveNativeDeps bool,
1229 checkNativeSdkVersion bool,
Yu Liuf6f85492025-01-13 21:02:36 +00001230 filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001231 var jniLibs []jniLib
1232 var prebuiltJniPackages android.Paths
1233 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001234
Yu Liuf6f85492025-01-13 21:02:36 +00001235 ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
Yu Liuef9e63e2025-03-04 19:01:28 +00001236 if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
Yu Liub732c842025-01-16 00:15:54 +00001237 return false
1238 }
Colin Crossa4f08812018-10-02 22:03:40 -07001239 otherName := ctx.OtherModuleName(module)
1240 tag := ctx.OtherModuleDependencyTag(module)
1241
Colin Crossf0913fb2020-07-29 12:59:39 -07001242 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Yu Liuf6f85492025-01-13 21:02:36 +00001243 if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
Spandan Das10c41362024-12-03 01:33:09 +00001244 if filter != nil && !filter(parent, module) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001245 return false
1246 }
1247
Yu Liuf6f85492025-01-13 21:02:36 +00001248 lib := dep.OutputFile
Colin Crossa4f08812018-10-02 22:03:40 -07001249 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001250 path := lib.Path()
1251 if seenModulePaths[path.String()] {
1252 return false
1253 }
1254 seenModulePaths[path.String()] = true
1255
Yu Liuef9e63e2025-03-04 19:01:28 +00001256 commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
Yu Liuf6f85492025-01-13 21:02:36 +00001257 if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
Cole Faust64cb7c92021-09-14 17:32:49 -07001258 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1259 otherName)
1260 }
1261
Colin Crossa4f08812018-10-02 22:03:40 -07001262 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001263 name: ctx.OtherModuleName(module),
1264 path: path,
Yu Liuf6f85492025-01-13 21:02:36 +00001265 target: commonInfo.Target,
1266 coverageFile: dep.CoverageOutputFile,
1267 unstrippedFile: dep.UnstrippedOutputFile,
1268 partition: dep.Partition,
1269 installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001270 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001271 } else if ctx.Config().AllowMissingDependencies() {
1272 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001273 } else {
1274 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1275 }
1276 } else {
1277 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001278 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001279
1280 return shouldCollectRecursiveNativeDeps
1281 }
1282
Colin Cross313aa542023-12-13 13:47:44 -08001283 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001284 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1285 }
1286
Peter Collingbournead84f972019-12-17 16:46:18 -08001287 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001288 })
1289
Makoto Onuki2ca84272024-02-10 00:15:21 +00001290 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001291}
1292
Colin Cross8bf14fc2024-09-25 16:41:31 -07001293func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Yu Liue263a692025-03-04 19:30:25 +00001294 ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001295 // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
1296 // heuristics to every transitive dependency, when it should probably be using the heuristics of the
1297 // immediate parent.
Yu Liuf1806032025-02-07 00:23:34 +00001298 isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
Yu Liue263a692025-03-04 19:30:25 +00001299 if am, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok && am.IsApexModule {
1300 if !do(ctx, parent, child, isExternal) {
Jooyung Han749dc692020-04-15 11:03:39 +09001301 return false
1302 }
Artur Satayev1111b842020-04-27 19:05:28 +01001303 }
1304 return !isExternal
1305 })
1306}
1307
1308func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1309 if ctx.Host() {
1310 return
1311 }
1312
1313 depsInfo := android.DepNameToDepInfoMap{}
Yu Liue263a692025-03-04 19:30:25 +00001314 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001315 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001316
1317 // Skip dependencies that are only available to APEXes; they are developed with updatability
1318 // in mind and don't need manual approval.
Yu Liuef9e63e2025-03-04 19:01:28 +00001319 if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform {
Artur Satayev533b98c2021-03-11 18:03:42 +00001320 return true
1321 }
1322
Artur Satayev1111b842020-04-27 19:05:28 +01001323 if info, exist := depsInfo[depName]; exist {
1324 info.From = append(info.From, from.Name())
1325 info.IsExternal = info.IsExternal && externalDep
1326 depsInfo[depName] = info
1327 } else {
1328 toMinSdkVersion := "(no version)"
Yu Liuef9e63e2025-03-04 19:01:28 +00001329 if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoProvider); ok &&
Yu Liudf0b8392025-02-12 18:27:03 +00001330 !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
1331 toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001332 }
1333 depsInfo[depName] = android.ApexModuleDepInfo{
1334 To: depName,
1335 From: []string{from.Name()},
1336 IsExternal: externalDep,
1337 MinSdkVersion: toMinSdkVersion,
1338 }
1339 }
Jooyung Han749dc692020-04-15 11:03:39 +09001340 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001341 })
1342
Jiyong Park92315372021-04-02 08:45:46 +09001343 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001344}
1345
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001346func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1347 return a.appProperties.EnforceDefaultTargetSdkVersion
1348}
1349
1350func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1351 a.appProperties.EnforceDefaultTargetSdkVersion = val
1352}
1353
Artur Satayev849f8442020-04-28 14:57:42 +01001354func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001355 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001356}
1357
Colin Cross0ea8ba82019-06-06 14:33:29 -07001358func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001359 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1360 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001361 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001362 }
Cole Fausteb9c1482024-11-18 16:49:19 -08001363 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001364}
1365
Yu Liuf1806032025-02-07 00:23:34 +00001366func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker {
1367 return AppDepInSameApexChecker{}
1368}
1369
1370type AppDepInSameApexChecker struct {
1371 android.BaseDepInSameApexChecker
1372}
1373
1374func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001375 if IsJniDepTag(tag) {
Jiyong Park0f80c182020-01-31 02:49:53 +09001376 return true
1377 }
Yu Liuf1806032025-02-07 00:23:34 +00001378 return depIsInSameApex(tag)
Jiyong Park0f80c182020-01-31 02:49:53 +09001379}
1380
Jiyong Parkf7487312019-10-17 12:54:30 +09001381func (a *AndroidApp) Privileged() bool {
1382 return Bool(a.appProperties.Privileged)
1383}
1384
Colin Crosse1a85552024-06-14 12:17:37 -07001385func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001386 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001387}
1388
Ivan Lozanod7586b62021-04-01 09:49:36 -04001389func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001390 a.appProperties.PreventInstall = true
1391}
1392
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001393func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1394 a.appProperties.IsCoverageVariant = coverage
1395}
1396
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001397func (a *AndroidApp) EnableCoverageIfNeeded() {}
1398
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001399var _ cc.Coverage = (*AndroidApp)(nil)
1400
Cole Faustb36d31d2024-08-27 16:04:28 -07001401func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1402 a.Library.IDEInfo(ctx, dpInfo)
1403 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001404}
1405
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001406func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1407 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1408}
1409
1410func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1411 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1412}
1413
Colin Cross1b16b0e2019-02-12 14:41:32 -08001414// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001415func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001416 module := &AndroidApp{}
1417
Liz Kammera7a64f32020-07-09 15:16:41 -07001418 module.Module.dexProperties.Optimize.EnabledByDefault = true
1419 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001420 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001421
Colin Crossae5caf52018-05-22 11:11:52 -07001422 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001423 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001424 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001425
Colin Crossce6734e2020-06-15 16:09:53 -07001426 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001427 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001428 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001429 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001430 &module.overridableAppProperties,
1431 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001432
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001433 module.usesLibrary.enforce = true
1434
Colin Crossa4f08812018-10-02 22:03:40 -07001435 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1436 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001437 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001438 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001439
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001440 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1441 a := ctx.Module().(*AndroidApp)
1442
1443 characteristics := ctx.Config().ProductAAPTCharacteristics()
1444 if characteristics == "default" || characteristics == "" {
1445 module.appProperties.Generate_product_characteristics_rro = nil
1446 // no need to create RRO
1447 return
1448 }
1449
1450 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1451 return
1452 }
1453
1454 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1455 rroManifestName := rroPackageName + "_manifest"
1456
1457 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1458 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1459
1460 rroManifestProperties := struct {
1461 Name *string
1462 Tools []string
1463 Out []string
1464 Srcs []string
1465 Cmd *string
1466 }{
1467 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001468 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001469 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001470 Srcs: []string{":" + a.Name() + "{.apk}"},
1471 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001472 }
Cole Fauste19d3352024-10-17 10:30:57 -07001473 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001474
1475 rroProperties := struct {
1476 Name *string
1477 Filter_product *string
1478 Aaptflags []string
1479 Manifest *string
Cole Faust5b989772024-11-06 11:03:16 -08001480 Resource_dirs proptools.Configurable[[]string]
Jihoon Kangf62f4222024-10-21 23:06:41 +00001481 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001482 }{
1483 Name: proptools.StringPtr(rroPackageName),
1484 Filter_product: proptools.StringPtr(characteristics),
1485 Aaptflags: []string{"--auto-add-overlay"},
1486 Manifest: proptools.StringPtr(":" + rroManifestName),
1487 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001488 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001489 }
优秀d75e9982024-05-09 07:15:55 +00001490 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1491 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1492 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1493 }
1494 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001495 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
Spandan Dasde588a32024-12-03 22:52:24 +00001496
1497 })
1498
1499 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1500 createInternalRuntimeOverlays(ctx, module.ModuleBase)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001501 })
1502
Colin Cross36242852017-06-23 15:06:31 -07001503 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001504}
Colin Crossae5caf52018-05-22 11:11:52 -07001505
Spandan Das71be42d2024-11-20 18:34:16 +00001506func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1507 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1508}
1509
Spandan Dasde588a32024-12-03 22:52:24 +00001510type createModuleContext interface {
1511 android.EarlyModuleContext
1512 CreateModule(android.ModuleFactory, ...interface{}) android.Module
1513}
1514
1515func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
1516 if !ctx.Config().HasDeviceProduct() {
1517 return
1518 }
1519 // vendor
1520 vendorOverlayProps := struct {
1521 Name *string
1522 Base *string
1523 Vendor *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(), "vendor")),
1532 Base: proptools.StringPtr(a.Name()),
1533 Vendor: proptools.BoolPtr(true),
1534 Product_specific: proptools.BoolPtr(false),
1535 System_ext_specific: proptools.BoolPtr(false),
1536 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1537 Sdk_version: proptools.StringPtr("current"),
1538 Compile_multilib: proptools.StringPtr("first"),
1539 Enabled: a.EnabledProperty().Clone(),
1540 }
1541 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
1542
1543 // product
1544 productOverlayProps := struct {
1545 Name *string
1546 Base *string
1547 Vendor *bool
1548 Proprietary *bool
1549 Soc_specific *bool
1550 Product_specific *bool
1551 System_ext_specific *bool
1552 Manifest *string
1553 Sdk_version *string
1554 Compile_multilib *string
1555 Enabled proptools.Configurable[bool]
1556 }{
1557 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
1558 Base: proptools.StringPtr(a.Name()),
1559 Vendor: proptools.BoolPtr(false),
1560 Proprietary: proptools.BoolPtr(false),
1561 Soc_specific: proptools.BoolPtr(false),
1562 Product_specific: proptools.BoolPtr(true),
1563 System_ext_specific: proptools.BoolPtr(false),
1564 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1565 Sdk_version: proptools.StringPtr("current"),
1566 Compile_multilib: proptools.StringPtr("first"),
1567 Enabled: a.EnabledProperty().Clone(),
1568 }
1569 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
1570}
1571
Alix96ea88452023-08-31 15:48:23 +00001572// A dictionary of values to be overridden in the manifest.
1573type Manifest_values struct {
1574 // Overrides the value of package_name in the manifest
1575 ApplicationId *string
1576}
1577
Colin Crossae5caf52018-05-22 11:11:52 -07001578type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001579 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001580 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001581
Seth Moorec6f4b532023-02-02 13:22:26 -08001582 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001583 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001584
1585 // If specified, the mainline module package name in the test config is overwritten by it.
1586 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001587
1588 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001589}
1590
1591type AndroidTest struct {
1592 AndroidApp
1593
1594 appTestProperties appTestProperties
1595
1596 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001597
Dan Shi95d19422020-08-15 12:24:26 -07001598 testConfig android.Path
1599 extraTestConfigs android.Paths
1600 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001601}
1602
Jaewoong Jung0949f312019-09-11 10:25:18 -07001603func (a *AndroidTest) InstallInTestcases() bool {
1604 return true
1605}
1606
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001607type androidTestApp interface {
1608 includedInTestSuite(searchPrefix string) bool
1609}
1610
1611func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1612 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1613}
1614
1615func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1616 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1617}
1618
Colin Crossae5caf52018-05-22 11:11:52 -07001619func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001620 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001621 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001622 if a.appTestProperties.Instrumentation_target_package != nil {
1623 a.additionalAaptFlags = append(a.additionalAaptFlags,
1624 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1625 } else if a.appTestProperties.Instrumentation_for != nil {
1626 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001627 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1628 if overridden {
1629 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1630 }
1631 }
Alix96ea88452023-08-31 15:48:23 +00001632 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1633 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001634 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1635 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001636 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1637 }
1638 a.aapt.manifestValues.applicationId = *applicationId
1639 }
Colin Crossae5caf52018-05-22 11:11:52 -07001640 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001641
Jiyong Parkf528b702024-12-30 16:01:58 +09001642 for _, c := range a.testProperties.Test_options.Tradefed_options {
1643 configs = append(configs, c)
1644 }
easoncylee5bcff5d2020-04-30 14:57:06 +08001645 for _, module := range a.testProperties.Test_mainline_modules {
1646 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1647 }
1648
Jaewoong Jung39982342020-01-14 10:27:18 -08001649 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001650 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1651 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001652 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001653 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001654 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001655 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1656 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001657 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Colin Crossb3614422025-02-18 15:18:18 -08001658 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...)
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001659
Spandan Dasa65d1e02025-01-28 19:34:04 +00001660 // Install test deps
1661 if !ctx.Config().KatiEnabled() {
1662 pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name())
1663 if a.testConfig != nil {
1664 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig)
1665 }
Cole Faustec71dfb2025-02-18 13:31:12 -08001666 dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
1667 if dynamicConfig.Valid() {
1668 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path())
1669 }
Spandan Dasa65d1e02025-01-28 19:34:04 +00001670 testDeps := append(a.data, a.extraTestConfigs...)
1671 for _, data := range android.SortedUniquePaths(testDeps) {
1672 dataPath := android.DataPath{SrcPath: data}
1673 ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
1674 }
1675 }
1676
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001677 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001678 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001679 OutputFile: a.OutputFile(),
1680 TestConfig: a.testConfig,
1681 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001682 TestSuites: a.testProperties.Test_suites,
1683 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001684 LocalCertificate: a.certificate.AndroidMkString(),
1685 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001686 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1687 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001688 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001689 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1690 TestOnly: true,
1691 TopLevelTarget: true,
1692 })
1693
Cole Faust866ab392025-01-23 12:56:20 -08001694 moduleInfoJSON := ctx.ModuleInfoJSON()
1695 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
1696 if a.testConfig != nil {
1697 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String())
1698 }
1699 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...)
1700 if len(a.testProperties.Test_suites) > 0 {
1701 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...)
1702 } else {
1703 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
1704 }
1705
1706 if _, ok := testConfig.(android.WritablePath); ok {
1707 moduleInfoJSON.AutoTestConfig = []string{"true"}
1708 }
1709 moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
Cole Faust5e1454a2025-03-11 15:55:59 -07001710
1711 android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
1712 TestSuites: a.testProperties.Test_suites,
1713 })
Colin Cross303e21f2018-08-07 16:49:25 -07001714}
1715
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001716func testcaseRel(paths android.Paths) []string {
1717 relPaths := []string{}
1718 for _, p := range paths {
1719 relPaths = append(relPaths, p.Rel())
1720 }
1721 return relPaths
1722}
1723
Jaewoong Jung39982342020-01-14 10:27:18 -08001724func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1725 if testConfig == nil {
1726 return nil
1727 }
1728
1729 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001730 rule := android.NewRuleBuilder(pctx, ctx)
1731 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001732 fixNeeded := false
1733
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001734 // 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 -08001735 if ctx.ModuleName() != a.installApkName {
1736 fixNeeded = true
1737 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1738 }
1739
Cole Faust258b96f2024-10-04 10:48:24 -07001740 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1741 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001742 fixNeeded = true
1743 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001744 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001745 }
1746
Seth Moorec6f4b532023-02-02 13:22:26 -08001747 if a.appTestProperties.Mainline_package_name != nil {
1748 fixNeeded = true
1749 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1750 }
1751
Jaewoong Jung39982342020-01-14 10:27:18 -08001752 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001753 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001754 return fixedConfig
1755 }
1756 return testConfig
1757}
1758
Yihan Dong8be09c22024-08-29 15:32:13 +08001759func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1760 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1761 // Instrument the android_test_helper target to log potential API calls at the run time.
1762 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1763 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1764 a.setApiMapper(true)
1765 }
1766 a.AndroidApp.DepsMutator(ctx)
1767}
1768
Colin Cross303e21f2018-08-07 16:49:25 -07001769func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001770 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1771 // Instrument the android_test_helper target to log potential API calls at the run time.
1772 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1773 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1774 a.setApiMapper(true)
1775 }
Colin Cross303e21f2018-08-07 16:49:25 -07001776 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001777}
1778
1779func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1780 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001781 if a.appTestProperties.Instrumentation_for != nil {
1782 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1783 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1784 // use instrumentationForTag instead of libTag.
1785 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1786 }
Colin Crossae5caf52018-05-22 11:11:52 -07001787}
1788
Colin Cross1b16b0e2019-02-12 14:41:32 -08001789// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1790// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001791func AndroidTestFactory() android.Module {
1792 module := &AndroidTest{}
1793
Jared Duke63a3da92022-06-02 19:11:14 +00001794 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001795
1796 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001797 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001798 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001799 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1800 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001801 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001802 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001803
Colin Crossce6734e2020-06-15 16:09:53 -07001804 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001805 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001806 &module.aaptProperties,
1807 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001808 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001809 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001810 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001811
Colin Crossa4f08812018-10-02 22:03:40 -07001812 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1813 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001814 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001815
Colin Crossae5caf52018-05-22 11:11:52 -07001816 return module
1817}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001818
Colin Cross252fc6f2018-10-04 15:22:03 -07001819type appTestHelperAppProperties struct {
1820 // list of compatibility suites (for example "cts", "vts") that the module should be
1821 // installed into.
1822 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001823
1824 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1825 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1826 // explicitly.
1827 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001828
1829 // Install the test into a folder named for the module in all test suites.
1830 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001831
1832 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001833}
1834
1835type AndroidTestHelperApp struct {
1836 AndroidApp
1837
1838 appTestHelperAppProperties appTestHelperAppProperties
1839}
1840
Jaewoong Jung326a9412019-11-21 10:41:00 -08001841func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1842 return true
1843}
1844
Colin Cross1b16b0e2019-02-12 14:41:32 -08001845// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1846// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1847// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001848func AndroidTestHelperAppFactory() android.Module {
1849 module := &AndroidTestHelperApp{}
1850
Jared Duke63a3da92022-06-02 19:11:14 +00001851 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001852 module.Module.dexProperties.Optimize.EnabledByDefault = true
Christoffer Adamsenc8fd1f12025-01-06 19:04:03 +01001853 module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
1854 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross252fc6f2018-10-04 15:22:03 -07001855
1856 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001857 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1858 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001859 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001860 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001861
Colin Crossce6734e2020-06-15 16:09:53 -07001862 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001863 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001864 &module.aaptProperties,
1865 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001866 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001867 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001868
1869 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1870 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001871 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001872 return module
1873}
1874
Colin Crossbd01e2a2018-10-04 15:21:03 -07001875type AndroidAppCertificate struct {
1876 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001877
Colin Crossbd01e2a2018-10-04 15:21:03 -07001878 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001879 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001880}
1881
1882type AndroidAppCertificateProperties struct {
1883 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1884 Certificate *string
1885}
1886
Yu Liu728da7c2025-01-11 00:54:32 +00001887type AndroidAppCertificateInfo struct {
1888 Certificate Certificate
1889}
1890
1891var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]()
1892
Colin Cross1b16b0e2019-02-12 14:41:32 -08001893// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1894// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001895func AndroidAppCertificateFactory() android.Module {
1896 module := &AndroidAppCertificate{}
1897 module.AddProperties(&module.properties)
1898 android.InitAndroidModule(module)
1899 return module
1900}
1901
Colin Crossbd01e2a2018-10-04 15:21:03 -07001902func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1903 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001904 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001905 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1906 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001907 }
Yu Liu728da7c2025-01-11 00:54:32 +00001908
1909 android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{
1910 Certificate: c.Certificate,
1911 })
Colin Crossbd01e2a2018-10-04 15:21:03 -07001912}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001913
1914type OverrideAndroidApp struct {
1915 android.ModuleBase
1916 android.OverrideModuleBase
1917}
1918
Sasha Smundak613cbb12020-06-05 10:27:23 -07001919func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001920 // All the overrides happen in the base module.
1921 // TODO(jungjw): Check the base module type.
1922}
1923
1924// override_android_app is used to create an android_app module based on another android_app by overriding
1925// some of its properties.
1926func OverrideAndroidAppModuleFactory() android.Module {
1927 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001928 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001929 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001930 &overridableAppProperties{},
1931 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001932
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001933 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001934 android.InitOverrideModule(m)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001935 android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) {
Spandan Dasde588a32024-12-03 22:52:24 +00001936 createInternalRuntimeOverlays(ctx, m.ModuleBase)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001937 }, 1) // Run after soong config load hoook
Spandan Dasde588a32024-12-03 22:52:24 +00001938
Jaewoong Jung525443a2019-02-28 15:35:54 -08001939 return m
1940}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001941
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001942type OverrideAndroidTest struct {
1943 android.ModuleBase
1944 android.OverrideModuleBase
1945}
1946
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001947func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001948 // All the overrides happen in the base module.
1949 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001950 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1951 TestOnly: true,
1952 TopLevelTarget: true,
1953 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001954}
1955
1956// override_android_test is used to create an android_app module based on another android_test by overriding
1957// some of its properties.
1958func OverrideAndroidTestModuleFactory() android.Module {
1959 m := &OverrideAndroidTest{}
1960 m.AddProperties(&overridableAppProperties{})
1961 m.AddProperties(&appTestProperties{})
1962
1963 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1964 android.InitOverrideModule(m)
1965 return m
1966}
1967
Colin Cross50ddcc42019-05-16 12:28:22 -07001968type UsesLibraryProperties struct {
1969 // 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 -07001970 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001971
1972 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1973 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001974 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001975
1976 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1977 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1978 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001979
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001980 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1981 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1982 // normally is the same as the module name, but there are exceptions.
1983 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001984
1985 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1986 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1987 // added to the APK's manifest's <uses-library> elements.
1988 //
1989 // Care must be taken when using this as it could result in runtime errors if the APK actually
1990 // uses classes provided by the library and which are not provided in any other way.
1991 //
1992 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1993 // android.test.base shared library (and related libraries) but which depend on some common
1994 // libraries that depend on the android.test.base library. Without this those tests will end up
1995 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1996 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1997 // test altogether by providing access to classes that the tests were not expecting. Those tests
1998 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1999 // with the classes provided by the android.test.base library.
2000 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00002001
2002 // The module names of optional uses-library libraries that are missing from the source tree.
2003 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07002004}
2005
2006// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
2007// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
2008// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
2009// with knowledge of their shared libraries.
2010type usesLibrary struct {
2011 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002012
2013 // Whether to enforce verify_uses_library check.
2014 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00002015
2016 // Whether dexpreopt should be disabled
2017 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07002018}
2019
Colin Cross4a80a152022-12-21 21:51:52 -08002020func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09002021 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07002022 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00002023 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
2024 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08002025 // Only add these extra dependencies if the module is an app that depends on framework
2026 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01002027 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08002028 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002029 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
2030 // class loader context for dex2oat. Add them as a dependency with a special tag.
2031 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
2032 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
2033 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07002034 }
Cole Faust64f2d842024-10-17 13:28:34 -07002035 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00002036 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002037 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07002038 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002039 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07002040 }
2041}
2042
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002043// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07002044func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07002045 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002046 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01002047 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002048 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
2049 }
2050 return exists
2051 })
Colin Cross50ddcc42019-05-16 12:28:22 -07002052 return optionalUsesLibs
2053}
2054
Ulya Trafimovich24446712021-07-15 14:59:34 +01002055// Returns a map of module names of shared library dependencies to the paths to their dex jars on
2056// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002057func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
2058 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002059
2060 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
2061 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
2062 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
2063 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002064 }
2065
Yu Liu27b74aa2025-01-11 00:04:41 +00002066 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Ulya Trafimovich24446712021-07-15 14:59:34 +01002067 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
2068 if !isUsesLibTag {
2069 return
2070 }
2071
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002072 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01002073
Yu Liu27b74aa2025-01-11 00:04:41 +00002074 javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
2075 if !ok {
2076 return
2077 }
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002078 // Skip stub libraries. A dependency on the implementation library has been added earlier,
2079 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
2080 // from implementation libraries by their name, which is different as it has a suffix.
Yu Liu27b74aa2025-01-11 00:04:41 +00002081 if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
2082 if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002083 return
2084 }
2085 }
2086
Yu Liu27b74aa2025-01-11 00:04:41 +00002087 if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002088 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
2089 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
2090 // This will be restricted to optional_uses_libs
Yu Liu0a37d422025-02-13 02:05:00 +00002091 if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002092 u.shouldDisableDexpreopt = true
2093 return
2094 }
2095 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002096 libName := dep
Yu Liu27b74aa2025-01-11 00:04:41 +00002097 if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil {
2098 libName = *ulib.ProvidesUsesLib
Ulya Trafimovich24446712021-07-15 14:59:34 +01002099 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002100 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Yu Liu0a37d422025-02-13 02:05:00 +00002101 javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath,
Yu Liu27b74aa2025-01-11 00:04:41 +00002102 lib.ClassLoaderContexts)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002103 } else if ctx.Config().AllowMissingDependencies() {
2104 ctx.AddMissingDependencies([]string{dep})
2105 } else {
2106 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
2107 }
2108 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002109 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002110}
2111
2112// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
2113// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
2114// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07002115func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
2116 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
2117 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002118 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002119}
2120
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002121// 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 -07002122func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
2123 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002124 u.usesLibraryProperties.Enforce_uses_libs = &enforce
2125}
2126
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002127// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
2128// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
2129// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
2130// extension: APKs are supposed to end with '.apk').
2131func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00002132 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002133
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002134 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07002135
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002136 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
2137 // check is not necessary, and although it is good to have, it is difficult to maintain on
2138 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
2139 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01002140 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00002141 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002142 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002143 }
2144
Colin Crossf1a035e2020-11-16 17:32:30 -08002145 rule := android.NewRuleBuilder(pctx, ctx)
2146 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07002147 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002148 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002149 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00002150 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002151
2152 if outputFile != nil {
2153 cmd.FlagWithOutput("-o ", outputFile)
2154 }
Colin Cross50ddcc42019-05-16 12:28:22 -07002155
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002156 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
2157 cmd.Flag("--enforce-uses-libraries-relax")
2158 }
2159
Jiakai Zhangf98da192024-04-15 11:15:41 +00002160 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
2161 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002162 cmd.FlagWithArg("--uses-library ", lib)
2163 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00002164 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002165 cmd.FlagWithArg("--optional-uses-library ", lib)
2166 }
2167
Jiakai Zhangf98da192024-04-15 11:15:41 +00002168 // Also add missing optional uses libs, as the manifest check expects them.
2169 // Note that what we add here are the module names of those missing libs, not library names, while
2170 // the manifest check actually expects library names. However, the case where a library is missing
2171 // and the module name != the library name is too rare for us to handle.
2172 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
2173 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
2174 }
2175
Colin Crossf1a035e2020-11-16 17:32:30 -08002176 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002177 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002178}
Colin Cross50ddcc42019-05-16 12:28:22 -07002179
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002180// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
2181// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002182func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
2183 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002184 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00002185 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07002186}
2187
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002188// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
2189// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002190func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
2191 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
2192 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07002193}
Yu Liu0a37d422025-02-13 02:05:00 +00002194
2195// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
2196// the same way.
2197type androidApp interface {
2198 android.Module
2199 Privileged() bool
2200 InstallApkName() string
2201 OutputFile() android.Path
2202 JacocoReportClassesFile() android.Path
2203 Certificate() Certificate
2204 BaseModuleName() string
2205 PrivAppAllowlist() android.OptionalPath
2206}
2207
2208var _ androidApp = (*AndroidApp)(nil)
2209var _ androidApp = (*AndroidAppImport)(nil)
2210var _ androidApp = (*AndroidTestHelperApp)(nil)
2211
2212func setCommonAppInfo(appInfo *AppInfo, m androidApp) {
2213 appInfo.Privileged = m.Privileged()
2214 appInfo.OutputFile = m.OutputFile()
2215 appInfo.InstallApkName = m.InstallApkName()
2216 appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile()
2217 appInfo.Certificate = m.Certificate()
2218 appInfo.PrivAppAllowlist = m.PrivAppAllowlist()
2219}
Spandan Das38afe712025-03-05 23:27:55 +00002220
2221type AppInfos []AppInfo
2222
2223var AppInfosProvider = blueprint.NewProvider[AppInfos]()