blob: a3414f6ea65877016f522dfbd730677cea1bed27 [file] [log] [blame]
Colin Cross30e076a2015-04-13 13:58:27 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
Jaewoong Jungf9b44652020-12-21 12:29:12 -080017// This file contains the module implementations for android_app, android_test, and some more
18// related module types, including their override variants.
Colin Cross30e076a2015-04-13 13:58:27 -070019
20import (
Jiakai Zhang4f65a032023-06-01 15:16:58 +010021 "fmt"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070022 "path/filepath"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070023 "strings"
Colin Cross30e076a2015-04-13 13:58:27 -070024
Colin Cross50ddcc42019-05-16 12:28:22 -070025 "github.com/google/blueprint"
Colin Crossa14fb6a2024-10-23 16:57:06 -070026 "github.com/google/blueprint/depset"
Colin Cross50ddcc42019-05-16 12:28:22 -070027 "github.com/google/blueprint/proptools"
28
Colin Cross635c3b02016-05-18 15:37:25 -070029 "android/soong/android"
Colin Crossa4f08812018-10-02 22:03:40 -070030 "android/soong/cc"
Ulya Trafimovichd4bcea42020-06-03 14:57:22 +010031 "android/soong/dexpreopt"
Colin Cross303e21f2018-08-07 16:49:25 -070032 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070033)
34
Colin Cross3bc7ffa2017-11-22 16:19:37 -080035func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000036 RegisterAppBuildComponents(android.InitRegistrationContext)
Andrei Onea580636b2022-08-17 16:53:46 +000037 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080038}
39
Andrei Onea580636b2022-08-17 16:53:46 +000040var (
41 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
42 blueprint.RuleParams{
43 Command: "${ModifyAllowlistCmd} $in $packageName $out",
44 CommandDeps: []string{"${ModifyAllowlistCmd}"},
45 }, "packageName")
46)
47
Jihoon Kang9aef7772024-06-14 23:45:06 +000048type FlagsPackages struct {
49 // Paths to the aconfig dump output text files that are consumed by aapt2
50 AconfigTextFiles android.Paths
51}
52
53var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
54
Paul Duffinf9b1da02019-12-18 19:51:55 +000055func RegisterAppBuildComponents(ctx android.RegistrationContext) {
56 ctx.RegisterModuleType("android_app", AndroidAppFactory)
57 ctx.RegisterModuleType("android_test", AndroidTestFactory)
58 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
59 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
60 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
61 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000062}
63
Colin Cross99939e92024-10-01 16:02:46 -070064type AppInfo struct {
65 // Updatable is set to the value of the updatable property
66 Updatable bool
67
68 // TestHelperApp is true if the module is a android_test_helper_app
69 TestHelperApp bool
Colin Crossb614cd42024-10-11 12:52:21 -070070
71 // EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
72 EmbeddedJNILibs android.Paths
Yu Liu7eebf8b2025-01-17 00:23:57 +000073
74 MergedManifestFile android.Path
Yu Liu0a37d422025-02-13 02:05:00 +000075
76 Prebuilt bool
77 AppSet bool
78 Privileged bool
79 OutputFile android.Path
80 InstallApkName string
81 JacocoReportClassesFile android.Path
82 Certificate Certificate
83 PrivAppAllowlist android.OptionalPath
84 OverriddenManifestPackageName *string
Spandan Das99e7dc12025-03-19 20:52:27 +000085 ApkCertsFile android.Path
Colin Cross99939e92024-10-01 16:02:46 -070086}
87
88var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
89
Colin Cross30e076a2015-04-13 13:58:27 -070090// AndroidManifest.xml merging
91// package splits
92
Colin Crossfabb6082018-02-20 17:22:23 -080093type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070094 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070095 Additional_certificates []string
96
97 // If set, create package-export.apk, which other packages can
98 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080099 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -0700100
Colin Cross16056062017-12-13 22:46:28 -0800101 // Specifies that this app should be installed to the priv-app directory,
102 // where the system will grant it additional privileges not available to
103 // normal apps.
104 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -0700105
106 // list of resource labels to generate individual resource packages
107 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -0400108
Colin Crossa4f08812018-10-02 22:03:40 -0700109 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +0000110 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -0700111
Colin Cross7204cf02020-05-06 17:51:39 -0700112 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -0800113 // sdk_version.
114 Jni_uses_platform_apis *bool
115
Colin Cross7204cf02020-05-06 17:51:39 -0700116 // if true, use JNI libraries that link against SDK APIs even if this module does not set
117 // sdk_version.
118 Jni_uses_sdk_apis *bool
119
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700120 // STL library to use for JNI libraries.
121 Stl *string `android:"arch_variant"`
122
Colin Crosse4246ab2019-02-05 21:55:21 -0800123 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900124 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
125 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
126 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
127 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800128 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800129
130 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
131 // they are used from inside the APK at runtime.
132 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700133
Jiyong Parkd044bb42024-05-15 02:09:54 +0900134 // Forces native libraries to always be packaged into the APK,
135 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
136 // True for android_test* modules.
137 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700138
139 // If set, find and merge all NOTICE files that this module and its dependencies have and store
140 // it in the APK as an asset.
141 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700142
143 // cc.Coverage related properties
144 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700145 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100146
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000147 // It can be set to test the behaviour of default target sdk version.
148 // Only required when updatable: false. It is an error if updatable: true and this is false.
149 Enforce_default_target_sdk_version *bool
150
151 // If set, the targetSdkVersion for the target is set to the latest default API level.
152 // This would be by default false, unless updatable: true or
153 // enforce_default_target_sdk_version: true in which case this defaults to true.
154 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
155
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100156 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100157 // additional rules to make sure an app can safely be updated. Default is false.
158 // Prefer using other specific properties if build behaviour must be changed; avoid using this
159 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100160 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000161
162 // Specifies the file that contains the allowlist for this app.
163 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900164
165 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
166 // and install the RRO package to /product partition, instead of passing --product argument
167 // to aapt2. Default is false.
168 // Setting this will make this APK identical to all targets, regardless of
169 // PRODUCT_CHARACTERISTICS.
170 Generate_product_characteristics_rro *bool
171
172 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
173 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700174}
175
Jaewoong Jung525443a2019-02-28 15:35:54 -0800176// android_app properties that can be overridden by override_android_app
177type overridableAppProperties struct {
178 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
179 // or an android_app_certificate module name in the form ":module".
Cole Fausteb9c1482024-11-18 16:49:19 -0800180 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700181
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800182 // Name of the signing certificate lineage file or filegroup module.
183 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700184
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400185 // For overriding the --rotation-min-sdk-version property of apksig
186 RotationMinSdkVersion *string
187
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700188 // 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 -0700189 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800190
191 // the logging parent of this app.
192 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000193
194 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
195 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000196
197 // Names of modules to be overridden. Listed modules can only be other binaries
198 // (in Make or Soong).
199 // This does not completely prevent installation of the overridden binaries, but if both
200 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
201 // from PRODUCT_PACKAGES.
202 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800203}
204
Colin Cross30e076a2015-04-13 13:58:27 -0700205type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700206 Library
207 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800208 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700209
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900210 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700211
Colin Crossfabb6082018-02-20 17:22:23 -0800212 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700213
Jaewoong Jung525443a2019-02-28 15:35:54 -0800214 overridableAppProperties overridableAppProperties
215
Colin Cross403cc152020-07-06 14:15:24 -0700216 jniLibs []jniLib
217 installPathForJNISymbols android.Path
218 embeddedJniLibs bool
219 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700220
221 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800222
223 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
224 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800225
Colin Cross70dda7e2019-10-01 22:05:35 -0700226 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700227
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700228 onDeviceDir string
229
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800230 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700231
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900232 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100233
234 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000235
236 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000237
238 privAppAllowlist android.OptionalPath
Spandan Dasde588a32024-12-03 22:52:24 +0000239
240 requiredModuleNames []string
Colin Crosse1731a52017-12-14 11:22:55 -0800241}
242
Martin Stjernholm6d415272020-01-31 17:10:36 +0000243func (a *AndroidApp) IsInstallable() bool {
244 return Bool(a.properties.Installable)
245}
246
Colin Crossa14fb6a2024-10-23 16:57:06 -0700247func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000248 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700249}
250
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900251func (a *AndroidApp) OutputFile() android.Path {
252 return a.outputFile
253}
254
Colin Cross503c1d02020-01-28 14:00:53 -0800255func (a *AndroidApp) Certificate() Certificate {
256 return a.certificate
257}
258
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700259func (a *AndroidApp) JniCoverageOutputs() android.Paths {
260 return a.jniCoverageOutputs
261}
262
Andrei Onea580636b2022-08-17 16:53:46 +0000263func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
264 return a.privAppAllowlist
265}
266
Colin Crossa97c5d32018-03-28 14:58:31 -0700267var _ AndroidLibraryDependency = (*AndroidApp)(nil)
268
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900269type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800270 Pem, Key android.Path
271 presigned bool
272}
273
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700274var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800275
276func (c Certificate) AndroidMkString() string {
277 if c.presigned {
278 return "PRESIGNED"
279 } else {
280 return c.Pem.String()
281 }
Colin Cross30e076a2015-04-13 13:58:27 -0700282}
283
Colin Cross46c9b8b2017-06-22 16:51:17 -0700284func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900285 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700286 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
287 }
288
Jiyong Parkf1691d22021-03-29 20:11:58 +0900289 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000290 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
291 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100292 if sdkDep.hasFrameworkLibs() {
293 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700294 }
Colin Crossa4f08812018-10-02 22:03:40 -0700295
Jiyong Park92315372021-04-02 08:45:46 +0900296 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700297
298 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
299 ctx.PropertyErrorf("jni_uses_sdk_apis",
300 "can only be set for modules that do not set sdk_version")
301 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
302 ctx.PropertyErrorf("jni_uses_platform_apis",
303 "can only be set for modules that set sdk_version")
304 }
305
Colin Crossa4f08812018-10-02 22:03:40 -0700306 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700307 variation := append(jniTarget.Variations(),
308 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000309
Jiyong Park92d84042024-05-17 22:58:54 +0000310 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
311 // Many factors are considered here.
312 // 1. Basically, the selection follows whether the app has sdk_version set or not.
313 jniUsesSdkVariant := usesSDK
314 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
315 if Bool(a.appProperties.Jni_uses_sdk_apis) {
316 jniUsesSdkVariant = true
317 }
318 if Bool(a.appProperties.Jni_uses_platform_apis) {
319 jniUsesSdkVariant = false
320 }
321 // 3. Then the use of SDK variant is again prohibited for the following cases:
322 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
323 // partition (not only the app) is considered unbudled, there's no need to use the
324 // SDK variant.
325 // 3.2. the app doesn't support embedding the JNI libs
326 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
327 jniUsesSdkVariant = false
328 }
329 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000330 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
331 }
Jiyong Park92d84042024-05-17 22:58:54 +0000332
333 // Use the installable dep tag when the JNIs are not embedded
334 var tag dependencyTag
335 if a.shouldEmbedJnis(ctx) {
336 tag = jniLibTag
337 } else {
338 tag = jniInstallTag
339 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000340 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700341 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000342 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
343 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
344 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700345}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700346
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700347func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800348 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700349 if cert != "" {
350 ctx.AddDependency(ctx.Module(), certificateTag, cert)
351 }
352
Andrei Onea580636b2022-08-17 16:53:46 +0000353 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000354 // There are a few uids that are explicitly considered privileged regardless of their
355 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
356 // but for now, allow it not to be in priv-app.
357 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
358 if !privilegedBecauseOfUid {
359 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
360 }
Andrei Onea580636b2022-08-17 16:53:46 +0000361 }
362
Colin Crossbd01e2a2018-10-04 15:21:03 -0700363 for _, cert := range a.appProperties.Additional_certificates {
364 cert = android.SrcIsModule(cert)
365 if cert != "" {
366 ctx.AddDependency(ctx.Module(), certificateTag, cert)
367 } else {
368 ctx.PropertyErrorf("additional_certificates",
369 `must be names of android_app_certificate modules in the form ":module"`)
370 }
371 }
Colin Cross30e076a2015-04-13 13:58:27 -0700372}
373
Spandan Dasb0410872024-06-25 03:30:03 +0000374// TODO(b/156476221): Remove this allowlist
375var (
376 missingMinSdkVersionMtsAllowlist = []string{
377 "CellBroadcastReceiverGoogleUnitTests",
378 "CellBroadcastReceiverUnitTests",
379 "CtsBatterySavingTestCases",
380 "CtsDeviceAndProfileOwnerApp23",
381 "CtsDeviceAndProfileOwnerApp30",
382 "CtsIntentSenderApp",
383 "CtsJobSchedulerTestCases",
384 "CtsMimeMapTestCases",
385 "CtsTareTestCases",
386 "LibStatsPullTests",
387 "MediaProviderClientTests",
388 "TeleServiceTests",
389 "TestExternalImsServiceApp",
390 "TestSmsRetrieverApp",
391 "TetheringPrivilegedTests",
392 }
393)
394
395func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
396 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
397 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
398 }
399}
400
Jeongik Cha538c0d02019-07-11 15:54:27 +0900401func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000402 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000403 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
404 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700405 packageName := a.overridableAppProperties.Package_name.Get(ctx)
406 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000407 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
408 }
409 a.aapt.manifestValues.applicationId = *applicationId
410 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900411 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700412 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
413 TestOnly: true,
414 })
Yu Liu0a37d422025-02-13 02:05:00 +0000415 appInfo := &AppInfo{
Colin Cross99939e92024-10-01 16:02:46 -0700416 Updatable: Bool(a.appProperties.Updatable),
417 TestHelperApp: true,
Yu Liu0a37d422025-02-13 02:05:00 +0000418 }
419 setCommonAppInfo(appInfo, a)
420 android.SetProvider(ctx, AppInfoProvider, appInfo)
Cole Faust866ab392025-01-23 12:56:20 -0800421
422 moduleInfoJSON := ctx.ModuleInfoJSON()
423 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
424 if len(a.appTestHelperAppProperties.Test_suites) > 0 {
425 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...)
426 } else {
427 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
428 }
Cole Faust5e1454a2025-03-11 15:55:59 -0700429
430 android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
431 TestSuites: a.appTestHelperAppProperties.Test_suites,
Colin Cross99939e92024-10-01 16:02:46 -0700432 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900433}
434
Colin Cross46c9b8b2017-06-22 16:51:17 -0700435func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100436 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000437 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700438 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000439 a.generateJavaUsedByApex(ctx)
Colin Crossb614cd42024-10-11 12:52:21 -0700440
441 var embeddedJniLibs []android.Path
442
443 if a.embeddedJniLibs {
444 for _, jni := range a.jniLibs {
445 embeddedJniLibs = append(embeddedJniLibs, jni.path)
446 }
447 }
Yu Liu0a37d422025-02-13 02:05:00 +0000448 overriddenName := a.OverriddenManifestPackageName()
449 appInfo := &AppInfo{
450 Updatable: Bool(a.appProperties.Updatable),
451 TestHelperApp: false,
452 EmbeddedJNILibs: embeddedJniLibs,
453 MergedManifestFile: a.mergedManifest,
454 OverriddenManifestPackageName: &overriddenName,
455 }
456 setCommonAppInfo(appInfo, a)
457 android.SetProvider(ctx, AppInfoProvider, appInfo)
Spandan Dasde588a32024-12-03 22:52:24 +0000458
459 a.requiredModuleNames = a.getRequiredModuleNames(ctx)
Cole Faust1dcf9e42025-02-19 17:23:34 -0800460
461 if a.dexer.proguardDictionary.Valid() {
462 android.SetProvider(ctx, ProguardProvider, ProguardInfo{
463 ModuleName: ctx.ModuleName(),
464 Class: "APPS",
465 ProguardDictionary: a.dexer.proguardDictionary.Path(),
466 ProguardUsageZip: a.dexer.proguardUsageZip.Path(),
467 ClassesJar: a.implementationAndResourcesJar,
468 })
469 }
Spandan Dasde588a32024-12-03 22:52:24 +0000470}
471
472func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
473 var required []string
474 if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
475 required = []string{a.productCharacteristicsRROPackageName()}
476 }
477 // Install the vendor overlay variant if this app is installed.
478 if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
479 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
480 }
481 // Install the product overlay variant if this app is installed.
482 if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
483 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
484 }
485 return required
Colin Crossae5caf52018-05-22 11:11:52 -0700486}
487
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100488func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100489 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900490 if !a.SdkVersion(ctx).Stable() {
491 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100492 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000493 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100494 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
495 }
Jooyung Han749dc692020-04-15 11:03:39 +0900496
Jiyong Park92315372021-04-02 08:45:46 +0900497 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900498 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000499 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900500 } else {
501 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
502 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000503
504 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
505 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
506 }
507 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
508 if a.deviceProperties.Target_sdk_version == nil {
509 a.SetEnforceDefaultTargetSdkVersion(true)
510 }
511 }
512
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100513 a.checkPlatformAPI(ctx)
514 a.checkSdkVersions(ctx)
515}
516
Jiyong Park970c5242024-05-17 22:58:54 +0000517// Ensures that use_embedded_native_libs are set for apk-in-apex
518func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
519 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
520 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000521 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000522
523 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
524 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
525 }
526}
527
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900528// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
529// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900530func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900531 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
Yu Liufc8d5c12025-01-09 00:19:06 +0000532 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900533 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
534 return
535 }
Yu Liufc8d5c12025-01-09 00:19:06 +0000536 if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
537 panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
538 }
Yu Liuef9e63e2025-03-04 19:01:28 +0000539 commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoProvider)
Yu Liufc8d5c12025-01-09 00:19:06 +0000540 if !ok {
541 panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
542 }
Jooyung Han652d5b32020-05-20 17:12:13 +0900543 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900544 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
545 // handled properly regardless of sdk finalization.
Yu Liu5d3a2cf2025-02-06 00:25:22 +0000546 ver := ""
547 if !commonInfo.MinSdkVersion.IsPlatform {
548 ver = commonInfo.MinSdkVersion.ApiLevel.String()
549 }
550 jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900551 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Yu Liufc8d5c12025-01-09 00:19:06 +0000552 ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
Yu Liu5d3a2cf2025-02-06 00:25:22 +0000553 ver, minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900554 return
555 }
556
557 })
558}
559
Sasha Smundak6ad77252019-05-01 13:16:22 -0700560// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800561// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700562func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900563 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800564 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900565 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800566 }
567
Jiyong Parkd044bb42024-05-15 02:09:54 +0900568 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
569 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
570 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800571}
572
Colin Cross43f08db2018-11-12 10:13:39 -0800573// Returns whether this module should have the dex file stored uncompressed in the APK.
574func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800575 if Bool(a.appProperties.Use_embedded_dex) {
576 return true
577 }
578
Colin Cross53a87f52019-06-25 13:35:30 -0700579 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
580 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900581 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000582 return true
583 }
584
Colin Cross53a87f52019-06-25 13:35:30 -0700585 if ctx.Config().UnbundledBuild() {
586 return false
587 }
588
Spandan Dase21a8d42024-01-23 23:56:29 +0000589 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700590}
591
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700592func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900593 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000594 Bool(a.appProperties.Updatable) ||
595 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000596}
597
Liz Kammer9f9fd022020-06-18 19:44:06 +0000598func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
599 aaptFlags := []string{"--rename-manifest-package " + packageName}
600 if renameResourcesPackage {
601 // Required to rename the package name in the resources table.
602 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
603 }
604 return aaptFlags
605}
606
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900607func (a *AndroidApp) OverriddenManifestPackageName() string {
608 return a.overriddenManifestPackageName
609}
610
Liz Kammer9f9fd022020-06-18 19:44:06 +0000611func (a *AndroidApp) renameResourcesPackage() bool {
612 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
613}
614
Jihoon Kang9049c272024-03-19 21:57:36 +0000615func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Yu Liu460cf372025-01-10 00:34:06 +0000616 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000617 tag := ctx.OtherModuleDependencyTag(dep)
618 switch tag {
Spandan Das13193892025-03-03 21:49:06 +0000619 case staticLibTag, rroDepTag:
Jihoon Kang9aef7772024-06-14 23:45:06 +0000620 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
621 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
622 }
623
624 case aconfigDeclarationTag:
625 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
626 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
627 } else {
628 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
629 "flags_packages property, but %s is not aconfig_declarations module type",
630 dep.Name(),
631 )
632 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000633 }
634 })
635
Jihoon Kang9aef7772024-06-14 23:45:06 +0000636 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000637}
638
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800639func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900640 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900641 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900642 usePlatformAPI = true
643 }
644 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000645
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700646 // Ask manifest_fixer to add or update the application element indicating this app has no code.
647 a.aapt.hasNoCode = !a.hasCode(ctx)
648
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800649 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800650
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800651 // 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 +0900652 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800653 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900654 characteristics := ctx.Config().ProductAAPTCharacteristics()
655 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
656 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700657 }
658
Dan Willemsen72be5902018-10-24 20:24:57 -0700659 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
660 // Product AAPT config
661 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800662 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700663 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700664
Dan Willemsen72be5902018-10-24 20:24:57 -0700665 // Product AAPT preferred config
666 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800667 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700668 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700669 }
670
Jiyong Park7f67f482019-01-05 12:57:48 +0900671 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700672 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
673 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700674 // The product override variable has a priority over the package_name property.
675 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700676 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700677 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000678 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900679 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900680 }
681
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800682 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
683
Colin Crosse560c4a2019-03-19 16:03:11 -0700684 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800685 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100686 if a.Updatable() {
Alyssa Ketpreechasawat02774e82024-07-04 10:45:04 +0000687 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
688 a.aapt.defaultManifestVersion = override
689 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000690 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawat02774e82024-07-04 10:45:04 +0000691 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100692 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000693
Rico Winda2fa2632024-03-13 13:09:17 +0100694 // Use non final ids if we are doing optimized shrinking and are using R8.
LaMont Jonesb97f1d12025-03-18 15:18:58 -0700695 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled(ctx)
Jihoon Kang9aef7772024-06-14 23:45:06 +0000696
697 aconfigTextFilePaths := getAconfigFilePaths(ctx)
698
Alixf7a10272023-09-27 16:47:56 +0000699 a.aapt.buildActions(ctx,
700 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000701 sdkContext: android.SdkContext(a),
702 classLoaderContexts: a.classLoaderContexts,
703 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
704 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100705 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000706 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000707 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000708 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000709 },
710 )
Colin Cross30e076a2015-04-13 13:58:27 -0700711
Colin Cross46c9b8b2017-06-22 16:51:17 -0700712 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700713 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000714
715 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
716 AconfigTextFiles: aconfigTextFilePaths,
717 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800718}
Colin Cross30e076a2015-04-13 13:58:27 -0700719
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800720func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700721 var staticLibProguardFlagFiles android.Paths
Yu Liu80b68c42025-01-15 18:14:34 +0000722 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Colin Cross313aa542023-12-13 13:47:44 -0800723 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400724 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
725 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
726 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700727 }
728 })
729
730 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
731
Colin Cross312634e2023-11-21 15:13:56 -0800732 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200733 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100734 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
735 // live for code references and (transitively) mark these as live.
736 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
737 // dead code alive)
738 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
739 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800740}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800741
Colin Cross403cc152020-07-06 14:15:24 -0700742func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800743 var installDir string
744 if ctx.ModuleName() == "framework-res" {
745 // framework-res.apk is installed as system/framework/framework-res.apk
746 installDir = "framework"
Rashed Abdel-Tawab5b948ab2018-08-09 14:08:53 -0700747 } else if ctx.ModuleName() == "omnirom-res" {
748 // omnirom-res.apk is installed as system/framework/omnirom-res.apk
749 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900750 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800751 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800752 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800753 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800754 }
Colin Cross403cc152020-07-06 14:15:24 -0700755
756 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
757}
758
Yu Liu7eebf8b2025-01-17 00:23:57 +0000759func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) {
Colin Cross403cc152020-07-06 14:15:24 -0700760 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000761 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700762 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100763 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700764 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100765 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700766 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700767 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100768 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700769 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800770 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700771
Rico Wind98e7fa82023-11-27 09:44:03 +0100772 var packageResources = a.exportPackage
773
Yu Liu460cf372025-01-10 00:34:06 +0000774 javaInfo := &JavaInfo{}
Rashed Abdel-Tawab5b948ab2018-08-09 14:08:53 -0700775 if ctx.ModuleName() != "framework-res" && ctx.ModuleName() != "omnirom-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200776 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100777 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
778 aapt2Convert(ctx, protoFile, packageResources, "proto")
779 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
780 }
781
Colin Cross4eae06d2023-06-20 22:40:02 -0700782 var extraSrcJars android.Paths
783 var extraClasspathJars android.Paths
784 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800785 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700786 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
787 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
788 // classpath when compiling everything else, and add it to the final classes jar.
789 extraClasspathJars = android.Paths{a.aapt.rJar}
790 extraCombinedJars = android.Paths{a.aapt.rJar}
791 } else {
792 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
793 // R.java files for the app's package and the packages from all transitive static android_library
794 // dependencies. Compile the srcjar alongside the rest of the sources.
795 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
796 }
797
Yu Liu460cf372025-01-10 00:34:06 +0000798 javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200799 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100800 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
801 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
802 packageResources = binaryResources
803 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800804 }
Colin Cross30e076a2015-04-13 13:58:27 -0700805
Yu Liu7eebf8b2025-01-17 00:23:57 +0000806 return a.dexJarFile.PathOrNil(), packageResources, javaInfo
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800807}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800808
Sam Delmerico82602492022-06-10 17:05:42 +0000809func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700810 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000811 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700812 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700813 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700814 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800815 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000816 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700817 for _, jni := range jniLibs {
818 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700819 // Only collect coverage for the first target arch if this is a multilib target.
820 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
821 // data file path collisions since the current coverage file path format doesn't contain
822 // arch-related strings. This is fine for now though; the code coverage team doesn't use
823 // multi-arch targets such as test_suite_* for coverage collections yet.
824 //
825 // Work with the team to come up with a new format that handles multilib modules properly
826 // and change this.
827 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700828 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700829 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
830 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700831 }
832 }
Colin Cross403cc152020-07-06 14:15:24 -0700833 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700834 }
835 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800836 return jniJarFile
837}
Colin Crossa4f08812018-10-02 22:03:40 -0700838
Colin Cross403cc152020-07-06 14:15:24 -0700839func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
840 var jniSymbols android.RuleBuilderInstalls
841 for _, jniLib := range a.jniLibs {
842 if jniLib.unstrippedFile != nil {
843 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
844 From: jniLib.unstrippedFile,
845 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
846 })
847 }
848 }
849 return jniSymbols
850}
851
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700852// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
853// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700854func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
855 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700856 if android.SrcIsModule(certPropValue) == "" {
857 var mainCert Certificate
858 if certPropValue != "" {
859 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
860 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800861 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
862 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700863 }
864 } else {
865 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800866 mainCert = Certificate{
867 Pem: pem,
868 Key: key,
869 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700870 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700871 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700872 }
873
Colin Crossbc2c8a72022-09-14 12:45:42 -0700874 if len(certificates) > 0 {
875 mainCertificate = certificates[0]
876 } else {
877 // This can be reached with an empty certificate list if AllowMissingDependencies is set
878 // and the certificate property for this module is a module reference to a missing module.
879 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
880 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
881 }
882 // Set a certificate to avoid panics later when accessing it.
883 mainCertificate = Certificate{
884 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000885 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700886 }
887 }
888
Zyan Wub7550aa2023-05-18 15:46:31 +0800889 if !m.Platform() {
890 certPath := mainCertificate.Pem.String()
891 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
892 if strings.HasPrefix(certPath, systemCertPath) {
893 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
894 allowed := ctx.Config().EnforceSystemCertificateAllowList()
895
896 if enforceSystemCert && !inList(m.Name(), allowed) {
897 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
898 }
899 }
900 }
901
Colin Crossbc2c8a72022-09-14 12:45:42 -0700902 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800903}
904
Jooyung Han39ee1192020-03-23 20:21:11 +0900905func (a *AndroidApp) InstallApkName() string {
906 return a.installApkName
907}
908
Sam Delmerico15809f82023-05-15 17:21:47 -0400909func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000910 if a.appProperties.Privapp_allowlist == nil {
911 return nil
912 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400913
914 isOverrideApp := a.GetOverriddenBy() != ""
915 if !isOverrideApp {
916 // if this is not an override, we don't need to rewrite the existing privapp allowlist
917 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
918 }
919
Cole Faust258b96f2024-10-04 10:48:24 -0700920 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
921 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000922 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
923 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400924
Cole Faust258b96f2024-10-04 10:48:24 -0700925 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000926 fileName := "privapp_allowlist_" + packageName + ".xml"
Cole Faust4e9f5922024-11-13 16:09:23 -0800927 outPath := android.PathForModuleOut(ctx, fileName)
Andrei Onea580636b2022-08-17 16:53:46 +0000928 ctx.Build(pctx, android.BuildParams{
929 Rule: modifyAllowlist,
930 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
931 Output: outPath,
932 Args: map[string]string{
933 "packageName": packageName,
934 },
935 })
Cole Faust4e9f5922024-11-13 16:09:23 -0800936 return outPath
Andrei Onea580636b2022-08-17 16:53:46 +0000937}
938
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800939func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700940 var apkDeps android.Paths
941
Colin Crossff694a82023-12-13 15:54:49 -0800942 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
943 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700944 a.hideApexVariantFromMake = true
945 }
946
Jeongik Cha538c0d02019-07-11 15:54:27 +0900947 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
948 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
949
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000950 // Unlike installApkName, a.stem should respect base module name for override_android_app.
951 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000952 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000953
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800954 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000955 // Both android_app and override_android_app module are expected to possess
956 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
957 // from the base module. Therefore, use a.Name() which represents
958 // the module name for both android_app and override_android_app.
959 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000960 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800961
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700962 if ctx.ModuleName() == "framework-res" {
963 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700964 a.installDir = android.PathForModuleInstall(ctx, "framework")
Rashed Abdel-Tawab5b948ab2018-08-09 14:08:53 -0700965 } else if ctx.ModuleName() == "omnirom-res" {
966 // omnirom-res.apk is installed as system/framework/omnirom-res.apk
967 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900968 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700969 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
970 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800971 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700972 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700973 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700974 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700975 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700976
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100977 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000978 if a.usesLibrary.shouldDisableDexpreopt {
979 a.dexpreopter.disableDexpreopt()
980 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000981
Colin Cross61fb62e2022-06-23 10:46:28 -0700982 var noticeAssetPath android.WritablePath
983 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
984 // The rule to create the notice file can't be generated yet, as the final output path
985 // for the apk isn't known yet. Add the path where the notice file will be generated to the
986 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
987 // be generated later.
988 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
989 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
990 }
991
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000992 // For apps targeting latest target_sdk_version
993 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
994 a.SetEnforceDefaultTargetSdkVersion(true)
995 }
996
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800997 // Process all building blocks, from AAPT to certificates.
998 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100999 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -07001000 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001001
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001002 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -07001003 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +00001004 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
1005 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001006 apkDeps = append(apkDeps, manifestCheckFile)
1007 }
1008
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001009 a.proguardBuildActions(ctx)
1010
Colin Cross014489c2020-06-02 20:09:13 -07001011 a.linter.mergedManifest = a.aapt.mergedManifestFile
1012 a.linter.manifest = a.aapt.manifestPath
1013 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -07001014 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -07001015
Yu Liu7eebf8b2025-01-17 00:23:57 +00001016 dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001017
Jiyong Park92d84042024-05-17 22:58:54 +00001018 // No need to check the SDK version of the JNI deps unless we embed them
1019 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
1020 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +00001021 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001022
1023 if ctx.Failed() {
1024 return
1025 }
1026
Colin Crossbc2c8a72022-09-14 12:45:42 -07001027 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001028
1029 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -08001030 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001031 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
1032 var v4SignatureFile android.WritablePath = nil
1033 if v4SigningRequested {
1034 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
1035 }
Liz Kammere2b27f42020-05-07 13:24:05 -07001036 var lineageFile android.Path
1037 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
1038 lineageFile = android.PathForModuleSrc(ctx, lineage)
1039 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04001040 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
1041
Rico Wind98e7fa82023-11-27 09:44:03 +01001042 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001043 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -07001044 if v4SigningRequested {
1045 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1046 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001047
Colin Cross61fb62e2022-06-23 10:46:28 -07001048 if a.aapt.noticeFile.Valid() {
1049 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -07001050 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -07001051 android.BuildNoticeHtmlOutputFromLicenseMetadata(
1052 ctx, noticeFile, "", "",
1053 []string{
1054 a.installDir.String() + "/",
1055 android.PathForModuleInstall(ctx).String() + "/",
1056 a.outputFile.String(),
1057 })
Bob Badoureef4c1c2022-05-16 12:20:04 -07001058 builder := android.NewRuleBuilder(pctx, ctx)
1059 builder.Command().Text("cp").
1060 Input(noticeFile).
1061 Output(noticeAssetPath)
1062 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -07001063 }
1064
Colin Crosse560c4a2019-03-19 16:03:11 -07001065 for _, split := range a.aapt.splits {
1066 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -08001067 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001068 if v4SigningRequested {
1069 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
1070 }
Rico Wind98e7fa82023-11-27 09:44:03 +01001071 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -07001072 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -07001073 if v4SigningRequested {
1074 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1075 }
Colin Crosse560c4a2019-03-19 16:03:11 -07001076 }
1077
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001078 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -07001079 bundleFile := android.PathForModuleOut(ctx, "base.zip")
1080 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1081 a.bundleFile = bundleFile
1082
Andrei Onea580636b2022-08-17 16:53:46 +00001083 allowlist := a.createPrivappAllowlist(ctx)
1084 if allowlist != nil {
1085 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1086 }
1087
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001088 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001089 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1090 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001091 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001092 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1093 allowlistInstallFilename := a.installApkName + ".xml"
1094 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001095 }
1096
Colin Cross09ad3a62023-11-15 12:29:33 -08001097 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001098 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001099 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1100 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001101 }
Jiyong Park25b92222024-05-17 22:58:54 +00001102 // If we don't embed jni libs, make sure that those are installed along with the
1103 // app, and also place symlinks to the installed paths under the lib/<arch>
1104 // directory of the app installation directory. ex:
1105 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1106 if !a.embeddedJniLibs {
1107 for _, jniLib := range jniLibs {
1108 archStr := jniLib.target.Arch.ArchType.String()
1109 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1110 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001111 // install the symlink itself
1112 symlinkName := installedLib.Base()
1113 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1114 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1115 }
1116 }
1117 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001118 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001119 }
Artur Satayev1111b842020-04-27 19:05:28 +01001120
Colin Crossa6182ab2024-08-21 10:47:44 -07001121 ctx.CheckbuildFile(a.outputFile)
1122
Artur Satayev1111b842020-04-27 19:05:28 +01001123 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001124
1125 providePrebuiltInfo(ctx,
1126 prebuiltInfoProps{
1127 baseModuleName: a.BaseModuleName(),
1128 isPrebuilt: false,
1129 },
1130 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001131
Yu Liu7eebf8b2025-01-17 00:23:57 +00001132 if javaInfo != nil {
1133 javaInfo.OutputFile = a.outputFile
1134 setExtraJavaInfo(ctx, a, javaInfo)
1135 android.SetProvider(ctx, JavaInfoProvider, javaInfo)
1136 }
1137
Yu Liu95cef3a2025-02-25 00:54:20 +00001138 android.SetProvider(ctx, android.ApexBundleDepsDataProvider, android.ApexBundleDepsData{
1139 FlatListPath: a.FlatListPath(),
1140 Updatable: a.Updatable(),
1141 })
1142
Cole Faust866ab392025-01-23 12:56:20 -08001143 moduleInfoJSON := ctx.ModuleInfoJSON()
1144 moduleInfoJSON.Class = []string{"APPS"}
1145 if !a.embeddedJniLibs {
1146 for _, jniLib := range a.jniLibs {
1147 moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name)
1148 }
1149 }
1150
mrziwang9f7b9f42024-07-10 12:18:06 -07001151 a.setOutputFiles(ctx)
Wei Li986fe742025-01-30 15:14:42 -08001152
1153 buildComplianceMetadata(ctx)
mrziwang9f7b9f42024-07-10 12:18:06 -07001154}
1155
1156func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1157 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1158 if a.aaptSrcJar != nil {
1159 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1160 }
1161 if a.rJar != nil {
1162 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1163 }
1164 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1165 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1166 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1167 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001168}
1169
Colin Crossc2d24052020-05-13 11:05:02 -07001170type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001171 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001172 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001173 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1174}
1175
1176func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1177 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001178 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001179
Colin Crossc2d24052020-05-13 11:05:02 -07001180 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001181 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1182 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001183 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001184 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
Yu Liuf6f85492025-01-13 21:02:36 +00001185 checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool {
Spandan Das10c41362024-12-03 01:33:09 +00001186 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
Yu Liuf6f85492025-01-13 21:02:36 +00001187 childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
1188 parentIsLinkable := false
Yu Liue472c1d2025-02-26 20:13:04 +00001189 if android.EqualModules(ctx.Module(), parent) {
Yu Liuf6f85492025-01-13 21:02:36 +00001190 parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
1191 parentIsLinkable = parentLinkable != nil
1192 } else {
1193 _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider)
1194 }
1195 useStubsOfDep := childLinkable.IsStubs
1196 if apkInApex && parentIsLinkable {
Spandan Das10c41362024-12-03 01:33:09 +00001197 // APK-in-APEX
1198 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
Yu Liuf6f85492025-01-13 21:02:36 +00001199 useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child))
Spandan Das10c41362024-12-03 01:33:09 +00001200 }
Yu Liuf6f85492025-01-13 21:02:36 +00001201 return !childLinkable.IsNdk && !useStubsOfDep
Makoto Onuki2ca84272024-02-10 00:15:21 +00001202 })
1203
1204 var certificates []Certificate
1205
Colin Crossb614cd42024-10-11 12:52:21 -07001206 var directImplementationDeps android.Paths
1207 var transitiveImplementationDeps []depset.DepSet[android.Path]
Yu Liu728da7c2025-01-11 00:54:32 +00001208 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001209 otherName := ctx.OtherModuleName(module)
1210 tag := ctx.OtherModuleDependencyTag(module)
1211
1212 if tag == certificateTag {
Yu Liu728da7c2025-01-11 00:54:32 +00001213 if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001214 certificates = append(certificates, dep.Certificate)
1215 } else {
1216 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1217 }
1218 }
Colin Crossb614cd42024-10-11 12:52:21 -07001219
1220 if IsJniDepTag(tag) {
1221 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1222 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1223 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1224 }
1225 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001226 })
Colin Crossb614cd42024-10-11 12:52:21 -07001227 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1228 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1229 })
1230
Makoto Onuki2ca84272024-02-10 00:15:21 +00001231 return jniLib, prebuiltJniPackages, certificates
1232}
1233
1234func collectJniDeps(ctx android.ModuleContext,
1235 shouldCollectRecursiveNativeDeps bool,
1236 checkNativeSdkVersion bool,
Yu Liuf6f85492025-01-13 21:02:36 +00001237 filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001238 var jniLibs []jniLib
1239 var prebuiltJniPackages android.Paths
1240 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001241
Yu Liuf6f85492025-01-13 21:02:36 +00001242 ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
Yu Liuf22120f2025-03-13 18:36:35 +00001243 if !android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
Yu Liub732c842025-01-16 00:15:54 +00001244 return false
1245 }
Colin Crossa4f08812018-10-02 22:03:40 -07001246 otherName := ctx.OtherModuleName(module)
1247 tag := ctx.OtherModuleDependencyTag(module)
1248
Colin Crossf0913fb2020-07-29 12:59:39 -07001249 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Yu Liuf6f85492025-01-13 21:02:36 +00001250 if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
Spandan Das10c41362024-12-03 01:33:09 +00001251 if filter != nil && !filter(parent, module) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001252 return false
1253 }
1254
Yu Liuf6f85492025-01-13 21:02:36 +00001255 lib := dep.OutputFile
Colin Crossa4f08812018-10-02 22:03:40 -07001256 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001257 path := lib.Path()
1258 if seenModulePaths[path.String()] {
1259 return false
1260 }
1261 seenModulePaths[path.String()] = true
1262
Yu Liuf22120f2025-03-13 18:36:35 +00001263 commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
Yu Liuf6f85492025-01-13 21:02:36 +00001264 if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
Cole Faust64cb7c92021-09-14 17:32:49 -07001265 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1266 otherName)
1267 }
1268
Colin Crossa4f08812018-10-02 22:03:40 -07001269 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001270 name: ctx.OtherModuleName(module),
1271 path: path,
Yu Liuf6f85492025-01-13 21:02:36 +00001272 target: commonInfo.Target,
1273 coverageFile: dep.CoverageOutputFile,
1274 unstrippedFile: dep.UnstrippedOutputFile,
1275 partition: dep.Partition,
1276 installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001277 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001278 } else if ctx.Config().AllowMissingDependencies() {
1279 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001280 } else {
1281 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1282 }
1283 } else {
1284 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001285 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001286
1287 return shouldCollectRecursiveNativeDeps
1288 }
1289
Colin Cross313aa542023-12-13 13:47:44 -08001290 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001291 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1292 }
1293
Peter Collingbournead84f972019-12-17 16:46:18 -08001294 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001295 })
1296
Makoto Onuki2ca84272024-02-10 00:15:21 +00001297 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001298}
1299
Colin Cross8bf14fc2024-09-25 16:41:31 -07001300func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Yu Liue263a692025-03-04 19:30:25 +00001301 ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001302 // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
1303 // heuristics to every transitive dependency, when it should probably be using the heuristics of the
1304 // immediate parent.
Yu Liuf1806032025-02-07 00:23:34 +00001305 isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
Yu Liue263a692025-03-04 19:30:25 +00001306 if am, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok && am.IsApexModule {
1307 if !do(ctx, parent, child, isExternal) {
Jooyung Han749dc692020-04-15 11:03:39 +09001308 return false
1309 }
Artur Satayev1111b842020-04-27 19:05:28 +01001310 }
1311 return !isExternal
1312 })
1313}
1314
1315func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1316 if ctx.Host() {
1317 return
1318 }
1319
1320 depsInfo := android.DepNameToDepInfoMap{}
Yu Liue263a692025-03-04 19:30:25 +00001321 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001322 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001323
1324 // Skip dependencies that are only available to APEXes; they are developed with updatability
1325 // in mind and don't need manual approval.
Yu Liuf22120f2025-03-13 18:36:35 +00001326 if android.OtherModulePointerProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform {
Artur Satayev533b98c2021-03-11 18:03:42 +00001327 return true
1328 }
1329
Artur Satayev1111b842020-04-27 19:05:28 +01001330 if info, exist := depsInfo[depName]; exist {
1331 info.From = append(info.From, from.Name())
1332 info.IsExternal = info.IsExternal && externalDep
1333 depsInfo[depName] = info
1334 } else {
1335 toMinSdkVersion := "(no version)"
Yu Liuef9e63e2025-03-04 19:01:28 +00001336 if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoProvider); ok &&
Yu Liudf0b8392025-02-12 18:27:03 +00001337 !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
1338 toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001339 }
1340 depsInfo[depName] = android.ApexModuleDepInfo{
1341 To: depName,
1342 From: []string{from.Name()},
1343 IsExternal: externalDep,
1344 MinSdkVersion: toMinSdkVersion,
1345 }
1346 }
Jooyung Han749dc692020-04-15 11:03:39 +09001347 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001348 })
1349
Jiyong Park92315372021-04-02 08:45:46 +09001350 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001351}
1352
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001353func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1354 return a.appProperties.EnforceDefaultTargetSdkVersion
1355}
1356
1357func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1358 a.appProperties.EnforceDefaultTargetSdkVersion = val
1359}
1360
Artur Satayev849f8442020-04-28 14:57:42 +01001361func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001362 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001363}
1364
Colin Cross0ea8ba82019-06-06 14:33:29 -07001365func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001366 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1367 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001368 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001369 }
Cole Fausteb9c1482024-11-18 16:49:19 -08001370 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001371}
1372
Yu Liuf1806032025-02-07 00:23:34 +00001373func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker {
1374 return AppDepInSameApexChecker{}
1375}
1376
1377type AppDepInSameApexChecker struct {
1378 android.BaseDepInSameApexChecker
1379}
1380
1381func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001382 if IsJniDepTag(tag) {
Jiyong Park0f80c182020-01-31 02:49:53 +09001383 return true
1384 }
Yu Liuf1806032025-02-07 00:23:34 +00001385 return depIsInSameApex(tag)
Jiyong Park0f80c182020-01-31 02:49:53 +09001386}
1387
Jiyong Parkf7487312019-10-17 12:54:30 +09001388func (a *AndroidApp) Privileged() bool {
1389 return Bool(a.appProperties.Privileged)
1390}
1391
Colin Crosse1a85552024-06-14 12:17:37 -07001392func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001393 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001394}
1395
Ivan Lozanod7586b62021-04-01 09:49:36 -04001396func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001397 a.appProperties.PreventInstall = true
1398}
1399
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001400func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1401 a.appProperties.IsCoverageVariant = coverage
1402}
1403
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001404func (a *AndroidApp) EnableCoverageIfNeeded() {}
1405
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001406var _ cc.Coverage = (*AndroidApp)(nil)
1407
Cole Faustb36d31d2024-08-27 16:04:28 -07001408func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1409 a.Library.IDEInfo(ctx, dpInfo)
1410 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001411}
1412
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001413func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1414 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1415}
1416
1417func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1418 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1419}
1420
Colin Cross1b16b0e2019-02-12 14:41:32 -08001421// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001422func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001423 module := &AndroidApp{}
1424
Liz Kammera7a64f32020-07-09 15:16:41 -07001425 module.Module.dexProperties.Optimize.EnabledByDefault = true
1426 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001427 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001428
Colin Crossae5caf52018-05-22 11:11:52 -07001429 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001430 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001431 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001432
Colin Crossce6734e2020-06-15 16:09:53 -07001433 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001434 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001435 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001436 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001437 &module.overridableAppProperties,
1438 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001439
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001440 module.usesLibrary.enforce = true
1441
Colin Crossa4f08812018-10-02 22:03:40 -07001442 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1443 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001444 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001445 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001446
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001447 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1448 a := ctx.Module().(*AndroidApp)
1449
1450 characteristics := ctx.Config().ProductAAPTCharacteristics()
1451 if characteristics == "default" || characteristics == "" {
1452 module.appProperties.Generate_product_characteristics_rro = nil
1453 // no need to create RRO
1454 return
1455 }
1456
1457 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1458 return
1459 }
1460
1461 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1462 rroManifestName := rroPackageName + "_manifest"
1463
1464 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1465 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1466
1467 rroManifestProperties := struct {
1468 Name *string
1469 Tools []string
1470 Out []string
1471 Srcs []string
1472 Cmd *string
1473 }{
1474 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001475 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001476 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001477 Srcs: []string{":" + a.Name() + "{.apk}"},
1478 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001479 }
Cole Fauste19d3352024-10-17 10:30:57 -07001480 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001481
1482 rroProperties := struct {
1483 Name *string
1484 Filter_product *string
1485 Aaptflags []string
1486 Manifest *string
Cole Faust5b989772024-11-06 11:03:16 -08001487 Resource_dirs proptools.Configurable[[]string]
Jihoon Kangf62f4222024-10-21 23:06:41 +00001488 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001489 }{
1490 Name: proptools.StringPtr(rroPackageName),
1491 Filter_product: proptools.StringPtr(characteristics),
1492 Aaptflags: []string{"--auto-add-overlay"},
1493 Manifest: proptools.StringPtr(":" + rroManifestName),
1494 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001495 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001496 }
优秀d75e9982024-05-09 07:15:55 +00001497 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1498 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1499 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1500 }
1501 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001502 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
Spandan Dasde588a32024-12-03 22:52:24 +00001503
1504 })
1505
1506 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1507 createInternalRuntimeOverlays(ctx, module.ModuleBase)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001508 })
1509
Colin Cross36242852017-06-23 15:06:31 -07001510 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001511}
Colin Crossae5caf52018-05-22 11:11:52 -07001512
Spandan Das71be42d2024-11-20 18:34:16 +00001513func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1514 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1515}
1516
Spandan Dasde588a32024-12-03 22:52:24 +00001517type createModuleContext interface {
1518 android.EarlyModuleContext
1519 CreateModule(android.ModuleFactory, ...interface{}) android.Module
1520}
1521
1522func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
1523 if !ctx.Config().HasDeviceProduct() {
1524 return
1525 }
1526 // vendor
1527 vendorOverlayProps := struct {
1528 Name *string
1529 Base *string
1530 Vendor *bool
1531 Product_specific *bool
1532 System_ext_specific *bool
1533 Manifest *string
1534 Sdk_version *string
1535 Compile_multilib *string
1536 Enabled proptools.Configurable[bool]
1537 }{
1538 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")),
1539 Base: proptools.StringPtr(a.Name()),
1540 Vendor: proptools.BoolPtr(true),
1541 Product_specific: proptools.BoolPtr(false),
1542 System_ext_specific: proptools.BoolPtr(false),
1543 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1544 Sdk_version: proptools.StringPtr("current"),
1545 Compile_multilib: proptools.StringPtr("first"),
1546 Enabled: a.EnabledProperty().Clone(),
1547 }
1548 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
1549
1550 // product
1551 productOverlayProps := struct {
1552 Name *string
1553 Base *string
1554 Vendor *bool
1555 Proprietary *bool
1556 Soc_specific *bool
1557 Product_specific *bool
1558 System_ext_specific *bool
1559 Manifest *string
1560 Sdk_version *string
1561 Compile_multilib *string
1562 Enabled proptools.Configurable[bool]
1563 }{
1564 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
1565 Base: proptools.StringPtr(a.Name()),
1566 Vendor: proptools.BoolPtr(false),
1567 Proprietary: proptools.BoolPtr(false),
1568 Soc_specific: proptools.BoolPtr(false),
1569 Product_specific: proptools.BoolPtr(true),
1570 System_ext_specific: proptools.BoolPtr(false),
1571 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1572 Sdk_version: proptools.StringPtr("current"),
1573 Compile_multilib: proptools.StringPtr("first"),
1574 Enabled: a.EnabledProperty().Clone(),
1575 }
1576 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
1577}
1578
Alix96ea88452023-08-31 15:48:23 +00001579// A dictionary of values to be overridden in the manifest.
1580type Manifest_values struct {
1581 // Overrides the value of package_name in the manifest
1582 ApplicationId *string
1583}
1584
Colin Crossae5caf52018-05-22 11:11:52 -07001585type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001586 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001587 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001588
Seth Moorec6f4b532023-02-02 13:22:26 -08001589 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001590 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001591
1592 // If specified, the mainline module package name in the test config is overwritten by it.
1593 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001594
1595 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001596}
1597
1598type AndroidTest struct {
1599 AndroidApp
1600
1601 appTestProperties appTestProperties
1602
1603 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001604
Dan Shi95d19422020-08-15 12:24:26 -07001605 testConfig android.Path
1606 extraTestConfigs android.Paths
1607 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001608}
1609
Jaewoong Jung0949f312019-09-11 10:25:18 -07001610func (a *AndroidTest) InstallInTestcases() bool {
1611 return true
1612}
1613
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001614type androidTestApp interface {
1615 includedInTestSuite(searchPrefix string) bool
1616}
1617
1618func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1619 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1620}
1621
1622func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1623 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1624}
1625
Colin Crossae5caf52018-05-22 11:11:52 -07001626func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001627 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001628 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001629 if a.appTestProperties.Instrumentation_target_package != nil {
1630 a.additionalAaptFlags = append(a.additionalAaptFlags,
1631 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1632 } else if a.appTestProperties.Instrumentation_for != nil {
1633 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001634 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1635 if overridden {
1636 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1637 }
1638 }
Alix96ea88452023-08-31 15:48:23 +00001639 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1640 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001641 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1642 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001643 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1644 }
1645 a.aapt.manifestValues.applicationId = *applicationId
1646 }
Colin Crossae5caf52018-05-22 11:11:52 -07001647 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001648
Jiyong Parkf528b702024-12-30 16:01:58 +09001649 for _, c := range a.testProperties.Test_options.Tradefed_options {
1650 configs = append(configs, c)
1651 }
easoncylee5bcff5d2020-04-30 14:57:06 +08001652 for _, module := range a.testProperties.Test_mainline_modules {
1653 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1654 }
1655
Jaewoong Jung39982342020-01-14 10:27:18 -08001656 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001657 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1658 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001659 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001660 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001661 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001662 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1663 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001664 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Colin Crossb3614422025-02-18 15:18:18 -08001665 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...)
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001666
Spandan Dasa65d1e02025-01-28 19:34:04 +00001667 // Install test deps
1668 if !ctx.Config().KatiEnabled() {
1669 pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name())
1670 if a.testConfig != nil {
1671 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig)
1672 }
Cole Faustec71dfb2025-02-18 13:31:12 -08001673 dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
1674 if dynamicConfig.Valid() {
1675 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path())
1676 }
Spandan Dasa65d1e02025-01-28 19:34:04 +00001677 testDeps := append(a.data, a.extraTestConfigs...)
1678 for _, data := range android.SortedUniquePaths(testDeps) {
1679 dataPath := android.DataPath{SrcPath: data}
1680 ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
1681 }
1682 }
Colin Cross40213022023-12-13 15:19:49 -08001683
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001684 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001685 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001686 OutputFile: a.OutputFile(),
1687 TestConfig: a.testConfig,
1688 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001689 TestSuites: a.testProperties.Test_suites,
1690 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001691 LocalCertificate: a.certificate.AndroidMkString(),
1692 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001693 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1694 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001695 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001696 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1697 TestOnly: true,
1698 TopLevelTarget: true,
1699 })
1700
Cole Faust866ab392025-01-23 12:56:20 -08001701 moduleInfoJSON := ctx.ModuleInfoJSON()
1702 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
1703 if a.testConfig != nil {
1704 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String())
1705 }
1706 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...)
1707 if len(a.testProperties.Test_suites) > 0 {
1708 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...)
1709 } else {
1710 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
1711 }
1712
1713 if _, ok := testConfig.(android.WritablePath); ok {
1714 moduleInfoJSON.AutoTestConfig = []string{"true"}
1715 }
1716 moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
Cole Faust5e1454a2025-03-11 15:55:59 -07001717
1718 android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
1719 TestSuites: a.testProperties.Test_suites,
1720 })
Colin Cross303e21f2018-08-07 16:49:25 -07001721}
1722
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001723func testcaseRel(paths android.Paths) []string {
1724 relPaths := []string{}
1725 for _, p := range paths {
1726 relPaths = append(relPaths, p.Rel())
1727 }
1728 return relPaths
1729}
1730
Jaewoong Jung39982342020-01-14 10:27:18 -08001731func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1732 if testConfig == nil {
1733 return nil
1734 }
1735
1736 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001737 rule := android.NewRuleBuilder(pctx, ctx)
1738 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001739 fixNeeded := false
1740
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001741 // 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 -08001742 if ctx.ModuleName() != a.installApkName {
1743 fixNeeded = true
1744 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1745 }
1746
Cole Faust258b96f2024-10-04 10:48:24 -07001747 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1748 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001749 fixNeeded = true
1750 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001751 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001752 }
1753
Seth Moorec6f4b532023-02-02 13:22:26 -08001754 if a.appTestProperties.Mainline_package_name != nil {
1755 fixNeeded = true
1756 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1757 }
1758
Jaewoong Jung39982342020-01-14 10:27:18 -08001759 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001760 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001761 return fixedConfig
1762 }
1763 return testConfig
1764}
1765
Yihan Dong8be09c22024-08-29 15:32:13 +08001766func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1767 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1768 // Instrument the android_test_helper target to log potential API calls at the run time.
1769 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1770 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1771 a.setApiMapper(true)
1772 }
1773 a.AndroidApp.DepsMutator(ctx)
1774}
1775
Colin Cross303e21f2018-08-07 16:49:25 -07001776func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001777 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1778 // Instrument the android_test_helper target to log potential API calls at the run time.
1779 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1780 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1781 a.setApiMapper(true)
1782 }
Colin Cross303e21f2018-08-07 16:49:25 -07001783 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001784}
1785
1786func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1787 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001788 if a.appTestProperties.Instrumentation_for != nil {
1789 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1790 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1791 // use instrumentationForTag instead of libTag.
1792 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1793 }
Colin Crossae5caf52018-05-22 11:11:52 -07001794}
1795
Colin Cross1b16b0e2019-02-12 14:41:32 -08001796// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1797// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001798func AndroidTestFactory() android.Module {
1799 module := &AndroidTest{}
1800
Jared Duke63a3da92022-06-02 19:11:14 +00001801 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001802
1803 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001804 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001805 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001806 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1807 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001808 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001809 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001810
Colin Crossce6734e2020-06-15 16:09:53 -07001811 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001812 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001813 &module.aaptProperties,
1814 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001815 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001816 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001817 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001818
Colin Crossa4f08812018-10-02 22:03:40 -07001819 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1820 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001821 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001822
Colin Crossae5caf52018-05-22 11:11:52 -07001823 return module
1824}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001825
Colin Cross252fc6f2018-10-04 15:22:03 -07001826type appTestHelperAppProperties struct {
1827 // list of compatibility suites (for example "cts", "vts") that the module should be
1828 // installed into.
1829 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001830
1831 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1832 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1833 // explicitly.
1834 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001835
1836 // Install the test into a folder named for the module in all test suites.
1837 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001838
1839 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001840}
1841
1842type AndroidTestHelperApp struct {
1843 AndroidApp
1844
1845 appTestHelperAppProperties appTestHelperAppProperties
1846}
1847
Jaewoong Jung326a9412019-11-21 10:41:00 -08001848func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1849 return true
1850}
1851
Colin Cross1b16b0e2019-02-12 14:41:32 -08001852// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1853// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1854// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001855func AndroidTestHelperAppFactory() android.Module {
1856 module := &AndroidTestHelperApp{}
1857
Jared Duke63a3da92022-06-02 19:11:14 +00001858 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001859 module.Module.dexProperties.Optimize.EnabledByDefault = true
Christoffer Adamsenc8fd1f12025-01-06 19:04:03 +01001860 module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
1861 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross252fc6f2018-10-04 15:22:03 -07001862
1863 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001864 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1865 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001866 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001867 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001868
Colin Crossce6734e2020-06-15 16:09:53 -07001869 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001870 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001871 &module.aaptProperties,
1872 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001873 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001874 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001875
1876 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1877 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001878 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001879 return module
1880}
1881
Colin Crossbd01e2a2018-10-04 15:21:03 -07001882type AndroidAppCertificate struct {
1883 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001884
Colin Crossbd01e2a2018-10-04 15:21:03 -07001885 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001886 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001887}
1888
1889type AndroidAppCertificateProperties struct {
1890 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1891 Certificate *string
1892}
1893
Yu Liu728da7c2025-01-11 00:54:32 +00001894type AndroidAppCertificateInfo struct {
1895 Certificate Certificate
1896}
1897
1898var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]()
1899
Colin Cross1b16b0e2019-02-12 14:41:32 -08001900// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1901// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001902func AndroidAppCertificateFactory() android.Module {
1903 module := &AndroidAppCertificate{}
1904 module.AddProperties(&module.properties)
1905 android.InitAndroidModule(module)
1906 return module
1907}
1908
Colin Crossbd01e2a2018-10-04 15:21:03 -07001909func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1910 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001911 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001912 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1913 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001914 }
Yu Liu728da7c2025-01-11 00:54:32 +00001915
1916 android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{
1917 Certificate: c.Certificate,
1918 })
Colin Crossbd01e2a2018-10-04 15:21:03 -07001919}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001920
1921type OverrideAndroidApp struct {
1922 android.ModuleBase
1923 android.OverrideModuleBase
1924}
1925
Sasha Smundak613cbb12020-06-05 10:27:23 -07001926func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001927 // All the overrides happen in the base module.
1928 // TODO(jungjw): Check the base module type.
1929}
1930
1931// override_android_app is used to create an android_app module based on another android_app by overriding
1932// some of its properties.
1933func OverrideAndroidAppModuleFactory() android.Module {
1934 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001935 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001936 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001937 &overridableAppProperties{},
1938 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001939
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001940 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001941 android.InitOverrideModule(m)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001942 android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) {
Spandan Dasde588a32024-12-03 22:52:24 +00001943 createInternalRuntimeOverlays(ctx, m.ModuleBase)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001944 }, 1) // Run after soong config load hoook
Spandan Dasde588a32024-12-03 22:52:24 +00001945
Jaewoong Jung525443a2019-02-28 15:35:54 -08001946 return m
1947}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001948
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001949type OverrideAndroidTest struct {
1950 android.ModuleBase
1951 android.OverrideModuleBase
1952}
1953
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001954func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001955 // All the overrides happen in the base module.
1956 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001957 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1958 TestOnly: true,
1959 TopLevelTarget: true,
1960 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001961}
1962
1963// override_android_test is used to create an android_app module based on another android_test by overriding
1964// some of its properties.
1965func OverrideAndroidTestModuleFactory() android.Module {
1966 m := &OverrideAndroidTest{}
1967 m.AddProperties(&overridableAppProperties{})
1968 m.AddProperties(&appTestProperties{})
1969
1970 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1971 android.InitOverrideModule(m)
1972 return m
1973}
1974
Colin Cross50ddcc42019-05-16 12:28:22 -07001975type UsesLibraryProperties struct {
1976 // 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 -07001977 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001978
1979 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1980 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001981 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001982
1983 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1984 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1985 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001986
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001987 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1988 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1989 // normally is the same as the module name, but there are exceptions.
1990 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001991
1992 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1993 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1994 // added to the APK's manifest's <uses-library> elements.
1995 //
1996 // Care must be taken when using this as it could result in runtime errors if the APK actually
1997 // uses classes provided by the library and which are not provided in any other way.
1998 //
1999 // This is primarily intended for use by various CTS tests that check the runtime handling of the
2000 // android.test.base shared library (and related libraries) but which depend on some common
2001 // libraries that depend on the android.test.base library. Without this those tests will end up
2002 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
2003 // render the tests worthless (as they would be testing the wrong behavior), or would break the
2004 // test altogether by providing access to classes that the tests were not expecting. Those tests
2005 // provide the android.test.base statically and use jarjar to rename them so they do not collide
2006 // with the classes provided by the android.test.base library.
2007 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00002008
2009 // The module names of optional uses-library libraries that are missing from the source tree.
2010 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07002011}
2012
2013// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
2014// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
2015// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
2016// with knowledge of their shared libraries.
2017type usesLibrary struct {
2018 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002019
2020 // Whether to enforce verify_uses_library check.
2021 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00002022
2023 // Whether dexpreopt should be disabled
2024 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07002025}
2026
Colin Cross4a80a152022-12-21 21:51:52 -08002027func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09002028 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07002029 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00002030 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
2031 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08002032 // Only add these extra dependencies if the module is an app that depends on framework
2033 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01002034 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08002035 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002036 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
2037 // class loader context for dex2oat. Add them as a dependency with a special tag.
2038 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
2039 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
2040 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07002041 }
Cole Faust64f2d842024-10-17 13:28:34 -07002042 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00002043 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002044 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07002045 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05002046 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07002047 }
2048}
2049
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002050// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07002051func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07002052 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002053 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01002054 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01002055 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
2056 }
2057 return exists
2058 })
Colin Cross50ddcc42019-05-16 12:28:22 -07002059 return optionalUsesLibs
2060}
2061
Ulya Trafimovich24446712021-07-15 14:59:34 +01002062// Returns a map of module names of shared library dependencies to the paths to their dex jars on
2063// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002064func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
2065 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002066
2067 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
2068 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
2069 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
2070 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002071 }
2072
Yu Liu27b74aa2025-01-11 00:04:41 +00002073 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Ulya Trafimovich24446712021-07-15 14:59:34 +01002074 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
2075 if !isUsesLibTag {
2076 return
2077 }
2078
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002079 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01002080
Yu Liu27b74aa2025-01-11 00:04:41 +00002081 javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
2082 if !ok {
2083 return
2084 }
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002085 // Skip stub libraries. A dependency on the implementation library has been added earlier,
2086 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
2087 // from implementation libraries by their name, which is different as it has a suffix.
Yu Liu27b74aa2025-01-11 00:04:41 +00002088 if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
2089 if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
Ulya Trafimovich840efb62021-07-15 14:34:40 +01002090 return
2091 }
2092 }
2093
Yu Liu27b74aa2025-01-11 00:04:41 +00002094 if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002095 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
2096 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
2097 // This will be restricted to optional_uses_libs
Yu Liu0a37d422025-02-13 02:05:00 +00002098 if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00002099 u.shouldDisableDexpreopt = true
2100 return
2101 }
2102 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01002103 libName := dep
Yu Liu27b74aa2025-01-11 00:04:41 +00002104 if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil {
2105 libName = *ulib.ProvidesUsesLib
Ulya Trafimovich24446712021-07-15 14:59:34 +01002106 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002107 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Yu Liu0a37d422025-02-13 02:05:00 +00002108 javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath,
Yu Liu27b74aa2025-01-11 00:04:41 +00002109 lib.ClassLoaderContexts)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002110 } else if ctx.Config().AllowMissingDependencies() {
2111 ctx.AddMissingDependencies([]string{dep})
2112 } else {
2113 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
2114 }
2115 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002116 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002117}
2118
2119// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
2120// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
2121// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07002122func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
2123 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
2124 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002125 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002126}
2127
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002128// 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 -07002129func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
2130 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002131 u.usesLibraryProperties.Enforce_uses_libs = &enforce
2132}
2133
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002134// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
2135// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
2136// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
2137// extension: APKs are supposed to end with '.apk').
2138func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00002139 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002140
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002141 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07002142
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002143 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
2144 // check is not necessary, and although it is good to have, it is difficult to maintain on
2145 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
2146 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01002147 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00002148 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002149 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002150 }
2151
Colin Crossf1a035e2020-11-16 17:32:30 -08002152 rule := android.NewRuleBuilder(pctx, ctx)
2153 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07002154 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002155 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002156 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00002157 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002158
2159 if outputFile != nil {
2160 cmd.FlagWithOutput("-o ", outputFile)
2161 }
Colin Cross50ddcc42019-05-16 12:28:22 -07002162
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002163 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
2164 cmd.Flag("--enforce-uses-libraries-relax")
2165 }
2166
Jiakai Zhangf98da192024-04-15 11:15:41 +00002167 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
2168 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002169 cmd.FlagWithArg("--uses-library ", lib)
2170 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00002171 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002172 cmd.FlagWithArg("--optional-uses-library ", lib)
2173 }
2174
Jiakai Zhangf98da192024-04-15 11:15:41 +00002175 // Also add missing optional uses libs, as the manifest check expects them.
2176 // Note that what we add here are the module names of those missing libs, not library names, while
2177 // the manifest check actually expects library names. However, the case where a library is missing
2178 // and the module name != the library name is too rare for us to handle.
2179 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
2180 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
2181 }
2182
Colin Crossf1a035e2020-11-16 17:32:30 -08002183 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002184 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002185}
Colin Cross50ddcc42019-05-16 12:28:22 -07002186
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002187// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
2188// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002189func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
2190 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002191 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00002192 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07002193}
2194
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002195// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
2196// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002197func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
2198 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
2199 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07002200}
Yu Liu0a37d422025-02-13 02:05:00 +00002201
2202// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
2203// the same way.
2204type androidApp interface {
2205 android.Module
2206 Privileged() bool
2207 InstallApkName() string
2208 OutputFile() android.Path
2209 JacocoReportClassesFile() android.Path
2210 Certificate() Certificate
2211 BaseModuleName() string
2212 PrivAppAllowlist() android.OptionalPath
2213}
2214
2215var _ androidApp = (*AndroidApp)(nil)
2216var _ androidApp = (*AndroidAppImport)(nil)
2217var _ androidApp = (*AndroidTestHelperApp)(nil)
2218
2219func setCommonAppInfo(appInfo *AppInfo, m androidApp) {
2220 appInfo.Privileged = m.Privileged()
2221 appInfo.OutputFile = m.OutputFile()
2222 appInfo.InstallApkName = m.InstallApkName()
2223 appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile()
2224 appInfo.Certificate = m.Certificate()
2225 appInfo.PrivAppAllowlist = m.PrivAppAllowlist()
2226}
Spandan Das38afe712025-03-05 23:27:55 +00002227
2228type AppInfos []AppInfo
2229
2230var AppInfosProvider = blueprint.NewProvider[AppInfos]()