blob: 5f433265028b47744246ff5b1ca8390313968470 [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
70}
71
72var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
73
Colin Cross30e076a2015-04-13 13:58:27 -070074// AndroidManifest.xml merging
75// package splits
76
Colin Crossfabb6082018-02-20 17:22:23 -080077type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070078 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070079 Additional_certificates []string
80
81 // If set, create package-export.apk, which other packages can
82 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080083 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070084
Colin Cross16056062017-12-13 22:46:28 -080085 // Specifies that this app should be installed to the priv-app directory,
86 // where the system will grant it additional privileges not available to
87 // normal apps.
88 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070089
90 // list of resource labels to generate individual resource packages
91 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040092
Colin Crossa4f08812018-10-02 22:03:40 -070093 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +000094 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -070095
Colin Cross7204cf02020-05-06 17:51:39 -070096 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -080097 // sdk_version.
98 Jni_uses_platform_apis *bool
99
Colin Cross7204cf02020-05-06 17:51:39 -0700100 // if true, use JNI libraries that link against SDK APIs even if this module does not set
101 // sdk_version.
102 Jni_uses_sdk_apis *bool
103
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700104 // STL library to use for JNI libraries.
105 Stl *string `android:"arch_variant"`
106
Colin Crosse4246ab2019-02-05 21:55:21 -0800107 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900108 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
109 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
110 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
111 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800112 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800113
114 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
115 // they are used from inside the APK at runtime.
116 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700117
Jiyong Parkd044bb42024-05-15 02:09:54 +0900118 // Forces native libraries to always be packaged into the APK,
119 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
120 // True for android_test* modules.
121 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700122
123 // If set, find and merge all NOTICE files that this module and its dependencies have and store
124 // it in the APK as an asset.
125 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700126
127 // cc.Coverage related properties
128 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700129 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100130
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000131 // It can be set to test the behaviour of default target sdk version.
132 // Only required when updatable: false. It is an error if updatable: true and this is false.
133 Enforce_default_target_sdk_version *bool
134
135 // If set, the targetSdkVersion for the target is set to the latest default API level.
136 // This would be by default false, unless updatable: true or
137 // enforce_default_target_sdk_version: true in which case this defaults to true.
138 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
139
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100140 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100141 // additional rules to make sure an app can safely be updated. Default is false.
142 // Prefer using other specific properties if build behaviour must be changed; avoid using this
143 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100144 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000145
146 // Specifies the file that contains the allowlist for this app.
147 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900148
149 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
150 // and install the RRO package to /product partition, instead of passing --product argument
151 // to aapt2. Default is false.
152 // Setting this will make this APK identical to all targets, regardless of
153 // PRODUCT_CHARACTERISTICS.
154 Generate_product_characteristics_rro *bool
155
156 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
157 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700158}
159
Jaewoong Jung525443a2019-02-28 15:35:54 -0800160// android_app properties that can be overridden by override_android_app
161type overridableAppProperties struct {
162 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
163 // or an android_app_certificate module name in the form ":module".
164 Certificate *string
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700165
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800166 // Name of the signing certificate lineage file or filegroup module.
167 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700168
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400169 // For overriding the --rotation-min-sdk-version property of apksig
170 RotationMinSdkVersion *string
171
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700172 // 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 -0700173 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800174
175 // the logging parent of this app.
176 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000177
178 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
179 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000180
181 // Names of modules to be overridden. Listed modules can only be other binaries
182 // (in Make or Soong).
183 // This does not completely prevent installation of the overridden binaries, but if both
184 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
185 // from PRODUCT_PACKAGES.
186 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800187}
188
Colin Cross30e076a2015-04-13 13:58:27 -0700189type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700190 Library
191 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800192 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700193
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900194 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700195
Colin Crossfabb6082018-02-20 17:22:23 -0800196 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700197
Jaewoong Jung525443a2019-02-28 15:35:54 -0800198 overridableAppProperties overridableAppProperties
199
Colin Cross403cc152020-07-06 14:15:24 -0700200 jniLibs []jniLib
201 installPathForJNISymbols android.Path
202 embeddedJniLibs bool
203 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700204
205 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800206
207 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
208 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800209
Colin Cross70dda7e2019-10-01 22:05:35 -0700210 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700211
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700212 onDeviceDir string
213
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800214 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700215
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900216 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100217
218 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000219
220 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000221
222 privAppAllowlist android.OptionalPath
Colin Crosse1731a52017-12-14 11:22:55 -0800223}
224
Martin Stjernholm6d415272020-01-31 17:10:36 +0000225func (a *AndroidApp) IsInstallable() bool {
226 return Bool(a.properties.Installable)
227}
228
Colin Crossa14fb6a2024-10-23 16:57:06 -0700229func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000230 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700231}
232
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900233func (a *AndroidApp) OutputFile() android.Path {
234 return a.outputFile
235}
236
Colin Cross503c1d02020-01-28 14:00:53 -0800237func (a *AndroidApp) Certificate() Certificate {
238 return a.certificate
239}
240
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700241func (a *AndroidApp) JniCoverageOutputs() android.Paths {
242 return a.jniCoverageOutputs
243}
244
Andrei Onea580636b2022-08-17 16:53:46 +0000245func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
246 return a.privAppAllowlist
247}
248
Colin Crossa97c5d32018-03-28 14:58:31 -0700249var _ AndroidLibraryDependency = (*AndroidApp)(nil)
250
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900251type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800252 Pem, Key android.Path
253 presigned bool
254}
255
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700256var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800257
258func (c Certificate) AndroidMkString() string {
259 if c.presigned {
260 return "PRESIGNED"
261 } else {
262 return c.Pem.String()
263 }
Colin Cross30e076a2015-04-13 13:58:27 -0700264}
265
Colin Cross46c9b8b2017-06-22 16:51:17 -0700266func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900267 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700268 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
269 }
270
Jiyong Parkf1691d22021-03-29 20:11:58 +0900271 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000272 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
273 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100274 if sdkDep.hasFrameworkLibs() {
275 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700276 }
Colin Crossa4f08812018-10-02 22:03:40 -0700277
Jiyong Park92315372021-04-02 08:45:46 +0900278 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700279
280 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
281 ctx.PropertyErrorf("jni_uses_sdk_apis",
282 "can only be set for modules that do not set sdk_version")
283 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
284 ctx.PropertyErrorf("jni_uses_platform_apis",
285 "can only be set for modules that set sdk_version")
286 }
287
Colin Crossa4f08812018-10-02 22:03:40 -0700288 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700289 variation := append(jniTarget.Variations(),
290 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000291
Jiyong Park92d84042024-05-17 22:58:54 +0000292 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
293 // Many factors are considered here.
294 // 1. Basically, the selection follows whether the app has sdk_version set or not.
295 jniUsesSdkVariant := usesSDK
296 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
297 if Bool(a.appProperties.Jni_uses_sdk_apis) {
298 jniUsesSdkVariant = true
299 }
300 if Bool(a.appProperties.Jni_uses_platform_apis) {
301 jniUsesSdkVariant = false
302 }
303 // 3. Then the use of SDK variant is again prohibited for the following cases:
304 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
305 // partition (not only the app) is considered unbudled, there's no need to use the
306 // SDK variant.
307 // 3.2. the app doesn't support embedding the JNI libs
308 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
309 jniUsesSdkVariant = false
310 }
311 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000312 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
313 }
Jiyong Park92d84042024-05-17 22:58:54 +0000314
315 // Use the installable dep tag when the JNIs are not embedded
316 var tag dependencyTag
317 if a.shouldEmbedJnis(ctx) {
318 tag = jniLibTag
319 } else {
320 tag = jniInstallTag
321 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000322 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700323 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000324 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
325 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
326 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700327}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700328
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700329func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800330 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700331 if cert != "" {
332 ctx.AddDependency(ctx.Module(), certificateTag, cert)
333 }
334
Andrei Onea580636b2022-08-17 16:53:46 +0000335 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000336 // There are a few uids that are explicitly considered privileged regardless of their
337 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
338 // but for now, allow it not to be in priv-app.
339 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
340 if !privilegedBecauseOfUid {
341 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
342 }
Andrei Onea580636b2022-08-17 16:53:46 +0000343 }
344
Colin Crossbd01e2a2018-10-04 15:21:03 -0700345 for _, cert := range a.appProperties.Additional_certificates {
346 cert = android.SrcIsModule(cert)
347 if cert != "" {
348 ctx.AddDependency(ctx.Module(), certificateTag, cert)
349 } else {
350 ctx.PropertyErrorf("additional_certificates",
351 `must be names of android_app_certificate modules in the form ":module"`)
352 }
353 }
Colin Cross30e076a2015-04-13 13:58:27 -0700354}
355
Spandan Dasb0410872024-06-25 03:30:03 +0000356// TODO(b/156476221): Remove this allowlist
357var (
358 missingMinSdkVersionMtsAllowlist = []string{
359 "CellBroadcastReceiverGoogleUnitTests",
360 "CellBroadcastReceiverUnitTests",
361 "CtsBatterySavingTestCases",
362 "CtsDeviceAndProfileOwnerApp23",
363 "CtsDeviceAndProfileOwnerApp30",
364 "CtsIntentSenderApp",
365 "CtsJobSchedulerTestCases",
366 "CtsMimeMapTestCases",
367 "CtsTareTestCases",
368 "LibStatsPullTests",
369 "MediaProviderClientTests",
370 "TeleServiceTests",
371 "TestExternalImsServiceApp",
372 "TestSmsRetrieverApp",
373 "TetheringPrivilegedTests",
374 }
375)
376
377func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
378 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
379 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
380 }
381}
382
Jeongik Cha538c0d02019-07-11 15:54:27 +0900383func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000384 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000385 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
386 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700387 packageName := a.overridableAppProperties.Package_name.Get(ctx)
388 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000389 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
390 }
391 a.aapt.manifestValues.applicationId = *applicationId
392 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900393 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700394 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
395 TestOnly: true,
396 })
Colin Cross99939e92024-10-01 16:02:46 -0700397 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
398 Updatable: Bool(a.appProperties.Updatable),
399 TestHelperApp: true,
400 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900401}
402
Colin Cross46c9b8b2017-06-22 16:51:17 -0700403func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100404 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000405 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700406 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000407 a.generateJavaUsedByApex(ctx)
Colin Cross99939e92024-10-01 16:02:46 -0700408 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
409 Updatable: Bool(a.appProperties.Updatable),
410 TestHelperApp: false,
411 })
Colin Crossae5caf52018-05-22 11:11:52 -0700412}
413
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100414func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100415 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900416 if !a.SdkVersion(ctx).Stable() {
417 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100418 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000419 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100420 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
421 }
Jooyung Han749dc692020-04-15 11:03:39 +0900422
Jiyong Park92315372021-04-02 08:45:46 +0900423 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900424 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000425 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900426 } else {
427 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
428 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000429
430 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
431 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
432 }
433 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
434 if a.deviceProperties.Target_sdk_version == nil {
435 a.SetEnforceDefaultTargetSdkVersion(true)
436 }
437 }
438
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100439 a.checkPlatformAPI(ctx)
440 a.checkSdkVersions(ctx)
441}
442
Jiyong Park970c5242024-05-17 22:58:54 +0000443// Ensures that use_embedded_native_libs are set for apk-in-apex
444func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
445 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
446 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000447 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000448
449 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
450 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
451 }
452}
453
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900454// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
455// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900456func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900457 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
458 ctx.VisitDirectDeps(func(m android.Module) {
459 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
460 return
461 }
462 dep, _ := m.(*cc.Module)
Jooyung Han652d5b32020-05-20 17:12:13 +0900463 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900464 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
465 // handled properly regardless of sdk finalization.
Spandan Das2e8c0442022-05-08 00:39:35 +0000466 jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900467 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Spandan Das2e8c0442022-05-08 00:39:35 +0000468 ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
469 dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900470 return
471 }
472
473 })
474}
475
Sasha Smundak6ad77252019-05-01 13:16:22 -0700476// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800477// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700478func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900479 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800480 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900481 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800482 }
483
Jiyong Parkd044bb42024-05-15 02:09:54 +0900484 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
485 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
486 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800487}
488
Colin Cross43f08db2018-11-12 10:13:39 -0800489// Returns whether this module should have the dex file stored uncompressed in the APK.
490func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800491 if Bool(a.appProperties.Use_embedded_dex) {
492 return true
493 }
494
Colin Cross53a87f52019-06-25 13:35:30 -0700495 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
496 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900497 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000498 return true
499 }
500
Colin Cross53a87f52019-06-25 13:35:30 -0700501 if ctx.Config().UnbundledBuild() {
502 return false
503 }
504
Spandan Dase21a8d42024-01-23 23:56:29 +0000505 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700506}
507
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700508func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900509 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000510 Bool(a.appProperties.Updatable) ||
511 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000512}
513
Liz Kammer9f9fd022020-06-18 19:44:06 +0000514func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
515 aaptFlags := []string{"--rename-manifest-package " + packageName}
516 if renameResourcesPackage {
517 // Required to rename the package name in the resources table.
518 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
519 }
520 return aaptFlags
521}
522
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900523func (a *AndroidApp) OverriddenManifestPackageName() string {
524 return a.overriddenManifestPackageName
525}
526
Liz Kammer9f9fd022020-06-18 19:44:06 +0000527func (a *AndroidApp) renameResourcesPackage() bool {
528 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
529}
530
Jihoon Kang9049c272024-03-19 21:57:36 +0000531func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000532 ctx.VisitDirectDeps(func(dep android.Module) {
533 tag := ctx.OtherModuleDependencyTag(dep)
534 switch tag {
535 case staticLibTag:
536 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
537 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
538 }
539
540 case aconfigDeclarationTag:
541 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
542 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
543 } else {
544 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
545 "flags_packages property, but %s is not aconfig_declarations module type",
546 dep.Name(),
547 )
548 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000549 }
550 })
551
Jihoon Kang9aef7772024-06-14 23:45:06 +0000552 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000553}
554
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800555func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900556 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900557 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900558 usePlatformAPI = true
559 }
560 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000561
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700562 // Ask manifest_fixer to add or update the application element indicating this app has no code.
563 a.aapt.hasNoCode = !a.hasCode(ctx)
564
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800565 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800566
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800567 // 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 +0900568 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800569 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900570 characteristics := ctx.Config().ProductAAPTCharacteristics()
571 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
572 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700573 }
574
Dan Willemsen72be5902018-10-24 20:24:57 -0700575 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
576 // Product AAPT config
577 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800578 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700579 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700580
Dan Willemsen72be5902018-10-24 20:24:57 -0700581 // Product AAPT preferred config
582 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800583 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700584 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700585 }
586
Jiyong Park7f67f482019-01-05 12:57:48 +0900587 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700588 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
589 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700590 // The product override variable has a priority over the package_name property.
591 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700592 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700593 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000594 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900595 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900596 }
597
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800598 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
599
Colin Crosse560c4a2019-03-19 16:03:11 -0700600 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800601 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100602 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000603 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
604 a.aapt.defaultManifestVersion = override
605 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000606 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000607 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100608 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000609
Rico Winda2fa2632024-03-13 13:09:17 +0100610 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200611 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000612
613 aconfigTextFilePaths := getAconfigFilePaths(ctx)
614
Alixf7a10272023-09-27 16:47:56 +0000615 a.aapt.buildActions(ctx,
616 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000617 sdkContext: android.SdkContext(a),
618 classLoaderContexts: a.classLoaderContexts,
619 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
620 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100621 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000622 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000623 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000624 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000625 },
626 )
Colin Cross30e076a2015-04-13 13:58:27 -0700627
Colin Cross46c9b8b2017-06-22 16:51:17 -0700628 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700629 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000630
631 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
632 AconfigTextFiles: aconfigTextFilePaths,
633 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800634}
Colin Cross30e076a2015-04-13 13:58:27 -0700635
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800636func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700637 var staticLibProguardFlagFiles android.Paths
638 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800639 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400640 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
641 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
642 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700643 }
644 })
645
646 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
647
Colin Cross312634e2023-11-21 15:13:56 -0800648 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200649 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100650 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
651 // live for code references and (transitively) mark these as live.
652 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
653 // dead code alive)
654 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
655 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800656}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800657
Colin Cross403cc152020-07-06 14:15:24 -0700658func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800659 var installDir string
660 if ctx.ModuleName() == "framework-res" {
661 // framework-res.apk is installed as system/framework/framework-res.apk
662 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900663 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800664 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800665 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800666 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800667 }
Colin Cross403cc152020-07-06 14:15:24 -0700668
669 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
670}
671
Rico Wind98e7fa82023-11-27 09:44:03 +0100672func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700673 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000674 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700675 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100676 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700677 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100678 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700679 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700680 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100681 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700682 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800683 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700684
Rico Wind98e7fa82023-11-27 09:44:03 +0100685 var packageResources = a.exportPackage
686
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800687 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200688 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100689 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
690 aapt2Convert(ctx, protoFile, packageResources, "proto")
691 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
692 }
693
Colin Cross4eae06d2023-06-20 22:40:02 -0700694 var extraSrcJars android.Paths
695 var extraClasspathJars android.Paths
696 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800697 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700698 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
699 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
700 // classpath when compiling everything else, and add it to the final classes jar.
701 extraClasspathJars = android.Paths{a.aapt.rJar}
702 extraCombinedJars = android.Paths{a.aapt.rJar}
703 } else {
704 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
705 // R.java files for the app's package and the packages from all transitive static android_library
706 // dependencies. Compile the srcjar alongside the rest of the sources.
707 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
708 }
709
Colin Crossfdaa6722024-08-23 11:58:08 -0700710 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200711 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100712 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
713 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
714 packageResources = binaryResources
715 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800716 }
Colin Cross30e076a2015-04-13 13:58:27 -0700717
Rico Wind98e7fa82023-11-27 09:44:03 +0100718 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800719}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800720
Sam Delmerico82602492022-06-10 17:05:42 +0000721func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700722 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000723 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700724 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700725 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700726 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800727 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000728 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700729 for _, jni := range jniLibs {
730 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700731 // Only collect coverage for the first target arch if this is a multilib target.
732 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
733 // data file path collisions since the current coverage file path format doesn't contain
734 // arch-related strings. This is fine for now though; the code coverage team doesn't use
735 // multi-arch targets such as test_suite_* for coverage collections yet.
736 //
737 // Work with the team to come up with a new format that handles multilib modules properly
738 // and change this.
739 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700740 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700741 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
742 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700743 }
744 }
Colin Cross403cc152020-07-06 14:15:24 -0700745 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700746 }
747 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800748 return jniJarFile
749}
Colin Crossa4f08812018-10-02 22:03:40 -0700750
Colin Cross403cc152020-07-06 14:15:24 -0700751func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
752 var jniSymbols android.RuleBuilderInstalls
753 for _, jniLib := range a.jniLibs {
754 if jniLib.unstrippedFile != nil {
755 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
756 From: jniLib.unstrippedFile,
757 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
758 })
759 }
760 }
761 return jniSymbols
762}
763
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700764// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
765// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700766func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
767 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700768 if android.SrcIsModule(certPropValue) == "" {
769 var mainCert Certificate
770 if certPropValue != "" {
771 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
772 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800773 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
774 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700775 }
776 } else {
777 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800778 mainCert = Certificate{
779 Pem: pem,
780 Key: key,
781 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700782 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700783 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700784 }
785
Colin Crossbc2c8a72022-09-14 12:45:42 -0700786 if len(certificates) > 0 {
787 mainCertificate = certificates[0]
788 } else {
789 // This can be reached with an empty certificate list if AllowMissingDependencies is set
790 // and the certificate property for this module is a module reference to a missing module.
791 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
792 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
793 }
794 // Set a certificate to avoid panics later when accessing it.
795 mainCertificate = Certificate{
796 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000797 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700798 }
799 }
800
Zyan Wub7550aa2023-05-18 15:46:31 +0800801 if !m.Platform() {
802 certPath := mainCertificate.Pem.String()
803 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
804 if strings.HasPrefix(certPath, systemCertPath) {
805 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
806 allowed := ctx.Config().EnforceSystemCertificateAllowList()
807
808 if enforceSystemCert && !inList(m.Name(), allowed) {
809 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
810 }
811 }
812 }
813
Colin Crossbc2c8a72022-09-14 12:45:42 -0700814 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800815}
816
Jooyung Han39ee1192020-03-23 20:21:11 +0900817func (a *AndroidApp) InstallApkName() string {
818 return a.installApkName
819}
820
Sam Delmerico15809f82023-05-15 17:21:47 -0400821func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000822 if a.appProperties.Privapp_allowlist == nil {
823 return nil
824 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400825
826 isOverrideApp := a.GetOverriddenBy() != ""
827 if !isOverrideApp {
828 // if this is not an override, we don't need to rewrite the existing privapp allowlist
829 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
830 }
831
Cole Faust258b96f2024-10-04 10:48:24 -0700832 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
833 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000834 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
835 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400836
Cole Faust258b96f2024-10-04 10:48:24 -0700837 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000838 fileName := "privapp_allowlist_" + packageName + ".xml"
839 outPath := android.PathForModuleOut(ctx, fileName).OutputPath
840 ctx.Build(pctx, android.BuildParams{
841 Rule: modifyAllowlist,
842 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
843 Output: outPath,
844 Args: map[string]string{
845 "packageName": packageName,
846 },
847 })
848 return &outPath
849}
850
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800851func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700852 var apkDeps android.Paths
853
Colin Crossff694a82023-12-13 15:54:49 -0800854 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
855 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700856 a.hideApexVariantFromMake = true
857 }
858
Jeongik Cha538c0d02019-07-11 15:54:27 +0900859 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
860 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
861
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000862 // Unlike installApkName, a.stem should respect base module name for override_android_app.
863 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000864 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000865
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800866 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000867 // Both android_app and override_android_app module are expected to possess
868 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
869 // from the base module. Therefore, use a.Name() which represents
870 // the module name for both android_app and override_android_app.
871 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000872 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800873
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700874 if ctx.ModuleName() == "framework-res" {
875 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700876 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900877 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700878 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
879 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800880 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700881 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700882 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700883 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700884 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700885
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100886 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000887 if a.usesLibrary.shouldDisableDexpreopt {
888 a.dexpreopter.disableDexpreopt()
889 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000890
Colin Cross61fb62e2022-06-23 10:46:28 -0700891 var noticeAssetPath android.WritablePath
892 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
893 // The rule to create the notice file can't be generated yet, as the final output path
894 // for the apk isn't known yet. Add the path where the notice file will be generated to the
895 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
896 // be generated later.
897 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
898 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
899 }
900
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000901 // For apps targeting latest target_sdk_version
902 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
903 a.SetEnforceDefaultTargetSdkVersion(true)
904 }
905
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800906 // Process all building blocks, from AAPT to certificates.
907 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100908 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700909 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100910
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100911 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700912 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000913 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
914 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700915 apkDeps = append(apkDeps, manifestCheckFile)
916 }
917
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800918 a.proguardBuildActions(ctx)
919
Colin Cross014489c2020-06-02 20:09:13 -0700920 a.linter.mergedManifest = a.aapt.mergedManifestFile
921 a.linter.manifest = a.aapt.manifestPath
922 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700923 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700924
Rico Wind98e7fa82023-11-27 09:44:03 +0100925 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800926
Jiyong Park92d84042024-05-17 22:58:54 +0000927 // No need to check the SDK version of the JNI deps unless we embed them
928 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
929 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000930 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800931
932 if ctx.Failed() {
933 return
934 }
935
Colin Crossbc2c8a72022-09-14 12:45:42 -0700936 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800937
938 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800939 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700940 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
941 var v4SignatureFile android.WritablePath = nil
942 if v4SigningRequested {
943 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
944 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700945 var lineageFile android.Path
946 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
947 lineageFile = android.PathForModuleSrc(ctx, lineage)
948 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400949 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
950
Rico Wind98e7fa82023-11-27 09:44:03 +0100951 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800952 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700953 if v4SigningRequested {
954 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
955 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800956
Colin Cross61fb62e2022-06-23 10:46:28 -0700957 if a.aapt.noticeFile.Valid() {
958 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -0700959 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -0700960 android.BuildNoticeHtmlOutputFromLicenseMetadata(
961 ctx, noticeFile, "", "",
962 []string{
963 a.installDir.String() + "/",
964 android.PathForModuleInstall(ctx).String() + "/",
965 a.outputFile.String(),
966 })
Bob Badoureef4c1c2022-05-16 12:20:04 -0700967 builder := android.NewRuleBuilder(pctx, ctx)
968 builder.Command().Text("cp").
969 Input(noticeFile).
970 Output(noticeAssetPath)
971 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -0700972 }
973
Colin Crosse560c4a2019-03-19 16:03:11 -0700974 for _, split := range a.aapt.splits {
975 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -0800976 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700977 if v4SigningRequested {
978 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
979 }
Rico Wind98e7fa82023-11-27 09:44:03 +0100980 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -0700981 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -0700982 if v4SigningRequested {
983 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
984 }
Colin Crosse560c4a2019-03-19 16:03:11 -0700985 }
986
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800987 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -0700988 bundleFile := android.PathForModuleOut(ctx, "base.zip")
989 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
990 a.bundleFile = bundleFile
991
Andrei Onea580636b2022-08-17 16:53:46 +0000992 allowlist := a.createPrivappAllowlist(ctx)
993 if allowlist != nil {
994 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
995 }
996
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800997 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +0000998 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
999 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001000 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001001 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1002 allowlistInstallFilename := a.installApkName + ".xml"
1003 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001004 }
1005
Colin Cross09ad3a62023-11-15 12:29:33 -08001006 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001007 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001008 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1009 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001010 }
Jiyong Park25b92222024-05-17 22:58:54 +00001011 // If we don't embed jni libs, make sure that those are installed along with the
1012 // app, and also place symlinks to the installed paths under the lib/<arch>
1013 // directory of the app installation directory. ex:
1014 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1015 if !a.embeddedJniLibs {
1016 for _, jniLib := range jniLibs {
1017 archStr := jniLib.target.Arch.ArchType.String()
1018 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1019 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001020 // install the symlink itself
1021 symlinkName := installedLib.Base()
1022 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1023 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1024 }
1025 }
1026 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001027 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001028 }
Artur Satayev1111b842020-04-27 19:05:28 +01001029
Colin Crossa6182ab2024-08-21 10:47:44 -07001030 ctx.CheckbuildFile(a.outputFile)
1031
Artur Satayev1111b842020-04-27 19:05:28 +01001032 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001033
1034 providePrebuiltInfo(ctx,
1035 prebuiltInfoProps{
1036 baseModuleName: a.BaseModuleName(),
1037 isPrebuilt: false,
1038 },
1039 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001040
1041 a.setOutputFiles(ctx)
1042}
1043
1044func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1045 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1046 if a.aaptSrcJar != nil {
1047 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1048 }
1049 if a.rJar != nil {
1050 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1051 }
1052 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1053 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1054 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1055 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001056}
1057
Colin Crossc2d24052020-05-13 11:05:02 -07001058type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001059 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001060 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001061 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1062}
1063
1064func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1065 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001066 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001067
Colin Crossc2d24052020-05-13 11:05:02 -07001068 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001069 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1070 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001071 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001072 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1073 checkNativeSdkVersion, func(dep cc.LinkableInterface) bool {
1074 return !dep.IsNdk(ctx.Config()) && !dep.IsStubs()
1075 })
1076
1077 var certificates []Certificate
1078
1079 ctx.VisitDirectDeps(func(module android.Module) {
1080 otherName := ctx.OtherModuleName(module)
1081 tag := ctx.OtherModuleDependencyTag(module)
1082
1083 if tag == certificateTag {
1084 if dep, ok := module.(*AndroidAppCertificate); ok {
1085 certificates = append(certificates, dep.Certificate)
1086 } else {
1087 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1088 }
1089 }
1090 })
1091 return jniLib, prebuiltJniPackages, certificates
1092}
1093
1094func collectJniDeps(ctx android.ModuleContext,
1095 shouldCollectRecursiveNativeDeps bool,
1096 checkNativeSdkVersion bool,
1097 filter func(cc.LinkableInterface) bool) ([]jniLib, android.Paths) {
1098 var jniLibs []jniLib
1099 var prebuiltJniPackages android.Paths
1100 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001101
Peter Collingbournead84f972019-12-17 16:46:18 -08001102 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001103 otherName := ctx.OtherModuleName(module)
1104 tag := ctx.OtherModuleDependencyTag(module)
1105
Colin Crossf0913fb2020-07-29 12:59:39 -07001106 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001107 if dep, ok := module.(cc.LinkableInterface); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001108 if filter != nil && !filter(dep) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001109 return false
1110 }
1111
Colin Crossa4f08812018-10-02 22:03:40 -07001112 lib := dep.OutputFile()
1113 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001114 path := lib.Path()
1115 if seenModulePaths[path.String()] {
1116 return false
1117 }
1118 seenModulePaths[path.String()] = true
1119
1120 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1121 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1122 otherName)
1123 }
1124
Colin Crossa4f08812018-10-02 22:03:40 -07001125 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001126 name: ctx.OtherModuleName(module),
1127 path: path,
1128 target: module.Target(),
1129 coverageFile: dep.CoverageOutputFile(),
1130 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001131 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001132 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001133 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001134 } else if ctx.Config().AllowMissingDependencies() {
1135 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001136 } else {
1137 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1138 }
1139 } else {
1140 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001141 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001142
1143 return shouldCollectRecursiveNativeDeps
1144 }
1145
Colin Cross313aa542023-12-13 13:47:44 -08001146 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001147 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1148 }
1149
Peter Collingbournead84f972019-12-17 16:46:18 -08001150 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001151 })
1152
Makoto Onuki2ca84272024-02-10 00:15:21 +00001153 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001154}
1155
Colin Cross8bf14fc2024-09-25 16:41:31 -07001156func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001157 ctx.WalkDeps(func(child, parent android.Module) bool {
1158 isExternal := !a.DepIsInSameApex(ctx, child)
1159 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001160 if !do(ctx, parent, am, isExternal) {
1161 return false
1162 }
Artur Satayev1111b842020-04-27 19:05:28 +01001163 }
1164 return !isExternal
1165 })
1166}
1167
1168func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1169 if ctx.Host() {
1170 return
1171 }
1172
1173 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross8bf14fc2024-09-25 16:41:31 -07001174 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001175 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001176
1177 // Skip dependencies that are only available to APEXes; they are developed with updatability
1178 // in mind and don't need manual approval.
1179 if to.(android.ApexModule).NotAvailableForPlatform() {
1180 return true
1181 }
1182
Artur Satayev1111b842020-04-27 19:05:28 +01001183 if info, exist := depsInfo[depName]; exist {
1184 info.From = append(info.From, from.Name())
1185 info.IsExternal = info.IsExternal && externalDep
1186 depsInfo[depName] = info
1187 } else {
1188 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001189 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001190 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001191 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001192 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1193 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001194 }
Jiyong Park92315372021-04-02 08:45:46 +09001195 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1196 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1197 // string
1198 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001199 toMinSdkVersion = v
1200 }
Artur Satayev1111b842020-04-27 19:05:28 +01001201 }
1202 depsInfo[depName] = android.ApexModuleDepInfo{
1203 To: depName,
1204 From: []string{from.Name()},
1205 IsExternal: externalDep,
1206 MinSdkVersion: toMinSdkVersion,
1207 }
1208 }
Jooyung Han749dc692020-04-15 11:03:39 +09001209 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001210 })
1211
Jiyong Park92315372021-04-02 08:45:46 +09001212 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001213}
1214
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001215func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1216 return a.appProperties.EnforceDefaultTargetSdkVersion
1217}
1218
1219func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1220 a.appProperties.EnforceDefaultTargetSdkVersion = val
1221}
1222
Artur Satayev849f8442020-04-28 14:57:42 +01001223func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001224 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001225}
1226
Colin Cross0ea8ba82019-06-06 14:33:29 -07001227func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001228 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1229 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001230 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001231 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001232 return String(a.overridableAppProperties.Certificate)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001233}
1234
Jiyong Park0f80c182020-01-31 02:49:53 +09001235func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1236 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1237 return true
1238 }
1239 return a.Library.DepIsInSameApex(ctx, dep)
1240}
1241
Jiyong Parkf7487312019-10-17 12:54:30 +09001242func (a *AndroidApp) Privileged() bool {
1243 return Bool(a.appProperties.Privileged)
1244}
1245
Colin Crosse1a85552024-06-14 12:17:37 -07001246func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001247 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001248}
1249
Ivan Lozanod7586b62021-04-01 09:49:36 -04001250func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001251 a.appProperties.PreventInstall = true
1252}
1253
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001254func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1255 a.appProperties.IsCoverageVariant = coverage
1256}
1257
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001258func (a *AndroidApp) EnableCoverageIfNeeded() {}
1259
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001260var _ cc.Coverage = (*AndroidApp)(nil)
1261
Cole Faustb36d31d2024-08-27 16:04:28 -07001262func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1263 a.Library.IDEInfo(ctx, dpInfo)
1264 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001265}
1266
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001267func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1268 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1269}
1270
1271func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1272 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1273}
1274
Colin Cross1b16b0e2019-02-12 14:41:32 -08001275// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001276func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001277 module := &AndroidApp{}
1278
Liz Kammera7a64f32020-07-09 15:16:41 -07001279 module.Module.dexProperties.Optimize.EnabledByDefault = true
1280 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001281 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001282
Colin Crossae5caf52018-05-22 11:11:52 -07001283 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001284 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001285 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001286
Colin Crossce6734e2020-06-15 16:09:53 -07001287 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001288 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001289 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001290 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001291 &module.overridableAppProperties,
1292 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001293
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001294 module.usesLibrary.enforce = true
1295
Colin Crossa4f08812018-10-02 22:03:40 -07001296 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1297 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001298 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001299 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001300
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001301 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1302 a := ctx.Module().(*AndroidApp)
1303
1304 characteristics := ctx.Config().ProductAAPTCharacteristics()
1305 if characteristics == "default" || characteristics == "" {
1306 module.appProperties.Generate_product_characteristics_rro = nil
1307 // no need to create RRO
1308 return
1309 }
1310
1311 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1312 return
1313 }
1314
1315 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1316 rroManifestName := rroPackageName + "_manifest"
1317
1318 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1319 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1320
1321 rroManifestProperties := struct {
1322 Name *string
1323 Tools []string
1324 Out []string
1325 Srcs []string
1326 Cmd *string
1327 }{
1328 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001329 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001330 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001331 Srcs: []string{":" + a.Name() + "{.apk}"},
1332 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001333 }
Cole Fauste19d3352024-10-17 10:30:57 -07001334 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001335
1336 rroProperties := struct {
1337 Name *string
1338 Filter_product *string
1339 Aaptflags []string
1340 Manifest *string
1341 Resource_dirs []string
Jihoon Kangf62f4222024-10-21 23:06:41 +00001342 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001343 }{
1344 Name: proptools.StringPtr(rroPackageName),
1345 Filter_product: proptools.StringPtr(characteristics),
1346 Aaptflags: []string{"--auto-add-overlay"},
1347 Manifest: proptools.StringPtr(":" + rroManifestName),
1348 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001349 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001350 }
优秀d75e9982024-05-09 07:15:55 +00001351 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1352 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1353 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1354 }
1355 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001356 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1357 })
1358
Colin Cross36242852017-06-23 15:06:31 -07001359 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001360}
Colin Crossae5caf52018-05-22 11:11:52 -07001361
Alix96ea88452023-08-31 15:48:23 +00001362// A dictionary of values to be overridden in the manifest.
1363type Manifest_values struct {
1364 // Overrides the value of package_name in the manifest
1365 ApplicationId *string
1366}
1367
Colin Crossae5caf52018-05-22 11:11:52 -07001368type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001369 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001370 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001371
Seth Moorec6f4b532023-02-02 13:22:26 -08001372 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001373 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001374
1375 // If specified, the mainline module package name in the test config is overwritten by it.
1376 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001377
1378 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001379}
1380
1381type AndroidTest struct {
1382 AndroidApp
1383
1384 appTestProperties appTestProperties
1385
1386 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001387
Dan Shi95d19422020-08-15 12:24:26 -07001388 testConfig android.Path
1389 extraTestConfigs android.Paths
1390 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001391}
1392
Jaewoong Jung0949f312019-09-11 10:25:18 -07001393func (a *AndroidTest) InstallInTestcases() bool {
1394 return true
1395}
1396
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001397type androidTestApp interface {
1398 includedInTestSuite(searchPrefix string) bool
1399}
1400
1401func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1402 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1403}
1404
1405func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1406 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1407}
1408
Colin Crossae5caf52018-05-22 11:11:52 -07001409func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001410 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001411 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001412 if a.appTestProperties.Instrumentation_target_package != nil {
1413 a.additionalAaptFlags = append(a.additionalAaptFlags,
1414 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1415 } else if a.appTestProperties.Instrumentation_for != nil {
1416 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001417 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1418 if overridden {
1419 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1420 }
1421 }
Alix96ea88452023-08-31 15:48:23 +00001422 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1423 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001424 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1425 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001426 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1427 }
1428 a.aapt.manifestValues.applicationId = *applicationId
1429 }
Colin Crossae5caf52018-05-22 11:11:52 -07001430 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001431
easoncylee5bcff5d2020-04-30 14:57:06 +08001432 for _, module := range a.testProperties.Test_mainline_modules {
1433 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1434 }
1435
Jaewoong Jung39982342020-01-14 10:27:18 -08001436 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001437 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1438 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001439 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001440 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001441 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001442 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1443 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001444 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Ronald Braunstein45dca5c2024-10-22 01:41:20 +00001445
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001446 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunstein45dca5c2024-10-22 01:41:20 +00001447 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001448 OutputFile: a.OutputFile(),
1449 TestConfig: a.testConfig,
1450 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001451 TestSuites: a.testProperties.Test_suites,
1452 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001453 LocalCertificate: a.certificate.AndroidMkString(),
1454 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunstein45dca5c2024-10-22 01:41:20 +00001455 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1456 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001457 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001458 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1459 TestOnly: true,
1460 TopLevelTarget: true,
1461 })
1462
Colin Cross303e21f2018-08-07 16:49:25 -07001463}
1464
Ronald Braunstein45dca5c2024-10-22 01:41:20 +00001465func testcaseRel(paths android.Paths) []string {
1466 relPaths := []string{}
1467 for _, p := range paths {
1468 relPaths = append(relPaths, p.Rel())
1469 }
1470 return relPaths
1471}
1472
Jaewoong Jung39982342020-01-14 10:27:18 -08001473func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1474 if testConfig == nil {
1475 return nil
1476 }
1477
1478 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001479 rule := android.NewRuleBuilder(pctx, ctx)
1480 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001481 fixNeeded := false
1482
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001483 // 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 -08001484 if ctx.ModuleName() != a.installApkName {
1485 fixNeeded = true
1486 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1487 }
1488
Cole Faust258b96f2024-10-04 10:48:24 -07001489 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1490 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001491 fixNeeded = true
1492 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001493 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001494 }
1495
Seth Moorec6f4b532023-02-02 13:22:26 -08001496 if a.appTestProperties.Mainline_package_name != nil {
1497 fixNeeded = true
1498 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1499 }
1500
Jaewoong Jung39982342020-01-14 10:27:18 -08001501 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001502 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001503 return fixedConfig
1504 }
1505 return testConfig
1506}
1507
Yihan Dong8be09c22024-08-29 15:32:13 +08001508func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1509 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1510 // Instrument the android_test_helper target to log potential API calls at the run time.
1511 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1512 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1513 a.setApiMapper(true)
1514 }
1515 a.AndroidApp.DepsMutator(ctx)
1516}
1517
Colin Cross303e21f2018-08-07 16:49:25 -07001518func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001519 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1520 // Instrument the android_test_helper target to log potential API calls at the run time.
1521 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1522 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1523 a.setApiMapper(true)
1524 }
Colin Cross303e21f2018-08-07 16:49:25 -07001525 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001526}
1527
1528func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1529 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001530 if a.appTestProperties.Instrumentation_for != nil {
1531 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1532 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1533 // use instrumentationForTag instead of libTag.
1534 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1535 }
Colin Crossae5caf52018-05-22 11:11:52 -07001536}
1537
Colin Cross1b16b0e2019-02-12 14:41:32 -08001538// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1539// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001540func AndroidTestFactory() android.Module {
1541 module := &AndroidTest{}
1542
Jared Duke63a3da92022-06-02 19:11:14 +00001543 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001544
1545 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001546 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001547 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001548 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1549 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001550 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001551 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001552
Colin Crossce6734e2020-06-15 16:09:53 -07001553 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001554 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001555 &module.aaptProperties,
1556 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001557 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001558 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001559 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001560
Colin Crossa4f08812018-10-02 22:03:40 -07001561 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1562 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001563 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001564
Colin Crossae5caf52018-05-22 11:11:52 -07001565 return module
1566}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001567
Colin Cross252fc6f2018-10-04 15:22:03 -07001568type appTestHelperAppProperties struct {
1569 // list of compatibility suites (for example "cts", "vts") that the module should be
1570 // installed into.
1571 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001572
1573 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1574 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1575 // explicitly.
1576 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001577
1578 // Install the test into a folder named for the module in all test suites.
1579 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001580
1581 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001582}
1583
1584type AndroidTestHelperApp struct {
1585 AndroidApp
1586
1587 appTestHelperAppProperties appTestHelperAppProperties
1588}
1589
Jaewoong Jung326a9412019-11-21 10:41:00 -08001590func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1591 return true
1592}
1593
Colin Cross1b16b0e2019-02-12 14:41:32 -08001594// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1595// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1596// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001597func AndroidTestHelperAppFactory() android.Module {
1598 module := &AndroidTestHelperApp{}
1599
Jared Duke63a3da92022-06-02 19:11:14 +00001600 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001601 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001602
1603 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001604 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1605 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001606 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001607 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001608
Colin Crossce6734e2020-06-15 16:09:53 -07001609 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001610 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001611 &module.aaptProperties,
1612 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001613 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001614 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001615
1616 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1617 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001618 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001619 return module
1620}
1621
Colin Crossbd01e2a2018-10-04 15:21:03 -07001622type AndroidAppCertificate struct {
1623 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001624
Colin Crossbd01e2a2018-10-04 15:21:03 -07001625 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001626 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001627}
1628
1629type AndroidAppCertificateProperties struct {
1630 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1631 Certificate *string
1632}
1633
Colin Cross1b16b0e2019-02-12 14:41:32 -08001634// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1635// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001636func AndroidAppCertificateFactory() android.Module {
1637 module := &AndroidAppCertificate{}
1638 module.AddProperties(&module.properties)
1639 android.InitAndroidModule(module)
1640 return module
1641}
1642
Colin Crossbd01e2a2018-10-04 15:21:03 -07001643func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1644 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001645 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001646 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1647 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001648 }
1649}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001650
1651type OverrideAndroidApp struct {
1652 android.ModuleBase
1653 android.OverrideModuleBase
1654}
1655
Sasha Smundak613cbb12020-06-05 10:27:23 -07001656func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001657 // All the overrides happen in the base module.
1658 // TODO(jungjw): Check the base module type.
1659}
1660
1661// override_android_app is used to create an android_app module based on another android_app by overriding
1662// some of its properties.
1663func OverrideAndroidAppModuleFactory() android.Module {
1664 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001665 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001666 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001667 &overridableAppProperties{},
1668 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001669
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001670 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001671 android.InitOverrideModule(m)
1672 return m
1673}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001674
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001675type OverrideAndroidTest struct {
1676 android.ModuleBase
1677 android.OverrideModuleBase
1678}
1679
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001680func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001681 // All the overrides happen in the base module.
1682 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001683 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1684 TestOnly: true,
1685 TopLevelTarget: true,
1686 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001687}
1688
1689// override_android_test is used to create an android_app module based on another android_test by overriding
1690// some of its properties.
1691func OverrideAndroidTestModuleFactory() android.Module {
1692 m := &OverrideAndroidTest{}
1693 m.AddProperties(&overridableAppProperties{})
1694 m.AddProperties(&appTestProperties{})
1695
1696 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1697 android.InitOverrideModule(m)
1698 return m
1699}
1700
Colin Cross50ddcc42019-05-16 12:28:22 -07001701type UsesLibraryProperties struct {
1702 // 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 -07001703 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001704
1705 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1706 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001707 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001708
1709 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1710 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1711 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001712
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001713 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1714 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1715 // normally is the same as the module name, but there are exceptions.
1716 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001717
1718 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1719 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1720 // added to the APK's manifest's <uses-library> elements.
1721 //
1722 // Care must be taken when using this as it could result in runtime errors if the APK actually
1723 // uses classes provided by the library and which are not provided in any other way.
1724 //
1725 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1726 // android.test.base shared library (and related libraries) but which depend on some common
1727 // libraries that depend on the android.test.base library. Without this those tests will end up
1728 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1729 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1730 // test altogether by providing access to classes that the tests were not expecting. Those tests
1731 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1732 // with the classes provided by the android.test.base library.
1733 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001734
1735 // The module names of optional uses-library libraries that are missing from the source tree.
1736 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001737}
1738
1739// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1740// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1741// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1742// with knowledge of their shared libraries.
1743type usesLibrary struct {
1744 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001745
1746 // Whether to enforce verify_uses_library check.
1747 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001748
1749 // Whether dexpreopt should be disabled
1750 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001751}
1752
Colin Cross4a80a152022-12-21 21:51:52 -08001753func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001754 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07001755 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001756 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1757 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001758 // Only add these extra dependencies if the module is an app that depends on framework
1759 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001760 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001761 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001762 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1763 // class loader context for dex2oat. Add them as a dependency with a special tag.
1764 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1765 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1766 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001767 }
Cole Faust64f2d842024-10-17 13:28:34 -07001768 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001769 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001770 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07001771 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001772 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001773 }
1774}
1775
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001776// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001777func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07001778 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001779 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001780 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001781 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1782 }
1783 return exists
1784 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001785 return optionalUsesLibs
1786}
1787
Ulya Trafimovich24446712021-07-15 14:59:34 +01001788// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1789// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001790func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1791 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001792
1793 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1794 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1795 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1796 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001797 }
1798
Ulya Trafimovich24446712021-07-15 14:59:34 +01001799 ctx.VisitDirectDeps(func(m android.Module) {
1800 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1801 if !isUsesLibTag {
1802 return
1803 }
1804
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001805 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001806
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001807 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1808 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1809 // from implementation libraries by their name, which is different as it has a suffix.
1810 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1811 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1812 return
1813 }
1814 }
1815
Ulya Trafimovich24446712021-07-15 14:59:34 +01001816 if lib, ok := m.(UsesLibraryDependency); ok {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001817 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1818 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1819 // This will be restricted to optional_uses_libs
1820 if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
1821 u.shouldDisableDexpreopt = true
1822 return
1823 }
1824 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001825 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001826 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001827 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001828 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001829 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001830 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001831 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001832 } else if ctx.Config().AllowMissingDependencies() {
1833 ctx.AddMissingDependencies([]string{dep})
1834 } else {
1835 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1836 }
1837 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001838 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001839}
1840
1841// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1842// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1843// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07001844func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
1845 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
1846 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001847 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001848}
1849
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001850// 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 -07001851func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
1852 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001853 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1854}
1855
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001856// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1857// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1858// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1859// extension: APKs are supposed to end with '.apk').
1860func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001861 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001862
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001863 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001864
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001865 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1866 // check is not necessary, and although it is good to have, it is difficult to maintain on
1867 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1868 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001869 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001870 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001871 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001872 }
1873
Colin Crossf1a035e2020-11-16 17:32:30 -08001874 rule := android.NewRuleBuilder(pctx, ctx)
1875 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001876 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001877 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001878 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001879 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001880
1881 if outputFile != nil {
1882 cmd.FlagWithOutput("-o ", outputFile)
1883 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001884
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001885 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1886 cmd.Flag("--enforce-uses-libraries-relax")
1887 }
1888
Jiakai Zhangf98da192024-04-15 11:15:41 +00001889 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1890 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001891 cmd.FlagWithArg("--uses-library ", lib)
1892 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001893 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001894 cmd.FlagWithArg("--optional-uses-library ", lib)
1895 }
1896
Jiakai Zhangf98da192024-04-15 11:15:41 +00001897 // Also add missing optional uses libs, as the manifest check expects them.
1898 // Note that what we add here are the module names of those missing libs, not library names, while
1899 // the manifest check actually expects library names. However, the case where a library is missing
1900 // and the module name != the library name is too rare for us to handle.
1901 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1902 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1903 }
1904
Colin Crossf1a035e2020-11-16 17:32:30 -08001905 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001906 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001907}
Colin Cross50ddcc42019-05-16 12:28:22 -07001908
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001909// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1910// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001911func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1912 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001913 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001914 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001915}
1916
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001917// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1918// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001919func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1920 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1921 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001922}