blob: 69fdc4772f7577fe7a834552eace04b09364b5f2 [file] [log] [blame]
Colin Cross30e076a2015-04-13 13:58:27 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
Jaewoong Jungf9b44652020-12-21 12:29:12 -080017// This file contains the module implementations for android_app, android_test, and some more
18// related module types, including their override variants.
Colin Cross30e076a2015-04-13 13:58:27 -070019
20import (
Jiakai Zhang4f65a032023-06-01 15:16:58 +010021 "fmt"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070022 "path/filepath"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070023 "strings"
Colin Cross30e076a2015-04-13 13:58:27 -070024
Aditya Choudhary9b593522023-10-06 19:54:58 +000025 "android/soong/testing"
Jihoon Kang84b25892023-12-01 22:01:06 +000026
Colin Cross50ddcc42019-05-16 12:28:22 -070027 "github.com/google/blueprint"
28 "github.com/google/blueprint/proptools"
29
Colin Cross635c3b02016-05-18 15:37:25 -070030 "android/soong/android"
Colin Crossa4f08812018-10-02 22:03:40 -070031 "android/soong/cc"
Ulya Trafimovichd4bcea42020-06-03 14:57:22 +010032 "android/soong/dexpreopt"
Colin Cross303e21f2018-08-07 16:49:25 -070033 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070034)
35
Colin Cross3bc7ffa2017-11-22 16:19:37 -080036func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000037 RegisterAppBuildComponents(android.InitRegistrationContext)
Andrei Onea580636b2022-08-17 16:53:46 +000038 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080039}
40
Andrei Onea580636b2022-08-17 16:53:46 +000041var (
42 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
43 blueprint.RuleParams{
44 Command: "${ModifyAllowlistCmd} $in $packageName $out",
45 CommandDeps: []string{"${ModifyAllowlistCmd}"},
46 }, "packageName")
47)
48
Jihoon Kang9aef7772024-06-14 23:45:06 +000049type FlagsPackages struct {
50 // Paths to the aconfig dump output text files that are consumed by aapt2
51 AconfigTextFiles android.Paths
52}
53
54var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
55
Paul Duffinf9b1da02019-12-18 19:51:55 +000056func RegisterAppBuildComponents(ctx android.RegistrationContext) {
57 ctx.RegisterModuleType("android_app", AndroidAppFactory)
58 ctx.RegisterModuleType("android_test", AndroidTestFactory)
59 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
60 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
61 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
62 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000063}
64
Colin Cross99939e92024-10-01 16:02:46 -070065type AppInfo struct {
66 // Updatable is set to the value of the updatable property
67 Updatable bool
68
69 // TestHelperApp is true if the module is a android_test_helper_app
70 TestHelperApp bool
71}
72
73var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
74
Colin Cross30e076a2015-04-13 13:58:27 -070075// AndroidManifest.xml merging
76// package splits
77
Colin Crossfabb6082018-02-20 17:22:23 -080078type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070079 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070080 Additional_certificates []string
81
82 // If set, create package-export.apk, which other packages can
83 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080084 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070085
Colin Cross16056062017-12-13 22:46:28 -080086 // Specifies that this app should be installed to the priv-app directory,
87 // where the system will grant it additional privileges not available to
88 // normal apps.
89 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070090
91 // list of resource labels to generate individual resource packages
92 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040093
Colin Crossa4f08812018-10-02 22:03:40 -070094 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +000095 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -070096
Colin Cross7204cf02020-05-06 17:51:39 -070097 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -080098 // sdk_version.
99 Jni_uses_platform_apis *bool
100
Colin Cross7204cf02020-05-06 17:51:39 -0700101 // if true, use JNI libraries that link against SDK APIs even if this module does not set
102 // sdk_version.
103 Jni_uses_sdk_apis *bool
104
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700105 // STL library to use for JNI libraries.
106 Stl *string `android:"arch_variant"`
107
Colin Crosse4246ab2019-02-05 21:55:21 -0800108 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900109 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
110 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
111 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
112 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800113 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800114
115 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
116 // they are used from inside the APK at runtime.
117 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700118
Jiyong Parkd044bb42024-05-15 02:09:54 +0900119 // Forces native libraries to always be packaged into the APK,
120 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
121 // True for android_test* modules.
122 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700123
124 // If set, find and merge all NOTICE files that this module and its dependencies have and store
125 // it in the APK as an asset.
126 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700127
128 // cc.Coverage related properties
129 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700130 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100131
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000132 // It can be set to test the behaviour of default target sdk version.
133 // Only required when updatable: false. It is an error if updatable: true and this is false.
134 Enforce_default_target_sdk_version *bool
135
136 // If set, the targetSdkVersion for the target is set to the latest default API level.
137 // This would be by default false, unless updatable: true or
138 // enforce_default_target_sdk_version: true in which case this defaults to true.
139 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
140
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100141 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100142 // additional rules to make sure an app can safely be updated. Default is false.
143 // Prefer using other specific properties if build behaviour must be changed; avoid using this
144 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100145 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000146
147 // Specifies the file that contains the allowlist for this app.
148 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900149
150 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
151 // and install the RRO package to /product partition, instead of passing --product argument
152 // to aapt2. Default is false.
153 // Setting this will make this APK identical to all targets, regardless of
154 // PRODUCT_CHARACTERISTICS.
155 Generate_product_characteristics_rro *bool
156
157 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
158 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700159}
160
Jaewoong Jung525443a2019-02-28 15:35:54 -0800161// android_app properties that can be overridden by override_android_app
162type overridableAppProperties struct {
163 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
164 // or an android_app_certificate module name in the form ":module".
165 Certificate *string
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700166
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800167 // Name of the signing certificate lineage file or filegroup module.
168 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700169
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400170 // For overriding the --rotation-min-sdk-version property of apksig
171 RotationMinSdkVersion *string
172
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700173 // 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 -0700174 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800175
176 // the logging parent of this app.
177 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000178
179 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
180 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000181
182 // Names of modules to be overridden. Listed modules can only be other binaries
183 // (in Make or Soong).
184 // This does not completely prevent installation of the overridden binaries, but if both
185 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
186 // from PRODUCT_PACKAGES.
187 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800188}
189
Colin Cross30e076a2015-04-13 13:58:27 -0700190type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700191 Library
192 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800193 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700194
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900195 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700196
Colin Crossfabb6082018-02-20 17:22:23 -0800197 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700198
Jaewoong Jung525443a2019-02-28 15:35:54 -0800199 overridableAppProperties overridableAppProperties
200
Colin Cross403cc152020-07-06 14:15:24 -0700201 jniLibs []jniLib
202 installPathForJNISymbols android.Path
203 embeddedJniLibs bool
204 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700205
206 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800207
208 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
209 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800210
Colin Cross70dda7e2019-10-01 22:05:35 -0700211 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700212
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700213 onDeviceDir string
214
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800215 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700216
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900217 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100218
219 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000220
221 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000222
223 privAppAllowlist android.OptionalPath
Colin Crosse1731a52017-12-14 11:22:55 -0800224}
225
Martin Stjernholm6d415272020-01-31 17:10:36 +0000226func (a *AndroidApp) IsInstallable() bool {
227 return Bool(a.properties.Installable)
228}
229
Colin Crossab8d1382023-07-14 17:23:41 +0000230func (a *AndroidApp) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
231 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700232}
233
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900234func (a *AndroidApp) OutputFile() android.Path {
235 return a.outputFile
236}
237
Colin Cross503c1d02020-01-28 14:00:53 -0800238func (a *AndroidApp) Certificate() Certificate {
239 return a.certificate
240}
241
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700242func (a *AndroidApp) JniCoverageOutputs() android.Paths {
243 return a.jniCoverageOutputs
244}
245
Andrei Onea580636b2022-08-17 16:53:46 +0000246func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
247 return a.privAppAllowlist
248}
249
Colin Crossa97c5d32018-03-28 14:58:31 -0700250var _ AndroidLibraryDependency = (*AndroidApp)(nil)
251
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900252type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800253 Pem, Key android.Path
254 presigned bool
255}
256
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700257var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800258
259func (c Certificate) AndroidMkString() string {
260 if c.presigned {
261 return "PRESIGNED"
262 } else {
263 return c.Pem.String()
264 }
Colin Cross30e076a2015-04-13 13:58:27 -0700265}
266
Colin Cross46c9b8b2017-06-22 16:51:17 -0700267func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900268 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700269 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
270 }
271
Jiyong Parkf1691d22021-03-29 20:11:58 +0900272 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000273 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
274 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100275 if sdkDep.hasFrameworkLibs() {
276 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700277 }
Colin Crossa4f08812018-10-02 22:03:40 -0700278
Jiyong Park92315372021-04-02 08:45:46 +0900279 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700280
281 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
282 ctx.PropertyErrorf("jni_uses_sdk_apis",
283 "can only be set for modules that do not set sdk_version")
284 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
285 ctx.PropertyErrorf("jni_uses_platform_apis",
286 "can only be set for modules that set sdk_version")
287 }
288
Colin Crossa4f08812018-10-02 22:03:40 -0700289 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700290 variation := append(jniTarget.Variations(),
291 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000292
Jiyong Park92d84042024-05-17 22:58:54 +0000293 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
294 // Many factors are considered here.
295 // 1. Basically, the selection follows whether the app has sdk_version set or not.
296 jniUsesSdkVariant := usesSDK
297 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
298 if Bool(a.appProperties.Jni_uses_sdk_apis) {
299 jniUsesSdkVariant = true
300 }
301 if Bool(a.appProperties.Jni_uses_platform_apis) {
302 jniUsesSdkVariant = false
303 }
304 // 3. Then the use of SDK variant is again prohibited for the following cases:
305 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
306 // partition (not only the app) is considered unbudled, there's no need to use the
307 // SDK variant.
308 // 3.2. the app doesn't support embedding the JNI libs
309 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
310 jniUsesSdkVariant = false
311 }
312 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000313 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
314 }
Jiyong Park92d84042024-05-17 22:58:54 +0000315
316 // Use the installable dep tag when the JNIs are not embedded
317 var tag dependencyTag
318 if a.shouldEmbedJnis(ctx) {
319 tag = jniLibTag
320 } else {
321 tag = jniInstallTag
322 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000323 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700324 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000325 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
326 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
327 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700328}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700329
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700330func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800331 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700332 if cert != "" {
333 ctx.AddDependency(ctx.Module(), certificateTag, cert)
334 }
335
Andrei Onea580636b2022-08-17 16:53:46 +0000336 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000337 // There are a few uids that are explicitly considered privileged regardless of their
338 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
339 // but for now, allow it not to be in priv-app.
340 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
341 if !privilegedBecauseOfUid {
342 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
343 }
Andrei Onea580636b2022-08-17 16:53:46 +0000344 }
345
Colin Crossbd01e2a2018-10-04 15:21:03 -0700346 for _, cert := range a.appProperties.Additional_certificates {
347 cert = android.SrcIsModule(cert)
348 if cert != "" {
349 ctx.AddDependency(ctx.Module(), certificateTag, cert)
350 } else {
351 ctx.PropertyErrorf("additional_certificates",
352 `must be names of android_app_certificate modules in the form ":module"`)
353 }
354 }
Colin Cross30e076a2015-04-13 13:58:27 -0700355}
356
Spandan Dasb0410872024-06-25 03:30:03 +0000357// TODO(b/156476221): Remove this allowlist
358var (
359 missingMinSdkVersionMtsAllowlist = []string{
360 "CellBroadcastReceiverGoogleUnitTests",
361 "CellBroadcastReceiverUnitTests",
362 "CtsBatterySavingTestCases",
363 "CtsDeviceAndProfileOwnerApp23",
364 "CtsDeviceAndProfileOwnerApp30",
365 "CtsIntentSenderApp",
366 "CtsJobSchedulerTestCases",
367 "CtsMimeMapTestCases",
368 "CtsTareTestCases",
369 "LibStatsPullTests",
370 "MediaProviderClientTests",
371 "TeleServiceTests",
372 "TestExternalImsServiceApp",
373 "TestSmsRetrieverApp",
374 "TetheringPrivilegedTests",
375 }
376)
377
378func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
379 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
380 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
381 }
382}
383
Jeongik Cha538c0d02019-07-11 15:54:27 +0900384func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000385 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000386 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
387 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700388 packageName := a.overridableAppProperties.Package_name.Get(ctx)
389 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000390 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
391 }
392 a.aapt.manifestValues.applicationId = *applicationId
393 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900394 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700395 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
396 TestOnly: true,
397 })
Colin Cross99939e92024-10-01 16:02:46 -0700398 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
399 Updatable: Bool(a.appProperties.Updatable),
400 TestHelperApp: true,
401 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900402}
403
Colin Cross46c9b8b2017-06-22 16:51:17 -0700404func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100405 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000406 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700407 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000408 a.generateJavaUsedByApex(ctx)
Colin Cross99939e92024-10-01 16:02:46 -0700409 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
410 Updatable: Bool(a.appProperties.Updatable),
411 TestHelperApp: false,
412 })
Colin Crossae5caf52018-05-22 11:11:52 -0700413}
414
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100415func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100416 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900417 if !a.SdkVersion(ctx).Stable() {
418 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100419 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000420 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100421 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
422 }
Jooyung Han749dc692020-04-15 11:03:39 +0900423
Jiyong Park92315372021-04-02 08:45:46 +0900424 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900425 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000426 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900427 } else {
428 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
429 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000430
431 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
432 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
433 }
434 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
435 if a.deviceProperties.Target_sdk_version == nil {
436 a.SetEnforceDefaultTargetSdkVersion(true)
437 }
438 }
439
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100440 a.checkPlatformAPI(ctx)
441 a.checkSdkVersions(ctx)
442}
443
Jiyong Park970c5242024-05-17 22:58:54 +0000444// Ensures that use_embedded_native_libs are set for apk-in-apex
445func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
446 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
447 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000448 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000449
450 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
451 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
452 }
453}
454
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900455// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
456// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900457func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900458 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
459 ctx.VisitDirectDeps(func(m android.Module) {
460 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
461 return
462 }
463 dep, _ := m.(*cc.Module)
Jooyung Han652d5b32020-05-20 17:12:13 +0900464 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900465 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
466 // handled properly regardless of sdk finalization.
Spandan Das2e8c0442022-05-08 00:39:35 +0000467 jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900468 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Spandan Das2e8c0442022-05-08 00:39:35 +0000469 ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
470 dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900471 return
472 }
473
474 })
475}
476
Sasha Smundak6ad77252019-05-01 13:16:22 -0700477// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800478// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700479func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900480 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800481 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900482 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800483 }
484
Jiyong Parkd044bb42024-05-15 02:09:54 +0900485 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
486 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
487 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800488}
489
Colin Cross43f08db2018-11-12 10:13:39 -0800490// Returns whether this module should have the dex file stored uncompressed in the APK.
491func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800492 if Bool(a.appProperties.Use_embedded_dex) {
493 return true
494 }
495
Colin Cross53a87f52019-06-25 13:35:30 -0700496 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
497 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900498 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000499 return true
500 }
501
Colin Cross53a87f52019-06-25 13:35:30 -0700502 if ctx.Config().UnbundledBuild() {
503 return false
504 }
505
Spandan Dase21a8d42024-01-23 23:56:29 +0000506 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700507}
508
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700509func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900510 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000511 Bool(a.appProperties.Updatable) ||
512 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000513}
514
Liz Kammer9f9fd022020-06-18 19:44:06 +0000515func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
516 aaptFlags := []string{"--rename-manifest-package " + packageName}
517 if renameResourcesPackage {
518 // Required to rename the package name in the resources table.
519 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
520 }
521 return aaptFlags
522}
523
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900524func (a *AndroidApp) OverriddenManifestPackageName() string {
525 return a.overriddenManifestPackageName
526}
527
Liz Kammer9f9fd022020-06-18 19:44:06 +0000528func (a *AndroidApp) renameResourcesPackage() bool {
529 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
530}
531
Jihoon Kang9049c272024-03-19 21:57:36 +0000532func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000533 ctx.VisitDirectDeps(func(dep android.Module) {
534 tag := ctx.OtherModuleDependencyTag(dep)
535 switch tag {
536 case staticLibTag:
537 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
538 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
539 }
540
541 case aconfigDeclarationTag:
542 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
543 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
544 } else {
545 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
546 "flags_packages property, but %s is not aconfig_declarations module type",
547 dep.Name(),
548 )
549 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000550 }
551 })
552
Jihoon Kang9aef7772024-06-14 23:45:06 +0000553 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000554}
555
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800556func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900557 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900558 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900559 usePlatformAPI = true
560 }
561 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000562
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700563 // Ask manifest_fixer to add or update the application element indicating this app has no code.
564 a.aapt.hasNoCode = !a.hasCode(ctx)
565
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800566 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800567
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800568 // 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 +0900569 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800570 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900571 characteristics := ctx.Config().ProductAAPTCharacteristics()
572 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
573 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700574 }
575
Dan Willemsen72be5902018-10-24 20:24:57 -0700576 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
577 // Product AAPT config
578 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800579 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700580 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700581
Dan Willemsen72be5902018-10-24 20:24:57 -0700582 // Product AAPT preferred config
583 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800584 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700585 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700586 }
587
Jiyong Park7f67f482019-01-05 12:57:48 +0900588 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700589 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
590 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700591 // The product override variable has a priority over the package_name property.
592 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700593 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700594 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000595 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900596 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900597 }
598
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800599 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
600
Colin Crosse560c4a2019-03-19 16:03:11 -0700601 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800602 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100603 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000604 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
605 a.aapt.defaultManifestVersion = override
606 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000607 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000608 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100609 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000610
Rico Winda2fa2632024-03-13 13:09:17 +0100611 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200612 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000613
614 aconfigTextFilePaths := getAconfigFilePaths(ctx)
615
Alixf7a10272023-09-27 16:47:56 +0000616 a.aapt.buildActions(ctx,
617 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000618 sdkContext: android.SdkContext(a),
619 classLoaderContexts: a.classLoaderContexts,
620 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
621 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100622 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000623 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000624 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000625 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000626 },
627 )
Colin Cross30e076a2015-04-13 13:58:27 -0700628
Colin Cross46c9b8b2017-06-22 16:51:17 -0700629 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700630 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000631
632 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
633 AconfigTextFiles: aconfigTextFilePaths,
634 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800635}
Colin Cross30e076a2015-04-13 13:58:27 -0700636
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800637func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700638 var staticLibProguardFlagFiles android.Paths
639 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800640 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400641 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
642 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
643 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700644 }
645 })
646
647 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
648
Colin Cross312634e2023-11-21 15:13:56 -0800649 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200650 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100651 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
652 // live for code references and (transitively) mark these as live.
653 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
654 // dead code alive)
655 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
656 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800657}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800658
Colin Cross403cc152020-07-06 14:15:24 -0700659func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800660 var installDir string
661 if ctx.ModuleName() == "framework-res" {
662 // framework-res.apk is installed as system/framework/framework-res.apk
663 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900664 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800665 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800666 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800667 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800668 }
Colin Cross403cc152020-07-06 14:15:24 -0700669
670 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
671}
672
Rico Wind98e7fa82023-11-27 09:44:03 +0100673func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700674 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000675 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700676 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100677 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700678 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100679 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700680 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700681 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100682 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700683 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800684 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700685
Rico Wind98e7fa82023-11-27 09:44:03 +0100686 var packageResources = a.exportPackage
687
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800688 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200689 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100690 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
691 aapt2Convert(ctx, protoFile, packageResources, "proto")
692 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
693 }
694
Colin Cross4eae06d2023-06-20 22:40:02 -0700695 var extraSrcJars android.Paths
696 var extraClasspathJars android.Paths
697 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800698 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700699 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
700 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
701 // classpath when compiling everything else, and add it to the final classes jar.
702 extraClasspathJars = android.Paths{a.aapt.rJar}
703 extraCombinedJars = android.Paths{a.aapt.rJar}
704 } else {
705 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
706 // R.java files for the app's package and the packages from all transitive static android_library
707 // dependencies. Compile the srcjar alongside the rest of the sources.
708 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
709 }
710
Colin Crossfdaa6722024-08-23 11:58:08 -0700711 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200712 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100713 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
714 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
715 packageResources = binaryResources
716 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800717 }
Colin Cross30e076a2015-04-13 13:58:27 -0700718
Rico Wind98e7fa82023-11-27 09:44:03 +0100719 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800720}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800721
Sam Delmerico82602492022-06-10 17:05:42 +0000722func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700723 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000724 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700725 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700726 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700727 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800728 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000729 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700730 for _, jni := range jniLibs {
731 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700732 // Only collect coverage for the first target arch if this is a multilib target.
733 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
734 // data file path collisions since the current coverage file path format doesn't contain
735 // arch-related strings. This is fine for now though; the code coverage team doesn't use
736 // multi-arch targets such as test_suite_* for coverage collections yet.
737 //
738 // Work with the team to come up with a new format that handles multilib modules properly
739 // and change this.
740 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700741 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700742 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
743 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700744 }
745 }
Colin Cross403cc152020-07-06 14:15:24 -0700746 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700747 }
748 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800749 return jniJarFile
750}
Colin Crossa4f08812018-10-02 22:03:40 -0700751
Colin Cross403cc152020-07-06 14:15:24 -0700752func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
753 var jniSymbols android.RuleBuilderInstalls
754 for _, jniLib := range a.jniLibs {
755 if jniLib.unstrippedFile != nil {
756 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
757 From: jniLib.unstrippedFile,
758 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
759 })
760 }
761 }
762 return jniSymbols
763}
764
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700765// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
766// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700767func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
768 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700769 if android.SrcIsModule(certPropValue) == "" {
770 var mainCert Certificate
771 if certPropValue != "" {
772 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
773 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800774 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
775 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700776 }
777 } else {
778 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800779 mainCert = Certificate{
780 Pem: pem,
781 Key: key,
782 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700783 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700784 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700785 }
786
Colin Crossbc2c8a72022-09-14 12:45:42 -0700787 if len(certificates) > 0 {
788 mainCertificate = certificates[0]
789 } else {
790 // This can be reached with an empty certificate list if AllowMissingDependencies is set
791 // and the certificate property for this module is a module reference to a missing module.
792 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
793 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
794 }
795 // Set a certificate to avoid panics later when accessing it.
796 mainCertificate = Certificate{
797 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000798 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700799 }
800 }
801
Zyan Wub7550aa2023-05-18 15:46:31 +0800802 if !m.Platform() {
803 certPath := mainCertificate.Pem.String()
804 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
805 if strings.HasPrefix(certPath, systemCertPath) {
806 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
807 allowed := ctx.Config().EnforceSystemCertificateAllowList()
808
809 if enforceSystemCert && !inList(m.Name(), allowed) {
810 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
811 }
812 }
813 }
814
Colin Crossbc2c8a72022-09-14 12:45:42 -0700815 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800816}
817
Jooyung Han39ee1192020-03-23 20:21:11 +0900818func (a *AndroidApp) InstallApkName() string {
819 return a.installApkName
820}
821
Sam Delmerico15809f82023-05-15 17:21:47 -0400822func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000823 if a.appProperties.Privapp_allowlist == nil {
824 return nil
825 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400826
827 isOverrideApp := a.GetOverriddenBy() != ""
828 if !isOverrideApp {
829 // if this is not an override, we don't need to rewrite the existing privapp allowlist
830 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
831 }
832
Cole Faust258b96f2024-10-04 10:48:24 -0700833 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
834 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000835 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
836 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400837
Cole Faust258b96f2024-10-04 10:48:24 -0700838 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000839 fileName := "privapp_allowlist_" + packageName + ".xml"
840 outPath := android.PathForModuleOut(ctx, fileName).OutputPath
841 ctx.Build(pctx, android.BuildParams{
842 Rule: modifyAllowlist,
843 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
844 Output: outPath,
845 Args: map[string]string{
846 "packageName": packageName,
847 },
848 })
849 return &outPath
850}
851
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800852func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700853 var apkDeps android.Paths
854
Colin Crossff694a82023-12-13 15:54:49 -0800855 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
856 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700857 a.hideApexVariantFromMake = true
858 }
859
Jeongik Cha538c0d02019-07-11 15:54:27 +0900860 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
861 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
862
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000863 // Unlike installApkName, a.stem should respect base module name for override_android_app.
864 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000865 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000866
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800867 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000868 // Both android_app and override_android_app module are expected to possess
869 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
870 // from the base module. Therefore, use a.Name() which represents
871 // the module name for both android_app and override_android_app.
872 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000873 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800874
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700875 if ctx.ModuleName() == "framework-res" {
876 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700877 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900878 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700879 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
880 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800881 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700882 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700883 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700884 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700885 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700886
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100887 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000888 if a.usesLibrary.shouldDisableDexpreopt {
889 a.dexpreopter.disableDexpreopt()
890 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000891
Colin Cross61fb62e2022-06-23 10:46:28 -0700892 var noticeAssetPath android.WritablePath
893 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
894 // The rule to create the notice file can't be generated yet, as the final output path
895 // for the apk isn't known yet. Add the path where the notice file will be generated to the
896 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
897 // be generated later.
898 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
899 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
900 }
901
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000902 // For apps targeting latest target_sdk_version
903 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
904 a.SetEnforceDefaultTargetSdkVersion(true)
905 }
906
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800907 // Process all building blocks, from AAPT to certificates.
908 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100909 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700910 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100911
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100912 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700913 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000914 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
915 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700916 apkDeps = append(apkDeps, manifestCheckFile)
917 }
918
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800919 a.proguardBuildActions(ctx)
920
Colin Cross014489c2020-06-02 20:09:13 -0700921 a.linter.mergedManifest = a.aapt.mergedManifestFile
922 a.linter.manifest = a.aapt.manifestPath
923 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700924 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700925
Rico Wind98e7fa82023-11-27 09:44:03 +0100926 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800927
Jiyong Park92d84042024-05-17 22:58:54 +0000928 // No need to check the SDK version of the JNI deps unless we embed them
929 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
930 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000931 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800932
933 if ctx.Failed() {
934 return
935 }
936
Colin Crossbc2c8a72022-09-14 12:45:42 -0700937 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800938
939 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800940 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700941 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
942 var v4SignatureFile android.WritablePath = nil
943 if v4SigningRequested {
944 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
945 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700946 var lineageFile android.Path
947 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
948 lineageFile = android.PathForModuleSrc(ctx, lineage)
949 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400950 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
951
Rico Wind98e7fa82023-11-27 09:44:03 +0100952 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800953 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700954 if v4SigningRequested {
955 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
956 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800957
Colin Cross61fb62e2022-06-23 10:46:28 -0700958 if a.aapt.noticeFile.Valid() {
959 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -0700960 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -0700961 android.BuildNoticeHtmlOutputFromLicenseMetadata(
962 ctx, noticeFile, "", "",
963 []string{
964 a.installDir.String() + "/",
965 android.PathForModuleInstall(ctx).String() + "/",
966 a.outputFile.String(),
967 })
Bob Badoureef4c1c2022-05-16 12:20:04 -0700968 builder := android.NewRuleBuilder(pctx, ctx)
969 builder.Command().Text("cp").
970 Input(noticeFile).
971 Output(noticeAssetPath)
972 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -0700973 }
974
Colin Crosse560c4a2019-03-19 16:03:11 -0700975 for _, split := range a.aapt.splits {
976 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -0800977 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700978 if v4SigningRequested {
979 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
980 }
Rico Wind98e7fa82023-11-27 09:44:03 +0100981 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -0700982 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -0700983 if v4SigningRequested {
984 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
985 }
Colin Crosse560c4a2019-03-19 16:03:11 -0700986 }
987
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800988 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -0700989 bundleFile := android.PathForModuleOut(ctx, "base.zip")
990 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
991 a.bundleFile = bundleFile
992
Andrei Onea580636b2022-08-17 16:53:46 +0000993 allowlist := a.createPrivappAllowlist(ctx)
994 if allowlist != nil {
995 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
996 }
997
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800998 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +0000999 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1000 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001001 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001002 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1003 allowlistInstallFilename := a.installApkName + ".xml"
1004 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001005 }
1006
Colin Cross09ad3a62023-11-15 12:29:33 -08001007 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001008 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001009 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1010 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001011 }
Jiyong Park25b92222024-05-17 22:58:54 +00001012 // If we don't embed jni libs, make sure that those are installed along with the
1013 // app, and also place symlinks to the installed paths under the lib/<arch>
1014 // directory of the app installation directory. ex:
1015 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1016 if !a.embeddedJniLibs {
1017 for _, jniLib := range jniLibs {
1018 archStr := jniLib.target.Arch.ArchType.String()
1019 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1020 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001021 // install the symlink itself
1022 symlinkName := installedLib.Base()
1023 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1024 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1025 }
1026 }
1027 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001028 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001029 }
Artur Satayev1111b842020-04-27 19:05:28 +01001030
Colin Crossa6182ab2024-08-21 10:47:44 -07001031 ctx.CheckbuildFile(a.outputFile)
1032
Artur Satayev1111b842020-04-27 19:05:28 +01001033 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001034
1035 providePrebuiltInfo(ctx,
1036 prebuiltInfoProps{
1037 baseModuleName: a.BaseModuleName(),
1038 isPrebuilt: false,
1039 },
1040 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001041
1042 a.setOutputFiles(ctx)
1043}
1044
1045func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1046 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1047 if a.aaptSrcJar != nil {
1048 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1049 }
1050 if a.rJar != nil {
1051 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1052 }
1053 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1054 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1055 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1056 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001057}
1058
Colin Crossc2d24052020-05-13 11:05:02 -07001059type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001060 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001061 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001062 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1063}
1064
1065func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1066 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001067 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001068
Colin Crossc2d24052020-05-13 11:05:02 -07001069 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001070 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1071 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001072 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001073 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1074 checkNativeSdkVersion, func(dep cc.LinkableInterface) bool {
1075 return !dep.IsNdk(ctx.Config()) && !dep.IsStubs()
1076 })
1077
1078 var certificates []Certificate
1079
1080 ctx.VisitDirectDeps(func(module android.Module) {
1081 otherName := ctx.OtherModuleName(module)
1082 tag := ctx.OtherModuleDependencyTag(module)
1083
1084 if tag == certificateTag {
1085 if dep, ok := module.(*AndroidAppCertificate); ok {
1086 certificates = append(certificates, dep.Certificate)
1087 } else {
1088 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1089 }
1090 }
1091 })
1092 return jniLib, prebuiltJniPackages, certificates
1093}
1094
1095func collectJniDeps(ctx android.ModuleContext,
1096 shouldCollectRecursiveNativeDeps bool,
1097 checkNativeSdkVersion bool,
1098 filter func(cc.LinkableInterface) bool) ([]jniLib, android.Paths) {
1099 var jniLibs []jniLib
1100 var prebuiltJniPackages android.Paths
1101 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001102
Peter Collingbournead84f972019-12-17 16:46:18 -08001103 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001104 otherName := ctx.OtherModuleName(module)
1105 tag := ctx.OtherModuleDependencyTag(module)
1106
Colin Crossf0913fb2020-07-29 12:59:39 -07001107 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001108 if dep, ok := module.(cc.LinkableInterface); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001109 if filter != nil && !filter(dep) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001110 return false
1111 }
1112
Colin Crossa4f08812018-10-02 22:03:40 -07001113 lib := dep.OutputFile()
1114 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001115 path := lib.Path()
1116 if seenModulePaths[path.String()] {
1117 return false
1118 }
1119 seenModulePaths[path.String()] = true
1120
1121 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1122 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1123 otherName)
1124 }
1125
Colin Crossa4f08812018-10-02 22:03:40 -07001126 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001127 name: ctx.OtherModuleName(module),
1128 path: path,
1129 target: module.Target(),
1130 coverageFile: dep.CoverageOutputFile(),
1131 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001132 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001133 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001134 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001135 } else if ctx.Config().AllowMissingDependencies() {
1136 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001137 } else {
1138 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1139 }
1140 } else {
1141 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001142 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001143
1144 return shouldCollectRecursiveNativeDeps
1145 }
1146
Colin Cross313aa542023-12-13 13:47:44 -08001147 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001148 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1149 }
1150
Peter Collingbournead84f972019-12-17 16:46:18 -08001151 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001152 })
1153
Makoto Onuki2ca84272024-02-10 00:15:21 +00001154 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001155}
1156
Colin Cross8bf14fc2024-09-25 16:41:31 -07001157func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001158 ctx.WalkDeps(func(child, parent android.Module) bool {
1159 isExternal := !a.DepIsInSameApex(ctx, child)
1160 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001161 if !do(ctx, parent, am, isExternal) {
1162 return false
1163 }
Artur Satayev1111b842020-04-27 19:05:28 +01001164 }
1165 return !isExternal
1166 })
1167}
1168
1169func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1170 if ctx.Host() {
1171 return
1172 }
1173
1174 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross8bf14fc2024-09-25 16:41:31 -07001175 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001176 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001177
1178 // Skip dependencies that are only available to APEXes; they are developed with updatability
1179 // in mind and don't need manual approval.
1180 if to.(android.ApexModule).NotAvailableForPlatform() {
1181 return true
1182 }
1183
Artur Satayev1111b842020-04-27 19:05:28 +01001184 if info, exist := depsInfo[depName]; exist {
1185 info.From = append(info.From, from.Name())
1186 info.IsExternal = info.IsExternal && externalDep
1187 depsInfo[depName] = info
1188 } else {
1189 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001190 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001191 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001192 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001193 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1194 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001195 }
Jiyong Park92315372021-04-02 08:45:46 +09001196 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1197 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1198 // string
1199 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001200 toMinSdkVersion = v
1201 }
Artur Satayev1111b842020-04-27 19:05:28 +01001202 }
1203 depsInfo[depName] = android.ApexModuleDepInfo{
1204 To: depName,
1205 From: []string{from.Name()},
1206 IsExternal: externalDep,
1207 MinSdkVersion: toMinSdkVersion,
1208 }
1209 }
Jooyung Han749dc692020-04-15 11:03:39 +09001210 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001211 })
1212
Jiyong Park92315372021-04-02 08:45:46 +09001213 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001214}
1215
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001216func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1217 return a.appProperties.EnforceDefaultTargetSdkVersion
1218}
1219
1220func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1221 a.appProperties.EnforceDefaultTargetSdkVersion = val
1222}
1223
Artur Satayev849f8442020-04-28 14:57:42 +01001224func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001225 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001226}
1227
Colin Cross0ea8ba82019-06-06 14:33:29 -07001228func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001229 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1230 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001231 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001232 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001233 return String(a.overridableAppProperties.Certificate)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001234}
1235
Jiyong Park0f80c182020-01-31 02:49:53 +09001236func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1237 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1238 return true
1239 }
1240 return a.Library.DepIsInSameApex(ctx, dep)
1241}
1242
Jiyong Parkf7487312019-10-17 12:54:30 +09001243func (a *AndroidApp) Privileged() bool {
1244 return Bool(a.appProperties.Privileged)
1245}
1246
Colin Crosse1a85552024-06-14 12:17:37 -07001247func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001248 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001249}
1250
Ivan Lozanod7586b62021-04-01 09:49:36 -04001251func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001252 a.appProperties.PreventInstall = true
1253}
1254
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001255func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1256 a.appProperties.IsCoverageVariant = coverage
1257}
1258
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001259func (a *AndroidApp) EnableCoverageIfNeeded() {}
1260
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001261var _ cc.Coverage = (*AndroidApp)(nil)
1262
Cole Faustb36d31d2024-08-27 16:04:28 -07001263func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1264 a.Library.IDEInfo(ctx, dpInfo)
1265 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001266}
1267
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001268func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1269 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1270}
1271
1272func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1273 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1274}
1275
Colin Cross1b16b0e2019-02-12 14:41:32 -08001276// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001277func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001278 module := &AndroidApp{}
1279
Liz Kammera7a64f32020-07-09 15:16:41 -07001280 module.Module.dexProperties.Optimize.EnabledByDefault = true
1281 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001282 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001283
Colin Crossae5caf52018-05-22 11:11:52 -07001284 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001285 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001286 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001287
Colin Crossce6734e2020-06-15 16:09:53 -07001288 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001289 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001290 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001291 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001292 &module.overridableAppProperties,
1293 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001294
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001295 module.usesLibrary.enforce = true
1296
Colin Crossa4f08812018-10-02 22:03:40 -07001297 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1298 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001299 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001300 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001301
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001302 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1303 a := ctx.Module().(*AndroidApp)
1304
1305 characteristics := ctx.Config().ProductAAPTCharacteristics()
1306 if characteristics == "default" || characteristics == "" {
1307 module.appProperties.Generate_product_characteristics_rro = nil
1308 // no need to create RRO
1309 return
1310 }
1311
1312 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1313 return
1314 }
1315
1316 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1317 rroManifestName := rroPackageName + "_manifest"
1318
1319 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1320 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1321
1322 rroManifestProperties := struct {
1323 Name *string
1324 Tools []string
1325 Out []string
1326 Srcs []string
1327 Cmd *string
1328 }{
1329 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001330 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001331 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001332 Srcs: []string{":" + a.Name() + "{.apk}"},
1333 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001334 }
Cole Fauste19d3352024-10-17 10:30:57 -07001335 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001336
1337 rroProperties := struct {
1338 Name *string
1339 Filter_product *string
1340 Aaptflags []string
1341 Manifest *string
1342 Resource_dirs []string
1343 }{
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,
1349 }
优秀d75e9982024-05-09 07:15:55 +00001350 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1351 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1352 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1353 }
1354 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001355 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1356 })
1357
Colin Cross36242852017-06-23 15:06:31 -07001358 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001359}
Colin Crossae5caf52018-05-22 11:11:52 -07001360
Alix96ea88452023-08-31 15:48:23 +00001361// A dictionary of values to be overridden in the manifest.
1362type Manifest_values struct {
1363 // Overrides the value of package_name in the manifest
1364 ApplicationId *string
1365}
1366
Colin Crossae5caf52018-05-22 11:11:52 -07001367type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001368 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001369 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001370
Seth Moorec6f4b532023-02-02 13:22:26 -08001371 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001372 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001373
1374 // If specified, the mainline module package name in the test config is overwritten by it.
1375 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001376
1377 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001378}
1379
1380type AndroidTest struct {
1381 AndroidApp
1382
1383 appTestProperties appTestProperties
1384
1385 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001386
Dan Shi95d19422020-08-15 12:24:26 -07001387 testConfig android.Path
1388 extraTestConfigs android.Paths
1389 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001390}
1391
Jaewoong Jung0949f312019-09-11 10:25:18 -07001392func (a *AndroidTest) InstallInTestcases() bool {
1393 return true
1394}
1395
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001396type androidTestApp interface {
1397 includedInTestSuite(searchPrefix string) bool
1398}
1399
1400func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1401 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1402}
1403
1404func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1405 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1406}
1407
Colin Crossae5caf52018-05-22 11:11:52 -07001408func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001409 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001410 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001411 if a.appTestProperties.Instrumentation_target_package != nil {
1412 a.additionalAaptFlags = append(a.additionalAaptFlags,
1413 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1414 } else if a.appTestProperties.Instrumentation_for != nil {
1415 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001416 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1417 if overridden {
1418 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1419 }
1420 }
Alix96ea88452023-08-31 15:48:23 +00001421 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1422 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001423 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1424 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001425 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1426 }
1427 a.aapt.manifestValues.applicationId = *applicationId
1428 }
Colin Crossae5caf52018-05-22 11:11:52 -07001429 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001430
easoncylee5bcff5d2020-04-30 14:57:06 +08001431 for _, module := range a.testProperties.Test_mainline_modules {
1432 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1433 }
1434
Jaewoong Jung39982342020-01-14 10:27:18 -08001435 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001436 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1437 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001438 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001439 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001440 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Colin Cross40213022023-12-13 15:19:49 -08001441 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001442 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1443 InstalledFiles: a.data,
1444 OutputFile: a.OutputFile(),
1445 TestConfig: a.testConfig,
1446 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001447 TestSuites: a.testProperties.Test_suites,
1448 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001449 LocalCertificate: a.certificate.AndroidMkString(),
1450 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001451 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001452 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1453 TestOnly: true,
1454 TopLevelTarget: true,
1455 })
1456
Colin Cross303e21f2018-08-07 16:49:25 -07001457}
1458
Jaewoong Jung39982342020-01-14 10:27:18 -08001459func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1460 if testConfig == nil {
1461 return nil
1462 }
1463
1464 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001465 rule := android.NewRuleBuilder(pctx, ctx)
1466 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001467 fixNeeded := false
1468
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001469 // 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 -08001470 if ctx.ModuleName() != a.installApkName {
1471 fixNeeded = true
1472 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1473 }
1474
Cole Faust258b96f2024-10-04 10:48:24 -07001475 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1476 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001477 fixNeeded = true
1478 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001479 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001480 }
1481
Seth Moorec6f4b532023-02-02 13:22:26 -08001482 if a.appTestProperties.Mainline_package_name != nil {
1483 fixNeeded = true
1484 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1485 }
1486
Jaewoong Jung39982342020-01-14 10:27:18 -08001487 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001488 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001489 return fixedConfig
1490 }
1491 return testConfig
1492}
1493
Yihan Dong8be09c22024-08-29 15:32:13 +08001494func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1495 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1496 // Instrument the android_test_helper target to log potential API calls at the run time.
1497 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1498 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1499 a.setApiMapper(true)
1500 }
1501 a.AndroidApp.DepsMutator(ctx)
1502}
1503
Colin Cross303e21f2018-08-07 16:49:25 -07001504func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001505 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1506 // Instrument the android_test_helper target to log potential API calls at the run time.
1507 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1508 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1509 a.setApiMapper(true)
1510 }
Colin Cross303e21f2018-08-07 16:49:25 -07001511 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001512}
1513
1514func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1515 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001516 if a.appTestProperties.Instrumentation_for != nil {
1517 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1518 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1519 // use instrumentationForTag instead of libTag.
1520 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1521 }
Colin Crossae5caf52018-05-22 11:11:52 -07001522}
1523
Colin Cross1b16b0e2019-02-12 14:41:32 -08001524// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1525// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001526func AndroidTestFactory() android.Module {
1527 module := &AndroidTest{}
1528
Jared Duke63a3da92022-06-02 19:11:14 +00001529 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001530
1531 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001532 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001533 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001534 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1535 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001536 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001537 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001538
Colin Crossce6734e2020-06-15 16:09:53 -07001539 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001540 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001541 &module.aaptProperties,
1542 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001543 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001544 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001545 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001546
Colin Crossa4f08812018-10-02 22:03:40 -07001547 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1548 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001549 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001550
Colin Crossae5caf52018-05-22 11:11:52 -07001551 return module
1552}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001553
Colin Cross252fc6f2018-10-04 15:22:03 -07001554type appTestHelperAppProperties struct {
1555 // list of compatibility suites (for example "cts", "vts") that the module should be
1556 // installed into.
1557 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001558
1559 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1560 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1561 // explicitly.
1562 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001563
1564 // Install the test into a folder named for the module in all test suites.
1565 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001566
1567 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001568}
1569
1570type AndroidTestHelperApp struct {
1571 AndroidApp
1572
1573 appTestHelperAppProperties appTestHelperAppProperties
1574}
1575
Jaewoong Jung326a9412019-11-21 10:41:00 -08001576func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1577 return true
1578}
1579
Colin Cross1b16b0e2019-02-12 14:41:32 -08001580// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1581// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1582// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001583func AndroidTestHelperAppFactory() android.Module {
1584 module := &AndroidTestHelperApp{}
1585
Jared Duke63a3da92022-06-02 19:11:14 +00001586 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001587 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001588
1589 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001590 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1591 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001592 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001593 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001594
Colin Crossce6734e2020-06-15 16:09:53 -07001595 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001596 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001597 &module.aaptProperties,
1598 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001599 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001600 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001601
1602 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1603 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001604 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001605 return module
1606}
1607
Colin Crossbd01e2a2018-10-04 15:21:03 -07001608type AndroidAppCertificate struct {
1609 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001610
Colin Crossbd01e2a2018-10-04 15:21:03 -07001611 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001612 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001613}
1614
1615type AndroidAppCertificateProperties struct {
1616 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1617 Certificate *string
1618}
1619
Colin Cross1b16b0e2019-02-12 14:41:32 -08001620// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1621// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001622func AndroidAppCertificateFactory() android.Module {
1623 module := &AndroidAppCertificate{}
1624 module.AddProperties(&module.properties)
1625 android.InitAndroidModule(module)
1626 return module
1627}
1628
Colin Crossbd01e2a2018-10-04 15:21:03 -07001629func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1630 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001631 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001632 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1633 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001634 }
1635}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001636
1637type OverrideAndroidApp struct {
1638 android.ModuleBase
1639 android.OverrideModuleBase
1640}
1641
Sasha Smundak613cbb12020-06-05 10:27:23 -07001642func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001643 // All the overrides happen in the base module.
1644 // TODO(jungjw): Check the base module type.
1645}
1646
1647// override_android_app is used to create an android_app module based on another android_app by overriding
1648// some of its properties.
1649func OverrideAndroidAppModuleFactory() android.Module {
1650 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001651 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001652 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001653 &overridableAppProperties{},
1654 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001655
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001656 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001657 android.InitOverrideModule(m)
1658 return m
1659}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001660
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001661type OverrideAndroidTest struct {
1662 android.ModuleBase
1663 android.OverrideModuleBase
1664}
1665
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001666func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001667 // All the overrides happen in the base module.
1668 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001669 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1670 TestOnly: true,
1671 TopLevelTarget: true,
1672 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001673}
1674
1675// override_android_test is used to create an android_app module based on another android_test by overriding
1676// some of its properties.
1677func OverrideAndroidTestModuleFactory() android.Module {
1678 m := &OverrideAndroidTest{}
1679 m.AddProperties(&overridableAppProperties{})
1680 m.AddProperties(&appTestProperties{})
1681
1682 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1683 android.InitOverrideModule(m)
1684 return m
1685}
1686
Colin Cross50ddcc42019-05-16 12:28:22 -07001687type UsesLibraryProperties struct {
1688 // 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 -07001689 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001690
1691 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1692 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001693 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001694
1695 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1696 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1697 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001698
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001699 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1700 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1701 // normally is the same as the module name, but there are exceptions.
1702 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001703
1704 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1705 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1706 // added to the APK's manifest's <uses-library> elements.
1707 //
1708 // Care must be taken when using this as it could result in runtime errors if the APK actually
1709 // uses classes provided by the library and which are not provided in any other way.
1710 //
1711 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1712 // android.test.base shared library (and related libraries) but which depend on some common
1713 // libraries that depend on the android.test.base library. Without this those tests will end up
1714 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1715 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1716 // test altogether by providing access to classes that the tests were not expecting. Those tests
1717 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1718 // with the classes provided by the android.test.base library.
1719 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001720
1721 // The module names of optional uses-library libraries that are missing from the source tree.
1722 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001723}
1724
1725// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1726// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1727// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1728// with knowledge of their shared libraries.
1729type usesLibrary struct {
1730 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001731
1732 // Whether to enforce verify_uses_library check.
1733 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001734
1735 // Whether dexpreopt should be disabled
1736 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001737}
1738
Colin Cross4a80a152022-12-21 21:51:52 -08001739func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001740 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07001741 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001742 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1743 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001744 // Only add these extra dependencies if the module is an app that depends on framework
1745 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001746 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001747 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001748 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1749 // class loader context for dex2oat. Add them as a dependency with a special tag.
1750 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1751 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1752 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001753 }
Cole Faust64f2d842024-10-17 13:28:34 -07001754 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001755 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001756 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07001757 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001758 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001759 }
1760}
1761
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001762// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001763func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07001764 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001765 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001766 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001767 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1768 }
1769 return exists
1770 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001771 return optionalUsesLibs
1772}
1773
Ulya Trafimovich24446712021-07-15 14:59:34 +01001774// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1775// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001776func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1777 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001778
1779 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1780 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1781 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1782 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001783 }
1784
Ulya Trafimovich24446712021-07-15 14:59:34 +01001785 ctx.VisitDirectDeps(func(m android.Module) {
1786 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1787 if !isUsesLibTag {
1788 return
1789 }
1790
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001791 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001792
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001793 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1794 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1795 // from implementation libraries by their name, which is different as it has a suffix.
1796 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1797 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1798 return
1799 }
1800 }
1801
Ulya Trafimovich24446712021-07-15 14:59:34 +01001802 if lib, ok := m.(UsesLibraryDependency); ok {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001803 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1804 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1805 // This will be restricted to optional_uses_libs
1806 if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
1807 u.shouldDisableDexpreopt = true
1808 return
1809 }
1810 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001811 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001812 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001813 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001814 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001815 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001816 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001817 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001818 } else if ctx.Config().AllowMissingDependencies() {
1819 ctx.AddMissingDependencies([]string{dep})
1820 } else {
1821 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1822 }
1823 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001824 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001825}
1826
1827// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1828// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1829// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07001830func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
1831 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
1832 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001833 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001834}
1835
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001836// 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 -07001837func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
1838 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001839 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1840}
1841
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001842// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1843// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1844// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1845// extension: APKs are supposed to end with '.apk').
1846func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001847 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001848
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001849 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001850
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001851 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1852 // check is not necessary, and although it is good to have, it is difficult to maintain on
1853 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1854 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001855 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001856 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001857 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001858 }
1859
Colin Crossf1a035e2020-11-16 17:32:30 -08001860 rule := android.NewRuleBuilder(pctx, ctx)
1861 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001862 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001863 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001864 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001865 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001866
1867 if outputFile != nil {
1868 cmd.FlagWithOutput("-o ", outputFile)
1869 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001870
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001871 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1872 cmd.Flag("--enforce-uses-libraries-relax")
1873 }
1874
Jiakai Zhangf98da192024-04-15 11:15:41 +00001875 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1876 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001877 cmd.FlagWithArg("--uses-library ", lib)
1878 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001879 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001880 cmd.FlagWithArg("--optional-uses-library ", lib)
1881 }
1882
Jiakai Zhangf98da192024-04-15 11:15:41 +00001883 // Also add missing optional uses libs, as the manifest check expects them.
1884 // Note that what we add here are the module names of those missing libs, not library names, while
1885 // the manifest check actually expects library names. However, the case where a library is missing
1886 // and the module name != the library name is too rare for us to handle.
1887 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1888 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1889 }
1890
Colin Crossf1a035e2020-11-16 17:32:30 -08001891 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001892 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001893}
Colin Cross50ddcc42019-05-16 12:28:22 -07001894
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001895// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1896// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001897func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1898 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001899 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001900 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001901}
1902
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001903// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1904// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001905func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1906 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1907 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001908}