blob: 4dea7dc1b26db321a878f9d8af8fb8d3d0257bd3 [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
Colin Cross99939e92024-10-01 16:02:46 -070073}
74
75var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
76
Colin Cross30e076a2015-04-13 13:58:27 -070077// AndroidManifest.xml merging
78// package splits
79
Colin Crossfabb6082018-02-20 17:22:23 -080080type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070081 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070082 Additional_certificates []string
83
84 // If set, create package-export.apk, which other packages can
85 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080086 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070087
Colin Cross16056062017-12-13 22:46:28 -080088 // Specifies that this app should be installed to the priv-app directory,
89 // where the system will grant it additional privileges not available to
90 // normal apps.
91 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070092
93 // list of resource labels to generate individual resource packages
94 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040095
Colin Crossa4f08812018-10-02 22:03:40 -070096 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +000097 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -070098
Colin Cross7204cf02020-05-06 17:51:39 -070099 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -0800100 // sdk_version.
101 Jni_uses_platform_apis *bool
102
Colin Cross7204cf02020-05-06 17:51:39 -0700103 // if true, use JNI libraries that link against SDK APIs even if this module does not set
104 // sdk_version.
105 Jni_uses_sdk_apis *bool
106
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700107 // STL library to use for JNI libraries.
108 Stl *string `android:"arch_variant"`
109
Colin Crosse4246ab2019-02-05 21:55:21 -0800110 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900111 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
112 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
113 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
114 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800115 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800116
117 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
118 // they are used from inside the APK at runtime.
119 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700120
Jiyong Parkd044bb42024-05-15 02:09:54 +0900121 // Forces native libraries to always be packaged into the APK,
122 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
123 // True for android_test* modules.
124 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700125
126 // If set, find and merge all NOTICE files that this module and its dependencies have and store
127 // it in the APK as an asset.
128 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700129
130 // cc.Coverage related properties
131 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700132 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100133
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000134 // It can be set to test the behaviour of default target sdk version.
135 // Only required when updatable: false. It is an error if updatable: true and this is false.
136 Enforce_default_target_sdk_version *bool
137
138 // If set, the targetSdkVersion for the target is set to the latest default API level.
139 // This would be by default false, unless updatable: true or
140 // enforce_default_target_sdk_version: true in which case this defaults to true.
141 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
142
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100143 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100144 // additional rules to make sure an app can safely be updated. Default is false.
145 // Prefer using other specific properties if build behaviour must be changed; avoid using this
146 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100147 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000148
149 // Specifies the file that contains the allowlist for this app.
150 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900151
152 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
153 // and install the RRO package to /product partition, instead of passing --product argument
154 // to aapt2. Default is false.
155 // Setting this will make this APK identical to all targets, regardless of
156 // PRODUCT_CHARACTERISTICS.
157 Generate_product_characteristics_rro *bool
158
159 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
160 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700161}
162
Jaewoong Jung525443a2019-02-28 15:35:54 -0800163// android_app properties that can be overridden by override_android_app
164type overridableAppProperties struct {
165 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
166 // or an android_app_certificate module name in the form ":module".
Cole Fausteb9c1482024-11-18 16:49:19 -0800167 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700168
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800169 // Name of the signing certificate lineage file or filegroup module.
170 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700171
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400172 // For overriding the --rotation-min-sdk-version property of apksig
173 RotationMinSdkVersion *string
174
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700175 // 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 -0700176 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800177
178 // the logging parent of this app.
179 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000180
181 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
182 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000183
184 // Names of modules to be overridden. Listed modules can only be other binaries
185 // (in Make or Soong).
186 // This does not completely prevent installation of the overridden binaries, but if both
187 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
188 // from PRODUCT_PACKAGES.
189 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800190}
191
Colin Cross30e076a2015-04-13 13:58:27 -0700192type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700193 Library
194 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800195 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700196
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900197 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700198
Colin Crossfabb6082018-02-20 17:22:23 -0800199 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700200
Jaewoong Jung525443a2019-02-28 15:35:54 -0800201 overridableAppProperties overridableAppProperties
202
Colin Cross403cc152020-07-06 14:15:24 -0700203 jniLibs []jniLib
204 installPathForJNISymbols android.Path
205 embeddedJniLibs bool
206 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700207
208 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800209
210 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
211 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800212
Colin Cross70dda7e2019-10-01 22:05:35 -0700213 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700214
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700215 onDeviceDir string
216
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800217 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700218
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900219 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100220
221 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000222
223 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000224
225 privAppAllowlist android.OptionalPath
Colin Crosse1731a52017-12-14 11:22:55 -0800226}
227
Martin Stjernholm6d415272020-01-31 17:10:36 +0000228func (a *AndroidApp) IsInstallable() bool {
229 return Bool(a.properties.Installable)
230}
231
Colin Crossa14fb6a2024-10-23 16:57:06 -0700232func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000233 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700234}
235
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900236func (a *AndroidApp) OutputFile() android.Path {
237 return a.outputFile
238}
239
Colin Cross503c1d02020-01-28 14:00:53 -0800240func (a *AndroidApp) Certificate() Certificate {
241 return a.certificate
242}
243
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700244func (a *AndroidApp) JniCoverageOutputs() android.Paths {
245 return a.jniCoverageOutputs
246}
247
Andrei Onea580636b2022-08-17 16:53:46 +0000248func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
249 return a.privAppAllowlist
250}
251
Colin Crossa97c5d32018-03-28 14:58:31 -0700252var _ AndroidLibraryDependency = (*AndroidApp)(nil)
253
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900254type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800255 Pem, Key android.Path
256 presigned bool
257}
258
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700259var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800260
261func (c Certificate) AndroidMkString() string {
262 if c.presigned {
263 return "PRESIGNED"
264 } else {
265 return c.Pem.String()
266 }
Colin Cross30e076a2015-04-13 13:58:27 -0700267}
268
Colin Cross46c9b8b2017-06-22 16:51:17 -0700269func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900270 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700271 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
272 }
273
Jiyong Parkf1691d22021-03-29 20:11:58 +0900274 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000275 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
276 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100277 if sdkDep.hasFrameworkLibs() {
278 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700279 }
Colin Crossa4f08812018-10-02 22:03:40 -0700280
Jiyong Park92315372021-04-02 08:45:46 +0900281 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700282
283 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
284 ctx.PropertyErrorf("jni_uses_sdk_apis",
285 "can only be set for modules that do not set sdk_version")
286 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
287 ctx.PropertyErrorf("jni_uses_platform_apis",
288 "can only be set for modules that set sdk_version")
289 }
290
Colin Crossa4f08812018-10-02 22:03:40 -0700291 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700292 variation := append(jniTarget.Variations(),
293 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000294
Jiyong Park92d84042024-05-17 22:58:54 +0000295 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
296 // Many factors are considered here.
297 // 1. Basically, the selection follows whether the app has sdk_version set or not.
298 jniUsesSdkVariant := usesSDK
299 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
300 if Bool(a.appProperties.Jni_uses_sdk_apis) {
301 jniUsesSdkVariant = true
302 }
303 if Bool(a.appProperties.Jni_uses_platform_apis) {
304 jniUsesSdkVariant = false
305 }
306 // 3. Then the use of SDK variant is again prohibited for the following cases:
307 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
308 // partition (not only the app) is considered unbudled, there's no need to use the
309 // SDK variant.
310 // 3.2. the app doesn't support embedding the JNI libs
311 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
312 jniUsesSdkVariant = false
313 }
314 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000315 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
316 }
Jiyong Park92d84042024-05-17 22:58:54 +0000317
318 // Use the installable dep tag when the JNIs are not embedded
319 var tag dependencyTag
320 if a.shouldEmbedJnis(ctx) {
321 tag = jniLibTag
322 } else {
323 tag = jniInstallTag
324 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000325 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700326 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000327 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
328 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
329 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700330}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700331
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700332func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800333 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700334 if cert != "" {
335 ctx.AddDependency(ctx.Module(), certificateTag, cert)
336 }
337
Andrei Onea580636b2022-08-17 16:53:46 +0000338 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000339 // There are a few uids that are explicitly considered privileged regardless of their
340 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
341 // but for now, allow it not to be in priv-app.
342 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
343 if !privilegedBecauseOfUid {
344 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
345 }
Andrei Onea580636b2022-08-17 16:53:46 +0000346 }
347
Colin Crossbd01e2a2018-10-04 15:21:03 -0700348 for _, cert := range a.appProperties.Additional_certificates {
349 cert = android.SrcIsModule(cert)
350 if cert != "" {
351 ctx.AddDependency(ctx.Module(), certificateTag, cert)
352 } else {
353 ctx.PropertyErrorf("additional_certificates",
354 `must be names of android_app_certificate modules in the form ":module"`)
355 }
356 }
Colin Cross30e076a2015-04-13 13:58:27 -0700357}
358
Spandan Dasb0410872024-06-25 03:30:03 +0000359// TODO(b/156476221): Remove this allowlist
360var (
361 missingMinSdkVersionMtsAllowlist = []string{
362 "CellBroadcastReceiverGoogleUnitTests",
363 "CellBroadcastReceiverUnitTests",
364 "CtsBatterySavingTestCases",
365 "CtsDeviceAndProfileOwnerApp23",
366 "CtsDeviceAndProfileOwnerApp30",
367 "CtsIntentSenderApp",
368 "CtsJobSchedulerTestCases",
369 "CtsMimeMapTestCases",
370 "CtsTareTestCases",
371 "LibStatsPullTests",
372 "MediaProviderClientTests",
373 "TeleServiceTests",
374 "TestExternalImsServiceApp",
375 "TestSmsRetrieverApp",
376 "TetheringPrivilegedTests",
377 }
378)
379
380func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
381 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
382 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
383 }
384}
385
Jeongik Cha538c0d02019-07-11 15:54:27 +0900386func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000387 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000388 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
389 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700390 packageName := a.overridableAppProperties.Package_name.Get(ctx)
391 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000392 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
393 }
394 a.aapt.manifestValues.applicationId = *applicationId
395 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900396 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700397 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
398 TestOnly: true,
399 })
Colin Cross99939e92024-10-01 16:02:46 -0700400 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
401 Updatable: Bool(a.appProperties.Updatable),
402 TestHelperApp: true,
403 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900404}
405
Colin Cross46c9b8b2017-06-22 16:51:17 -0700406func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100407 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000408 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700409 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000410 a.generateJavaUsedByApex(ctx)
Colin Crossb614cd42024-10-11 12:52:21 -0700411
412 var embeddedJniLibs []android.Path
413
414 if a.embeddedJniLibs {
415 for _, jni := range a.jniLibs {
416 embeddedJniLibs = append(embeddedJniLibs, jni.path)
417 }
418 }
Colin Cross99939e92024-10-01 16:02:46 -0700419 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
Colin Crossb614cd42024-10-11 12:52:21 -0700420 Updatable: Bool(a.appProperties.Updatable),
421 TestHelperApp: false,
422 EmbeddedJNILibs: embeddedJniLibs,
Colin Cross99939e92024-10-01 16:02:46 -0700423 })
Colin Crossae5caf52018-05-22 11:11:52 -0700424}
425
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100426func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100427 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900428 if !a.SdkVersion(ctx).Stable() {
429 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100430 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000431 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100432 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
433 }
Jooyung Han749dc692020-04-15 11:03:39 +0900434
Jiyong Park92315372021-04-02 08:45:46 +0900435 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900436 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000437 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900438 } else {
439 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
440 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000441
442 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
443 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
444 }
445 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
446 if a.deviceProperties.Target_sdk_version == nil {
447 a.SetEnforceDefaultTargetSdkVersion(true)
448 }
449 }
450
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100451 a.checkPlatformAPI(ctx)
452 a.checkSdkVersions(ctx)
453}
454
Jiyong Park970c5242024-05-17 22:58:54 +0000455// Ensures that use_embedded_native_libs are set for apk-in-apex
456func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
457 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
458 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000459 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000460
461 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
462 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
463 }
464}
465
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900466// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
467// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900468func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900469 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
470 ctx.VisitDirectDeps(func(m android.Module) {
471 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
472 return
473 }
474 dep, _ := m.(*cc.Module)
Jooyung Han652d5b32020-05-20 17:12:13 +0900475 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900476 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
477 // handled properly regardless of sdk finalization.
Spandan Das2e8c0442022-05-08 00:39:35 +0000478 jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900479 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Spandan Das2e8c0442022-05-08 00:39:35 +0000480 ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
481 dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900482 return
483 }
484
485 })
486}
487
Sasha Smundak6ad77252019-05-01 13:16:22 -0700488// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800489// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700490func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900491 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800492 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900493 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800494 }
495
Jiyong Parkd044bb42024-05-15 02:09:54 +0900496 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
497 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
498 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800499}
500
Colin Cross43f08db2018-11-12 10:13:39 -0800501// Returns whether this module should have the dex file stored uncompressed in the APK.
502func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800503 if Bool(a.appProperties.Use_embedded_dex) {
504 return true
505 }
506
Colin Cross53a87f52019-06-25 13:35:30 -0700507 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
508 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900509 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000510 return true
511 }
512
Colin Cross53a87f52019-06-25 13:35:30 -0700513 if ctx.Config().UnbundledBuild() {
514 return false
515 }
516
Spandan Dase21a8d42024-01-23 23:56:29 +0000517 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700518}
519
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700520func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900521 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000522 Bool(a.appProperties.Updatable) ||
523 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000524}
525
Liz Kammer9f9fd022020-06-18 19:44:06 +0000526func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
527 aaptFlags := []string{"--rename-manifest-package " + packageName}
528 if renameResourcesPackage {
529 // Required to rename the package name in the resources table.
530 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
531 }
532 return aaptFlags
533}
534
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900535func (a *AndroidApp) OverriddenManifestPackageName() string {
536 return a.overriddenManifestPackageName
537}
538
Liz Kammer9f9fd022020-06-18 19:44:06 +0000539func (a *AndroidApp) renameResourcesPackage() bool {
540 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
541}
542
Jihoon Kang9049c272024-03-19 21:57:36 +0000543func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000544 ctx.VisitDirectDeps(func(dep android.Module) {
545 tag := ctx.OtherModuleDependencyTag(dep)
546 switch tag {
547 case staticLibTag:
548 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
549 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
550 }
551
552 case aconfigDeclarationTag:
553 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
554 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
555 } else {
556 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
557 "flags_packages property, but %s is not aconfig_declarations module type",
558 dep.Name(),
559 )
560 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000561 }
562 })
563
Jihoon Kang9aef7772024-06-14 23:45:06 +0000564 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000565}
566
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800567func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900568 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900569 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900570 usePlatformAPI = true
571 }
572 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000573
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700574 // Ask manifest_fixer to add or update the application element indicating this app has no code.
575 a.aapt.hasNoCode = !a.hasCode(ctx)
576
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800577 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800578
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800579 // 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 +0900580 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800581 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900582 characteristics := ctx.Config().ProductAAPTCharacteristics()
583 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
584 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700585 }
586
Dan Willemsen72be5902018-10-24 20:24:57 -0700587 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
588 // Product AAPT config
589 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800590 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700591 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700592
Dan Willemsen72be5902018-10-24 20:24:57 -0700593 // Product AAPT preferred config
594 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800595 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700596 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700597 }
598
Jiyong Park7f67f482019-01-05 12:57:48 +0900599 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700600 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
601 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700602 // The product override variable has a priority over the package_name property.
603 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700604 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700605 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000606 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900607 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900608 }
609
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800610 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
611
Colin Crosse560c4a2019-03-19 16:03:11 -0700612 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800613 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100614 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000615 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
616 a.aapt.defaultManifestVersion = override
617 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000618 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000619 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100620 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000621
Rico Winda2fa2632024-03-13 13:09:17 +0100622 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200623 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000624
625 aconfigTextFilePaths := getAconfigFilePaths(ctx)
626
Alixf7a10272023-09-27 16:47:56 +0000627 a.aapt.buildActions(ctx,
628 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000629 sdkContext: android.SdkContext(a),
630 classLoaderContexts: a.classLoaderContexts,
631 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
632 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100633 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000634 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000635 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000636 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000637 },
638 )
Colin Cross30e076a2015-04-13 13:58:27 -0700639
Colin Cross46c9b8b2017-06-22 16:51:17 -0700640 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700641 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000642
643 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
644 AconfigTextFiles: aconfigTextFilePaths,
645 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800646}
Colin Cross30e076a2015-04-13 13:58:27 -0700647
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800648func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700649 var staticLibProguardFlagFiles android.Paths
650 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800651 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400652 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
653 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
654 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700655 }
656 })
657
658 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
659
Colin Cross312634e2023-11-21 15:13:56 -0800660 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200661 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100662 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
663 // live for code references and (transitively) mark these as live.
664 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
665 // dead code alive)
666 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
667 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800668}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800669
Colin Cross403cc152020-07-06 14:15:24 -0700670func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800671 var installDir string
672 if ctx.ModuleName() == "framework-res" {
673 // framework-res.apk is installed as system/framework/framework-res.apk
674 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900675 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800676 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800677 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800678 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800679 }
Colin Cross403cc152020-07-06 14:15:24 -0700680
681 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
682}
683
Rico Wind98e7fa82023-11-27 09:44:03 +0100684func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700685 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000686 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700687 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100688 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700689 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100690 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700691 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700692 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100693 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700694 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800695 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700696
Rico Wind98e7fa82023-11-27 09:44:03 +0100697 var packageResources = a.exportPackage
698
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800699 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200700 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100701 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
702 aapt2Convert(ctx, protoFile, packageResources, "proto")
703 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
704 }
705
Colin Cross4eae06d2023-06-20 22:40:02 -0700706 var extraSrcJars android.Paths
707 var extraClasspathJars android.Paths
708 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800709 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700710 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
711 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
712 // classpath when compiling everything else, and add it to the final classes jar.
713 extraClasspathJars = android.Paths{a.aapt.rJar}
714 extraCombinedJars = android.Paths{a.aapt.rJar}
715 } else {
716 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
717 // R.java files for the app's package and the packages from all transitive static android_library
718 // dependencies. Compile the srcjar alongside the rest of the sources.
719 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
720 }
721
Colin Crossfdaa6722024-08-23 11:58:08 -0700722 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200723 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100724 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
725 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
726 packageResources = binaryResources
727 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800728 }
Colin Cross30e076a2015-04-13 13:58:27 -0700729
Rico Wind98e7fa82023-11-27 09:44:03 +0100730 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800731}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800732
Sam Delmerico82602492022-06-10 17:05:42 +0000733func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700734 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000735 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700736 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700737 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700738 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800739 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000740 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700741 for _, jni := range jniLibs {
742 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700743 // Only collect coverage for the first target arch if this is a multilib target.
744 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
745 // data file path collisions since the current coverage file path format doesn't contain
746 // arch-related strings. This is fine for now though; the code coverage team doesn't use
747 // multi-arch targets such as test_suite_* for coverage collections yet.
748 //
749 // Work with the team to come up with a new format that handles multilib modules properly
750 // and change this.
751 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700752 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700753 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
754 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700755 }
756 }
Colin Cross403cc152020-07-06 14:15:24 -0700757 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700758 }
759 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800760 return jniJarFile
761}
Colin Crossa4f08812018-10-02 22:03:40 -0700762
Colin Cross403cc152020-07-06 14:15:24 -0700763func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
764 var jniSymbols android.RuleBuilderInstalls
765 for _, jniLib := range a.jniLibs {
766 if jniLib.unstrippedFile != nil {
767 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
768 From: jniLib.unstrippedFile,
769 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
770 })
771 }
772 }
773 return jniSymbols
774}
775
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700776// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
777// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700778func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
779 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700780 if android.SrcIsModule(certPropValue) == "" {
781 var mainCert Certificate
782 if certPropValue != "" {
783 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
784 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800785 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
786 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700787 }
788 } else {
789 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800790 mainCert = Certificate{
791 Pem: pem,
792 Key: key,
793 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700794 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700795 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700796 }
797
Colin Crossbc2c8a72022-09-14 12:45:42 -0700798 if len(certificates) > 0 {
799 mainCertificate = certificates[0]
800 } else {
801 // This can be reached with an empty certificate list if AllowMissingDependencies is set
802 // and the certificate property for this module is a module reference to a missing module.
803 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
804 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
805 }
806 // Set a certificate to avoid panics later when accessing it.
807 mainCertificate = Certificate{
808 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000809 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700810 }
811 }
812
Zyan Wub7550aa2023-05-18 15:46:31 +0800813 if !m.Platform() {
814 certPath := mainCertificate.Pem.String()
815 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
816 if strings.HasPrefix(certPath, systemCertPath) {
817 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
818 allowed := ctx.Config().EnforceSystemCertificateAllowList()
819
820 if enforceSystemCert && !inList(m.Name(), allowed) {
821 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
822 }
823 }
824 }
825
Colin Crossbc2c8a72022-09-14 12:45:42 -0700826 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800827}
828
Jooyung Han39ee1192020-03-23 20:21:11 +0900829func (a *AndroidApp) InstallApkName() string {
830 return a.installApkName
831}
832
Sam Delmerico15809f82023-05-15 17:21:47 -0400833func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000834 if a.appProperties.Privapp_allowlist == nil {
835 return nil
836 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400837
838 isOverrideApp := a.GetOverriddenBy() != ""
839 if !isOverrideApp {
840 // if this is not an override, we don't need to rewrite the existing privapp allowlist
841 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
842 }
843
Cole Faust258b96f2024-10-04 10:48:24 -0700844 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
845 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000846 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
847 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400848
Cole Faust258b96f2024-10-04 10:48:24 -0700849 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000850 fileName := "privapp_allowlist_" + packageName + ".xml"
Cole Faust4e9f5922024-11-13 16:09:23 -0800851 outPath := android.PathForModuleOut(ctx, fileName)
Andrei Onea580636b2022-08-17 16:53:46 +0000852 ctx.Build(pctx, android.BuildParams{
853 Rule: modifyAllowlist,
854 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
855 Output: outPath,
856 Args: map[string]string{
857 "packageName": packageName,
858 },
859 })
Cole Faust4e9f5922024-11-13 16:09:23 -0800860 return outPath
Andrei Onea580636b2022-08-17 16:53:46 +0000861}
862
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800863func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700864 var apkDeps android.Paths
865
Colin Crossff694a82023-12-13 15:54:49 -0800866 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
867 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700868 a.hideApexVariantFromMake = true
869 }
870
Jeongik Cha538c0d02019-07-11 15:54:27 +0900871 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
872 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
873
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000874 // Unlike installApkName, a.stem should respect base module name for override_android_app.
875 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000876 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000877
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800878 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000879 // Both android_app and override_android_app module are expected to possess
880 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
881 // from the base module. Therefore, use a.Name() which represents
882 // the module name for both android_app and override_android_app.
883 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000884 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800885
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700886 if ctx.ModuleName() == "framework-res" {
887 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700888 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900889 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700890 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
891 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800892 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700893 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700894 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700895 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700896 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700897
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100898 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000899 if a.usesLibrary.shouldDisableDexpreopt {
900 a.dexpreopter.disableDexpreopt()
901 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000902
Colin Cross61fb62e2022-06-23 10:46:28 -0700903 var noticeAssetPath android.WritablePath
904 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
905 // The rule to create the notice file can't be generated yet, as the final output path
906 // for the apk isn't known yet. Add the path where the notice file will be generated to the
907 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
908 // be generated later.
909 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
910 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
911 }
912
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000913 // For apps targeting latest target_sdk_version
914 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
915 a.SetEnforceDefaultTargetSdkVersion(true)
916 }
917
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800918 // Process all building blocks, from AAPT to certificates.
919 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100920 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700921 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100922
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100923 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700924 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000925 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
926 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700927 apkDeps = append(apkDeps, manifestCheckFile)
928 }
929
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800930 a.proguardBuildActions(ctx)
931
Colin Cross014489c2020-06-02 20:09:13 -0700932 a.linter.mergedManifest = a.aapt.mergedManifestFile
933 a.linter.manifest = a.aapt.manifestPath
934 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700935 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700936
Rico Wind98e7fa82023-11-27 09:44:03 +0100937 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800938
Jiyong Park92d84042024-05-17 22:58:54 +0000939 // No need to check the SDK version of the JNI deps unless we embed them
940 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
941 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000942 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800943
944 if ctx.Failed() {
945 return
946 }
947
Colin Crossbc2c8a72022-09-14 12:45:42 -0700948 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800949
950 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800951 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700952 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
953 var v4SignatureFile android.WritablePath = nil
954 if v4SigningRequested {
955 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
956 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700957 var lineageFile android.Path
958 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
959 lineageFile = android.PathForModuleSrc(ctx, lineage)
960 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400961 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
962
Rico Wind98e7fa82023-11-27 09:44:03 +0100963 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800964 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700965 if v4SigningRequested {
966 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
967 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800968
Colin Cross61fb62e2022-06-23 10:46:28 -0700969 if a.aapt.noticeFile.Valid() {
970 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -0700971 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -0700972 android.BuildNoticeHtmlOutputFromLicenseMetadata(
973 ctx, noticeFile, "", "",
974 []string{
975 a.installDir.String() + "/",
976 android.PathForModuleInstall(ctx).String() + "/",
977 a.outputFile.String(),
978 })
Bob Badoureef4c1c2022-05-16 12:20:04 -0700979 builder := android.NewRuleBuilder(pctx, ctx)
980 builder.Command().Text("cp").
981 Input(noticeFile).
982 Output(noticeAssetPath)
983 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -0700984 }
985
Colin Crosse560c4a2019-03-19 16:03:11 -0700986 for _, split := range a.aapt.splits {
987 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -0800988 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700989 if v4SigningRequested {
990 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
991 }
Rico Wind98e7fa82023-11-27 09:44:03 +0100992 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -0700993 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -0700994 if v4SigningRequested {
995 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
996 }
Colin Crosse560c4a2019-03-19 16:03:11 -0700997 }
998
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800999 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -07001000 bundleFile := android.PathForModuleOut(ctx, "base.zip")
1001 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1002 a.bundleFile = bundleFile
1003
Andrei Onea580636b2022-08-17 16:53:46 +00001004 allowlist := a.createPrivappAllowlist(ctx)
1005 if allowlist != nil {
1006 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1007 }
1008
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001009 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001010 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1011 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001012 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001013 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1014 allowlistInstallFilename := a.installApkName + ".xml"
1015 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001016 }
1017
Colin Cross09ad3a62023-11-15 12:29:33 -08001018 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001019 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001020 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1021 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001022 }
Jiyong Park25b92222024-05-17 22:58:54 +00001023 // If we don't embed jni libs, make sure that those are installed along with the
1024 // app, and also place symlinks to the installed paths under the lib/<arch>
1025 // directory of the app installation directory. ex:
1026 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1027 if !a.embeddedJniLibs {
1028 for _, jniLib := range jniLibs {
1029 archStr := jniLib.target.Arch.ArchType.String()
1030 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1031 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001032 // install the symlink itself
1033 symlinkName := installedLib.Base()
1034 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1035 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1036 }
1037 }
1038 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001039 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001040 }
Artur Satayev1111b842020-04-27 19:05:28 +01001041
Colin Crossa6182ab2024-08-21 10:47:44 -07001042 ctx.CheckbuildFile(a.outputFile)
1043
Artur Satayev1111b842020-04-27 19:05:28 +01001044 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001045
1046 providePrebuiltInfo(ctx,
1047 prebuiltInfoProps{
1048 baseModuleName: a.BaseModuleName(),
1049 isPrebuilt: false,
1050 },
1051 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001052
1053 a.setOutputFiles(ctx)
1054}
1055
1056func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1057 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1058 if a.aaptSrcJar != nil {
1059 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1060 }
1061 if a.rJar != nil {
1062 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1063 }
1064 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1065 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1066 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1067 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001068}
1069
Colin Crossc2d24052020-05-13 11:05:02 -07001070type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001071 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001072 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001073 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1074}
1075
1076func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1077 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001078 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001079
Colin Crossc2d24052020-05-13 11:05:02 -07001080 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001081 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1082 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001083 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001084 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
Spandan Das10c41362024-12-03 01:33:09 +00001085 checkNativeSdkVersion, func(parent, child android.Module) bool {
1086 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
1087 childLinkable, _ := child.(cc.LinkableInterface)
1088 parentLinkable, _ := parent.(cc.LinkableInterface)
1089 useStubsOfDep := childLinkable.IsStubs()
1090 if apkInApex && parentLinkable != nil {
1091 // APK-in-APEX
1092 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
1093 useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child))
1094 }
1095 return !childLinkable.IsNdk(ctx.Config()) && !useStubsOfDep
1096 })
Makoto Onuki2ca84272024-02-10 00:15:21 +00001097
1098 var certificates []Certificate
1099
Colin Crossb614cd42024-10-11 12:52:21 -07001100 var directImplementationDeps android.Paths
1101 var transitiveImplementationDeps []depset.DepSet[android.Path]
Makoto Onuki2ca84272024-02-10 00:15:21 +00001102 ctx.VisitDirectDeps(func(module android.Module) {
1103 otherName := ctx.OtherModuleName(module)
1104 tag := ctx.OtherModuleDependencyTag(module)
1105
1106 if tag == certificateTag {
1107 if dep, ok := module.(*AndroidAppCertificate); ok {
1108 certificates = append(certificates, dep.Certificate)
1109 } else {
1110 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1111 }
1112 }
Colin Crossb614cd42024-10-11 12:52:21 -07001113
1114 if IsJniDepTag(tag) {
1115 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1116 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1117 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1118 }
1119 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001120 })
Colin Crossb614cd42024-10-11 12:52:21 -07001121 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1122 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1123 })
1124
Makoto Onuki2ca84272024-02-10 00:15:21 +00001125 return jniLib, prebuiltJniPackages, certificates
1126}
1127
1128func collectJniDeps(ctx android.ModuleContext,
1129 shouldCollectRecursiveNativeDeps bool,
1130 checkNativeSdkVersion bool,
Spandan Das10c41362024-12-03 01:33:09 +00001131 filter func(parent, child android.Module) bool) ([]jniLib, android.Paths) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001132 var jniLibs []jniLib
1133 var prebuiltJniPackages android.Paths
1134 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001135
Peter Collingbournead84f972019-12-17 16:46:18 -08001136 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001137 otherName := ctx.OtherModuleName(module)
1138 tag := ctx.OtherModuleDependencyTag(module)
1139
Colin Crossf0913fb2020-07-29 12:59:39 -07001140 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001141 if dep, ok := module.(cc.LinkableInterface); ok {
Spandan Das10c41362024-12-03 01:33:09 +00001142 if filter != nil && !filter(parent, module) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001143 return false
1144 }
1145
Colin Crossa4f08812018-10-02 22:03:40 -07001146 lib := dep.OutputFile()
1147 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001148 path := lib.Path()
1149 if seenModulePaths[path.String()] {
1150 return false
1151 }
1152 seenModulePaths[path.String()] = true
1153
1154 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1155 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1156 otherName)
1157 }
1158
Colin Crossa4f08812018-10-02 22:03:40 -07001159 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001160 name: ctx.OtherModuleName(module),
1161 path: path,
1162 target: module.Target(),
1163 coverageFile: dep.CoverageOutputFile(),
1164 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001165 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001166 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001167 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001168 } else if ctx.Config().AllowMissingDependencies() {
1169 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001170 } else {
1171 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1172 }
1173 } else {
1174 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001175 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001176
1177 return shouldCollectRecursiveNativeDeps
1178 }
1179
Colin Cross313aa542023-12-13 13:47:44 -08001180 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001181 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1182 }
1183
Peter Collingbournead84f972019-12-17 16:46:18 -08001184 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001185 })
1186
Makoto Onuki2ca84272024-02-10 00:15:21 +00001187 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001188}
1189
Colin Cross8bf14fc2024-09-25 16:41:31 -07001190func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001191 ctx.WalkDeps(func(child, parent android.Module) bool {
1192 isExternal := !a.DepIsInSameApex(ctx, child)
1193 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001194 if !do(ctx, parent, am, isExternal) {
1195 return false
1196 }
Artur Satayev1111b842020-04-27 19:05:28 +01001197 }
1198 return !isExternal
1199 })
1200}
1201
1202func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1203 if ctx.Host() {
1204 return
1205 }
1206
1207 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross8bf14fc2024-09-25 16:41:31 -07001208 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001209 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001210
1211 // Skip dependencies that are only available to APEXes; they are developed with updatability
1212 // in mind and don't need manual approval.
1213 if to.(android.ApexModule).NotAvailableForPlatform() {
1214 return true
1215 }
1216
Artur Satayev1111b842020-04-27 19:05:28 +01001217 if info, exist := depsInfo[depName]; exist {
1218 info.From = append(info.From, from.Name())
1219 info.IsExternal = info.IsExternal && externalDep
1220 depsInfo[depName] = info
1221 } else {
1222 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001223 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001224 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001225 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001226 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1227 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001228 }
Jiyong Park92315372021-04-02 08:45:46 +09001229 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1230 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1231 // string
1232 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001233 toMinSdkVersion = v
1234 }
Artur Satayev1111b842020-04-27 19:05:28 +01001235 }
1236 depsInfo[depName] = android.ApexModuleDepInfo{
1237 To: depName,
1238 From: []string{from.Name()},
1239 IsExternal: externalDep,
1240 MinSdkVersion: toMinSdkVersion,
1241 }
1242 }
Jooyung Han749dc692020-04-15 11:03:39 +09001243 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001244 })
1245
Jiyong Park92315372021-04-02 08:45:46 +09001246 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001247}
1248
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001249func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1250 return a.appProperties.EnforceDefaultTargetSdkVersion
1251}
1252
1253func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1254 a.appProperties.EnforceDefaultTargetSdkVersion = val
1255}
1256
Artur Satayev849f8442020-04-28 14:57:42 +01001257func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001258 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001259}
1260
Colin Cross0ea8ba82019-06-06 14:33:29 -07001261func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001262 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1263 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001264 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001265 }
Cole Fausteb9c1482024-11-18 16:49:19 -08001266 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001267}
1268
Jiyong Park0f80c182020-01-31 02:49:53 +09001269func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1270 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1271 return true
1272 }
1273 return a.Library.DepIsInSameApex(ctx, dep)
1274}
1275
Jiyong Parkf7487312019-10-17 12:54:30 +09001276func (a *AndroidApp) Privileged() bool {
1277 return Bool(a.appProperties.Privileged)
1278}
1279
Colin Crosse1a85552024-06-14 12:17:37 -07001280func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001281 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001282}
1283
Ivan Lozanod7586b62021-04-01 09:49:36 -04001284func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001285 a.appProperties.PreventInstall = true
1286}
1287
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001288func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1289 a.appProperties.IsCoverageVariant = coverage
1290}
1291
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001292func (a *AndroidApp) EnableCoverageIfNeeded() {}
1293
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001294var _ cc.Coverage = (*AndroidApp)(nil)
1295
Cole Faustb36d31d2024-08-27 16:04:28 -07001296func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1297 a.Library.IDEInfo(ctx, dpInfo)
1298 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001299}
1300
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001301func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1302 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1303}
1304
1305func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1306 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1307}
1308
Colin Cross1b16b0e2019-02-12 14:41:32 -08001309// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001310func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001311 module := &AndroidApp{}
1312
Liz Kammera7a64f32020-07-09 15:16:41 -07001313 module.Module.dexProperties.Optimize.EnabledByDefault = true
1314 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001315 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001316
Colin Crossae5caf52018-05-22 11:11:52 -07001317 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001318 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001319 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001320
Colin Crossce6734e2020-06-15 16:09:53 -07001321 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001322 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001323 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001324 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001325 &module.overridableAppProperties,
1326 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001327
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001328 module.usesLibrary.enforce = true
1329
Colin Crossa4f08812018-10-02 22:03:40 -07001330 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1331 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001332 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001333 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001334
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001335 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1336 a := ctx.Module().(*AndroidApp)
1337
1338 characteristics := ctx.Config().ProductAAPTCharacteristics()
1339 if characteristics == "default" || characteristics == "" {
1340 module.appProperties.Generate_product_characteristics_rro = nil
1341 // no need to create RRO
1342 return
1343 }
1344
1345 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1346 return
1347 }
1348
1349 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1350 rroManifestName := rroPackageName + "_manifest"
1351
1352 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1353 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1354
1355 rroManifestProperties := struct {
1356 Name *string
1357 Tools []string
1358 Out []string
1359 Srcs []string
1360 Cmd *string
1361 }{
1362 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001363 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001364 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001365 Srcs: []string{":" + a.Name() + "{.apk}"},
1366 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001367 }
Cole Fauste19d3352024-10-17 10:30:57 -07001368 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001369
1370 rroProperties := struct {
1371 Name *string
1372 Filter_product *string
1373 Aaptflags []string
1374 Manifest *string
Cole Faust5b989772024-11-06 11:03:16 -08001375 Resource_dirs proptools.Configurable[[]string]
Jihoon Kangf62f4222024-10-21 23:06:41 +00001376 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001377 }{
1378 Name: proptools.StringPtr(rroPackageName),
1379 Filter_product: proptools.StringPtr(characteristics),
1380 Aaptflags: []string{"--auto-add-overlay"},
1381 Manifest: proptools.StringPtr(":" + rroManifestName),
1382 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001383 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001384 }
优秀d75e9982024-05-09 07:15:55 +00001385 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1386 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1387 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1388 }
1389 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001390 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1391 })
1392
Colin Cross36242852017-06-23 15:06:31 -07001393 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001394}
Colin Crossae5caf52018-05-22 11:11:52 -07001395
Spandan Das71be42d2024-11-20 18:34:16 +00001396func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1397 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1398}
1399
Alix96ea88452023-08-31 15:48:23 +00001400// A dictionary of values to be overridden in the manifest.
1401type Manifest_values struct {
1402 // Overrides the value of package_name in the manifest
1403 ApplicationId *string
1404}
1405
Colin Crossae5caf52018-05-22 11:11:52 -07001406type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001407 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001408 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001409
Seth Moorec6f4b532023-02-02 13:22:26 -08001410 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001411 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001412
1413 // If specified, the mainline module package name in the test config is overwritten by it.
1414 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001415
1416 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001417}
1418
1419type AndroidTest struct {
1420 AndroidApp
1421
1422 appTestProperties appTestProperties
1423
1424 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001425
Dan Shi95d19422020-08-15 12:24:26 -07001426 testConfig android.Path
1427 extraTestConfigs android.Paths
1428 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001429}
1430
Jaewoong Jung0949f312019-09-11 10:25:18 -07001431func (a *AndroidTest) InstallInTestcases() bool {
1432 return true
1433}
1434
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001435type androidTestApp interface {
1436 includedInTestSuite(searchPrefix string) bool
1437}
1438
1439func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1440 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1441}
1442
1443func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1444 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1445}
1446
Colin Crossae5caf52018-05-22 11:11:52 -07001447func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001448 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001449 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001450 if a.appTestProperties.Instrumentation_target_package != nil {
1451 a.additionalAaptFlags = append(a.additionalAaptFlags,
1452 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1453 } else if a.appTestProperties.Instrumentation_for != nil {
1454 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001455 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1456 if overridden {
1457 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1458 }
1459 }
Alix96ea88452023-08-31 15:48:23 +00001460 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1461 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001462 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1463 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001464 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1465 }
1466 a.aapt.manifestValues.applicationId = *applicationId
1467 }
Colin Crossae5caf52018-05-22 11:11:52 -07001468 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001469
easoncylee5bcff5d2020-04-30 14:57:06 +08001470 for _, module := range a.testProperties.Test_mainline_modules {
1471 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1472 }
1473
Jaewoong Jung39982342020-01-14 10:27:18 -08001474 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001475 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1476 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001477 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001478 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001479 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001480 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1481 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001482 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001483
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001484 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001485 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001486 OutputFile: a.OutputFile(),
1487 TestConfig: a.testConfig,
1488 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001489 TestSuites: a.testProperties.Test_suites,
1490 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001491 LocalCertificate: a.certificate.AndroidMkString(),
1492 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001493 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1494 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001495 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001496 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1497 TestOnly: true,
1498 TopLevelTarget: true,
1499 })
1500
Colin Cross303e21f2018-08-07 16:49:25 -07001501}
1502
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001503func testcaseRel(paths android.Paths) []string {
1504 relPaths := []string{}
1505 for _, p := range paths {
1506 relPaths = append(relPaths, p.Rel())
1507 }
1508 return relPaths
1509}
1510
Jaewoong Jung39982342020-01-14 10:27:18 -08001511func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1512 if testConfig == nil {
1513 return nil
1514 }
1515
1516 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001517 rule := android.NewRuleBuilder(pctx, ctx)
1518 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001519 fixNeeded := false
1520
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001521 // 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 -08001522 if ctx.ModuleName() != a.installApkName {
1523 fixNeeded = true
1524 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1525 }
1526
Cole Faust258b96f2024-10-04 10:48:24 -07001527 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1528 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001529 fixNeeded = true
1530 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001531 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001532 }
1533
Seth Moorec6f4b532023-02-02 13:22:26 -08001534 if a.appTestProperties.Mainline_package_name != nil {
1535 fixNeeded = true
1536 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1537 }
1538
Jaewoong Jung39982342020-01-14 10:27:18 -08001539 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001540 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001541 return fixedConfig
1542 }
1543 return testConfig
1544}
1545
Yihan Dong8be09c22024-08-29 15:32:13 +08001546func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1547 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1548 // Instrument the android_test_helper target to log potential API calls at the run time.
1549 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1550 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1551 a.setApiMapper(true)
1552 }
1553 a.AndroidApp.DepsMutator(ctx)
1554}
1555
Colin Cross303e21f2018-08-07 16:49:25 -07001556func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001557 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1558 // Instrument the android_test_helper target to log potential API calls at the run time.
1559 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1560 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1561 a.setApiMapper(true)
1562 }
Colin Cross303e21f2018-08-07 16:49:25 -07001563 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001564}
1565
1566func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1567 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001568 if a.appTestProperties.Instrumentation_for != nil {
1569 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1570 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1571 // use instrumentationForTag instead of libTag.
1572 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1573 }
Colin Crossae5caf52018-05-22 11:11:52 -07001574}
1575
Colin Cross1b16b0e2019-02-12 14:41:32 -08001576// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1577// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001578func AndroidTestFactory() android.Module {
1579 module := &AndroidTest{}
1580
Jared Duke63a3da92022-06-02 19:11:14 +00001581 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001582
1583 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001584 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001585 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001586 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1587 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001588 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001589 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001590
Colin Crossce6734e2020-06-15 16:09:53 -07001591 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001592 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001593 &module.aaptProperties,
1594 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001595 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001596 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001597 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001598
Colin Crossa4f08812018-10-02 22:03:40 -07001599 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1600 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001601 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001602
Colin Crossae5caf52018-05-22 11:11:52 -07001603 return module
1604}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001605
Colin Cross252fc6f2018-10-04 15:22:03 -07001606type appTestHelperAppProperties struct {
1607 // list of compatibility suites (for example "cts", "vts") that the module should be
1608 // installed into.
1609 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001610
1611 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1612 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1613 // explicitly.
1614 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001615
1616 // Install the test into a folder named for the module in all test suites.
1617 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001618
1619 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001620}
1621
1622type AndroidTestHelperApp struct {
1623 AndroidApp
1624
1625 appTestHelperAppProperties appTestHelperAppProperties
1626}
1627
Jaewoong Jung326a9412019-11-21 10:41:00 -08001628func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1629 return true
1630}
1631
Colin Cross1b16b0e2019-02-12 14:41:32 -08001632// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1633// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1634// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001635func AndroidTestHelperAppFactory() android.Module {
1636 module := &AndroidTestHelperApp{}
1637
Jared Duke63a3da92022-06-02 19:11:14 +00001638 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001639 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001640
1641 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001642 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1643 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001644 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001645 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001646
Colin Crossce6734e2020-06-15 16:09:53 -07001647 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001648 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001649 &module.aaptProperties,
1650 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001651 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001652 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001653
1654 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1655 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001656 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001657 return module
1658}
1659
Colin Crossbd01e2a2018-10-04 15:21:03 -07001660type AndroidAppCertificate struct {
1661 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001662
Colin Crossbd01e2a2018-10-04 15:21:03 -07001663 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001664 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001665}
1666
1667type AndroidAppCertificateProperties struct {
1668 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1669 Certificate *string
1670}
1671
Colin Cross1b16b0e2019-02-12 14:41:32 -08001672// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1673// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001674func AndroidAppCertificateFactory() android.Module {
1675 module := &AndroidAppCertificate{}
1676 module.AddProperties(&module.properties)
1677 android.InitAndroidModule(module)
1678 return module
1679}
1680
Colin Crossbd01e2a2018-10-04 15:21:03 -07001681func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1682 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001683 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001684 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1685 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001686 }
1687}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001688
1689type OverrideAndroidApp struct {
1690 android.ModuleBase
1691 android.OverrideModuleBase
1692}
1693
Sasha Smundak613cbb12020-06-05 10:27:23 -07001694func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001695 // All the overrides happen in the base module.
1696 // TODO(jungjw): Check the base module type.
1697}
1698
1699// override_android_app is used to create an android_app module based on another android_app by overriding
1700// some of its properties.
1701func OverrideAndroidAppModuleFactory() android.Module {
1702 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001703 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001704 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001705 &overridableAppProperties{},
1706 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001707
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001708 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001709 android.InitOverrideModule(m)
1710 return m
1711}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001712
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001713type OverrideAndroidTest struct {
1714 android.ModuleBase
1715 android.OverrideModuleBase
1716}
1717
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001718func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001719 // All the overrides happen in the base module.
1720 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001721 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1722 TestOnly: true,
1723 TopLevelTarget: true,
1724 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001725}
1726
1727// override_android_test is used to create an android_app module based on another android_test by overriding
1728// some of its properties.
1729func OverrideAndroidTestModuleFactory() android.Module {
1730 m := &OverrideAndroidTest{}
1731 m.AddProperties(&overridableAppProperties{})
1732 m.AddProperties(&appTestProperties{})
1733
1734 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1735 android.InitOverrideModule(m)
1736 return m
1737}
1738
Colin Cross50ddcc42019-05-16 12:28:22 -07001739type UsesLibraryProperties struct {
1740 // 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 -07001741 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001742
1743 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1744 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001745 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001746
1747 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1748 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1749 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001750
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001751 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1752 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1753 // normally is the same as the module name, but there are exceptions.
1754 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001755
1756 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1757 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1758 // added to the APK's manifest's <uses-library> elements.
1759 //
1760 // Care must be taken when using this as it could result in runtime errors if the APK actually
1761 // uses classes provided by the library and which are not provided in any other way.
1762 //
1763 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1764 // android.test.base shared library (and related libraries) but which depend on some common
1765 // libraries that depend on the android.test.base library. Without this those tests will end up
1766 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1767 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1768 // test altogether by providing access to classes that the tests were not expecting. Those tests
1769 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1770 // with the classes provided by the android.test.base library.
1771 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001772
1773 // The module names of optional uses-library libraries that are missing from the source tree.
1774 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001775}
1776
1777// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1778// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1779// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1780// with knowledge of their shared libraries.
1781type usesLibrary struct {
1782 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001783
1784 // Whether to enforce verify_uses_library check.
1785 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001786
1787 // Whether dexpreopt should be disabled
1788 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001789}
1790
Colin Cross4a80a152022-12-21 21:51:52 -08001791func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001792 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07001793 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001794 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1795 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001796 // Only add these extra dependencies if the module is an app that depends on framework
1797 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001798 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001799 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001800 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1801 // class loader context for dex2oat. Add them as a dependency with a special tag.
1802 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1803 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1804 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001805 }
Cole Faust64f2d842024-10-17 13:28:34 -07001806 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001807 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001808 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07001809 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001810 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001811 }
1812}
1813
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001814// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001815func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07001816 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001817 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001818 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001819 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1820 }
1821 return exists
1822 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001823 return optionalUsesLibs
1824}
1825
Ulya Trafimovich24446712021-07-15 14:59:34 +01001826// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1827// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001828func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1829 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001830
1831 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1832 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1833 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1834 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001835 }
1836
Ulya Trafimovich24446712021-07-15 14:59:34 +01001837 ctx.VisitDirectDeps(func(m android.Module) {
1838 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1839 if !isUsesLibTag {
1840 return
1841 }
1842
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001843 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001844
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001845 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1846 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1847 // from implementation libraries by their name, which is different as it has a suffix.
1848 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1849 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1850 return
1851 }
1852 }
1853
Ulya Trafimovich24446712021-07-15 14:59:34 +01001854 if lib, ok := m.(UsesLibraryDependency); ok {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001855 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1856 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1857 // This will be restricted to optional_uses_libs
1858 if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
1859 u.shouldDisableDexpreopt = true
1860 return
1861 }
1862 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001863 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001864 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001865 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001866 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001867 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001868 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001869 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001870 } else if ctx.Config().AllowMissingDependencies() {
1871 ctx.AddMissingDependencies([]string{dep})
1872 } else {
1873 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1874 }
1875 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001876 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001877}
1878
1879// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1880// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1881// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07001882func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
1883 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
1884 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001885 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001886}
1887
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001888// 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 -07001889func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
1890 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001891 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1892}
1893
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001894// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1895// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1896// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1897// extension: APKs are supposed to end with '.apk').
1898func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001899 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001900
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001901 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001902
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001903 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1904 // check is not necessary, and although it is good to have, it is difficult to maintain on
1905 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1906 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001907 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001908 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001909 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001910 }
1911
Colin Crossf1a035e2020-11-16 17:32:30 -08001912 rule := android.NewRuleBuilder(pctx, ctx)
1913 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001914 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001915 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001916 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001917 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001918
1919 if outputFile != nil {
1920 cmd.FlagWithOutput("-o ", outputFile)
1921 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001922
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001923 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1924 cmd.Flag("--enforce-uses-libraries-relax")
1925 }
1926
Jiakai Zhangf98da192024-04-15 11:15:41 +00001927 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1928 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001929 cmd.FlagWithArg("--uses-library ", lib)
1930 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001931 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001932 cmd.FlagWithArg("--optional-uses-library ", lib)
1933 }
1934
Jiakai Zhangf98da192024-04-15 11:15:41 +00001935 // Also add missing optional uses libs, as the manifest check expects them.
1936 // Note that what we add here are the module names of those missing libs, not library names, while
1937 // the manifest check actually expects library names. However, the case where a library is missing
1938 // and the module name != the library name is too rare for us to handle.
1939 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1940 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1941 }
1942
Colin Crossf1a035e2020-11-16 17:32:30 -08001943 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001944 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001945}
Colin Cross50ddcc42019-05-16 12:28:22 -07001946
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001947// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1948// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001949func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1950 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001951 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001952 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001953}
1954
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001955// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1956// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001957func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1958 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1959 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001960}