blob: 8a2afbded361b86d7564d92b7b0f2edff77875ca [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
Yu Liu42f69972024-12-13 22:46:12 +000055type AndroidLibraryInfo struct {
56 // Empty for now
57}
58
59var AndroidLibraryInfoProvider = blueprint.NewProvider[AndroidLibraryInfo]()
60
Paul Duffinf9b1da02019-12-18 19:51:55 +000061func RegisterAppBuildComponents(ctx android.RegistrationContext) {
62 ctx.RegisterModuleType("android_app", AndroidAppFactory)
63 ctx.RegisterModuleType("android_test", AndroidTestFactory)
64 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
65 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
66 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
67 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000068}
69
Colin Cross99939e92024-10-01 16:02:46 -070070type AppInfo struct {
71 // Updatable is set to the value of the updatable property
72 Updatable bool
73
74 // TestHelperApp is true if the module is a android_test_helper_app
75 TestHelperApp bool
Colin Crossb614cd42024-10-11 12:52:21 -070076
77 // EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
78 EmbeddedJNILibs android.Paths
Colin Cross99939e92024-10-01 16:02:46 -070079}
80
81var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
82
Colin Cross30e076a2015-04-13 13:58:27 -070083// AndroidManifest.xml merging
84// package splits
85
Colin Crossfabb6082018-02-20 17:22:23 -080086type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070087 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070088 Additional_certificates []string
89
90 // If set, create package-export.apk, which other packages can
91 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080092 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070093
Colin Cross16056062017-12-13 22:46:28 -080094 // Specifies that this app should be installed to the priv-app directory,
95 // where the system will grant it additional privileges not available to
96 // normal apps.
97 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070098
99 // list of resource labels to generate individual resource packages
100 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -0400101
Colin Crossa4f08812018-10-02 22:03:40 -0700102 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +0000103 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -0700104
Colin Cross7204cf02020-05-06 17:51:39 -0700105 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -0800106 // sdk_version.
107 Jni_uses_platform_apis *bool
108
Colin Cross7204cf02020-05-06 17:51:39 -0700109 // if true, use JNI libraries that link against SDK APIs even if this module does not set
110 // sdk_version.
111 Jni_uses_sdk_apis *bool
112
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700113 // STL library to use for JNI libraries.
114 Stl *string `android:"arch_variant"`
115
Colin Crosse4246ab2019-02-05 21:55:21 -0800116 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900117 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
118 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
119 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
120 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800121 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800122
123 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
124 // they are used from inside the APK at runtime.
125 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700126
Jiyong Parkd044bb42024-05-15 02:09:54 +0900127 // Forces native libraries to always be packaged into the APK,
128 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
129 // True for android_test* modules.
130 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700131
132 // If set, find and merge all NOTICE files that this module and its dependencies have and store
133 // it in the APK as an asset.
134 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700135
136 // cc.Coverage related properties
137 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700138 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100139
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000140 // It can be set to test the behaviour of default target sdk version.
141 // Only required when updatable: false. It is an error if updatable: true and this is false.
142 Enforce_default_target_sdk_version *bool
143
144 // If set, the targetSdkVersion for the target is set to the latest default API level.
145 // This would be by default false, unless updatable: true or
146 // enforce_default_target_sdk_version: true in which case this defaults to true.
147 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
148
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100149 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100150 // additional rules to make sure an app can safely be updated. Default is false.
151 // Prefer using other specific properties if build behaviour must be changed; avoid using this
152 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100153 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000154
155 // Specifies the file that contains the allowlist for this app.
156 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900157
158 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
159 // and install the RRO package to /product partition, instead of passing --product argument
160 // to aapt2. Default is false.
161 // Setting this will make this APK identical to all targets, regardless of
162 // PRODUCT_CHARACTERISTICS.
163 Generate_product_characteristics_rro *bool
164
165 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
166 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700167}
168
Jaewoong Jung525443a2019-02-28 15:35:54 -0800169// android_app properties that can be overridden by override_android_app
170type overridableAppProperties struct {
171 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
172 // or an android_app_certificate module name in the form ":module".
Cole Fausteb9c1482024-11-18 16:49:19 -0800173 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700174
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800175 // Name of the signing certificate lineage file or filegroup module.
176 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700177
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400178 // For overriding the --rotation-min-sdk-version property of apksig
179 RotationMinSdkVersion *string
180
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700181 // 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 -0700182 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800183
184 // the logging parent of this app.
185 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000186
187 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
188 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000189
190 // Names of modules to be overridden. Listed modules can only be other binaries
191 // (in Make or Soong).
192 // This does not completely prevent installation of the overridden binaries, but if both
193 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
194 // from PRODUCT_PACKAGES.
195 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800196}
197
Colin Cross30e076a2015-04-13 13:58:27 -0700198type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700199 Library
200 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800201 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700202
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900203 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700204
Colin Crossfabb6082018-02-20 17:22:23 -0800205 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700206
Jaewoong Jung525443a2019-02-28 15:35:54 -0800207 overridableAppProperties overridableAppProperties
208
Colin Cross403cc152020-07-06 14:15:24 -0700209 jniLibs []jniLib
210 installPathForJNISymbols android.Path
211 embeddedJniLibs bool
212 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700213
214 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800215
216 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
217 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800218
Colin Cross70dda7e2019-10-01 22:05:35 -0700219 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700220
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700221 onDeviceDir string
222
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800223 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700224
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900225 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100226
227 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000228
229 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000230
231 privAppAllowlist android.OptionalPath
Spandan Dasde588a32024-12-03 22:52:24 +0000232
233 requiredModuleNames []string
Colin Crosse1731a52017-12-14 11:22:55 -0800234}
235
Martin Stjernholm6d415272020-01-31 17:10:36 +0000236func (a *AndroidApp) IsInstallable() bool {
237 return Bool(a.properties.Installable)
238}
239
Colin Crossa14fb6a2024-10-23 16:57:06 -0700240func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000241 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700242}
243
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900244func (a *AndroidApp) OutputFile() android.Path {
245 return a.outputFile
246}
247
Colin Cross503c1d02020-01-28 14:00:53 -0800248func (a *AndroidApp) Certificate() Certificate {
249 return a.certificate
250}
251
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700252func (a *AndroidApp) JniCoverageOutputs() android.Paths {
253 return a.jniCoverageOutputs
254}
255
Andrei Onea580636b2022-08-17 16:53:46 +0000256func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
257 return a.privAppAllowlist
258}
259
Colin Crossa97c5d32018-03-28 14:58:31 -0700260var _ AndroidLibraryDependency = (*AndroidApp)(nil)
261
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900262type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800263 Pem, Key android.Path
264 presigned bool
265}
266
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700267var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800268
269func (c Certificate) AndroidMkString() string {
270 if c.presigned {
271 return "PRESIGNED"
272 } else {
273 return c.Pem.String()
274 }
Colin Cross30e076a2015-04-13 13:58:27 -0700275}
276
Colin Cross46c9b8b2017-06-22 16:51:17 -0700277func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900278 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700279 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
280 }
281
Jiyong Parkf1691d22021-03-29 20:11:58 +0900282 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000283 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
284 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100285 if sdkDep.hasFrameworkLibs() {
286 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700287 }
Colin Crossa4f08812018-10-02 22:03:40 -0700288
Jiyong Park92315372021-04-02 08:45:46 +0900289 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700290
291 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
292 ctx.PropertyErrorf("jni_uses_sdk_apis",
293 "can only be set for modules that do not set sdk_version")
294 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
295 ctx.PropertyErrorf("jni_uses_platform_apis",
296 "can only be set for modules that set sdk_version")
297 }
298
Colin Crossa4f08812018-10-02 22:03:40 -0700299 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700300 variation := append(jniTarget.Variations(),
301 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000302
Jiyong Park92d84042024-05-17 22:58:54 +0000303 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
304 // Many factors are considered here.
305 // 1. Basically, the selection follows whether the app has sdk_version set or not.
306 jniUsesSdkVariant := usesSDK
307 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
308 if Bool(a.appProperties.Jni_uses_sdk_apis) {
309 jniUsesSdkVariant = true
310 }
311 if Bool(a.appProperties.Jni_uses_platform_apis) {
312 jniUsesSdkVariant = false
313 }
314 // 3. Then the use of SDK variant is again prohibited for the following cases:
315 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
316 // partition (not only the app) is considered unbudled, there's no need to use the
317 // SDK variant.
318 // 3.2. the app doesn't support embedding the JNI libs
319 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
320 jniUsesSdkVariant = false
321 }
322 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000323 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
324 }
Jiyong Park92d84042024-05-17 22:58:54 +0000325
326 // Use the installable dep tag when the JNIs are not embedded
327 var tag dependencyTag
328 if a.shouldEmbedJnis(ctx) {
329 tag = jniLibTag
330 } else {
331 tag = jniInstallTag
332 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000333 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700334 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000335 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
336 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
337 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700338}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700339
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700340func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800341 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700342 if cert != "" {
343 ctx.AddDependency(ctx.Module(), certificateTag, cert)
344 }
345
Andrei Onea580636b2022-08-17 16:53:46 +0000346 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000347 // There are a few uids that are explicitly considered privileged regardless of their
348 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
349 // but for now, allow it not to be in priv-app.
350 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
351 if !privilegedBecauseOfUid {
352 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
353 }
Andrei Onea580636b2022-08-17 16:53:46 +0000354 }
355
Colin Crossbd01e2a2018-10-04 15:21:03 -0700356 for _, cert := range a.appProperties.Additional_certificates {
357 cert = android.SrcIsModule(cert)
358 if cert != "" {
359 ctx.AddDependency(ctx.Module(), certificateTag, cert)
360 } else {
361 ctx.PropertyErrorf("additional_certificates",
362 `must be names of android_app_certificate modules in the form ":module"`)
363 }
364 }
Colin Cross30e076a2015-04-13 13:58:27 -0700365}
366
Spandan Dasb0410872024-06-25 03:30:03 +0000367// TODO(b/156476221): Remove this allowlist
368var (
369 missingMinSdkVersionMtsAllowlist = []string{
370 "CellBroadcastReceiverGoogleUnitTests",
371 "CellBroadcastReceiverUnitTests",
372 "CtsBatterySavingTestCases",
373 "CtsDeviceAndProfileOwnerApp23",
374 "CtsDeviceAndProfileOwnerApp30",
375 "CtsIntentSenderApp",
376 "CtsJobSchedulerTestCases",
377 "CtsMimeMapTestCases",
378 "CtsTareTestCases",
379 "LibStatsPullTests",
380 "MediaProviderClientTests",
381 "TeleServiceTests",
382 "TestExternalImsServiceApp",
383 "TestSmsRetrieverApp",
384 "TetheringPrivilegedTests",
385 }
386)
387
388func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
389 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
390 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
391 }
392}
393
Jeongik Cha538c0d02019-07-11 15:54:27 +0900394func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000395 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000396 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
397 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700398 packageName := a.overridableAppProperties.Package_name.Get(ctx)
399 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000400 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
401 }
402 a.aapt.manifestValues.applicationId = *applicationId
403 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900404 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700405 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
406 TestOnly: true,
407 })
Colin Cross99939e92024-10-01 16:02:46 -0700408 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
409 Updatable: Bool(a.appProperties.Updatable),
410 TestHelperApp: true,
411 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900412}
413
Colin Cross46c9b8b2017-06-22 16:51:17 -0700414func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100415 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000416 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700417 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000418 a.generateJavaUsedByApex(ctx)
Colin Crossb614cd42024-10-11 12:52:21 -0700419
420 var embeddedJniLibs []android.Path
421
422 if a.embeddedJniLibs {
423 for _, jni := range a.jniLibs {
424 embeddedJniLibs = append(embeddedJniLibs, jni.path)
425 }
426 }
Colin Cross99939e92024-10-01 16:02:46 -0700427 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
Colin Crossb614cd42024-10-11 12:52:21 -0700428 Updatable: Bool(a.appProperties.Updatable),
429 TestHelperApp: false,
430 EmbeddedJNILibs: embeddedJniLibs,
Colin Cross99939e92024-10-01 16:02:46 -0700431 })
Spandan Dasde588a32024-12-03 22:52:24 +0000432
Yu Liu42f69972024-12-13 22:46:12 +0000433 android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
434
Spandan Dasde588a32024-12-03 22:52:24 +0000435 a.requiredModuleNames = a.getRequiredModuleNames(ctx)
436}
437
438func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
439 var required []string
440 if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
441 required = []string{a.productCharacteristicsRROPackageName()}
442 }
443 // Install the vendor overlay variant if this app is installed.
444 if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
445 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
446 }
447 // Install the product overlay variant if this app is installed.
448 if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
449 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
450 }
451 return required
Colin Crossae5caf52018-05-22 11:11:52 -0700452}
453
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100454func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100455 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900456 if !a.SdkVersion(ctx).Stable() {
457 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100458 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000459 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100460 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
461 }
Jooyung Han749dc692020-04-15 11:03:39 +0900462
Jiyong Park92315372021-04-02 08:45:46 +0900463 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900464 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000465 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900466 } else {
467 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
468 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000469
470 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
471 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
472 }
473 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
474 if a.deviceProperties.Target_sdk_version == nil {
475 a.SetEnforceDefaultTargetSdkVersion(true)
476 }
477 }
478
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100479 a.checkPlatformAPI(ctx)
480 a.checkSdkVersions(ctx)
481}
482
Jiyong Park970c5242024-05-17 22:58:54 +0000483// Ensures that use_embedded_native_libs are set for apk-in-apex
484func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
485 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
486 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000487 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000488
489 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
490 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
491 }
492}
493
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900494// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
495// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900496func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900497 // 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 +0000498 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900499 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
500 return
501 }
Yu Liufc8d5c12025-01-09 00:19:06 +0000502 if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
503 panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
504 }
505 commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
506 if !ok {
507 panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
508 }
Jooyung Han652d5b32020-05-20 17:12:13 +0900509 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900510 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
511 // handled properly regardless of sdk finalization.
Yu Liufc8d5c12025-01-09 00:19:06 +0000512 jniSdkVersion, err := android.SdkSpecFrom(ctx, commonInfo.MinSdkVersion).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900513 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Yu Liufc8d5c12025-01-09 00:19:06 +0000514 ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
515 commonInfo.MinSdkVersion, minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900516 return
517 }
518
519 })
520}
521
Sasha Smundak6ad77252019-05-01 13:16:22 -0700522// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800523// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700524func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900525 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800526 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900527 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800528 }
529
Jiyong Parkd044bb42024-05-15 02:09:54 +0900530 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
531 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
532 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800533}
534
Colin Cross43f08db2018-11-12 10:13:39 -0800535// Returns whether this module should have the dex file stored uncompressed in the APK.
536func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800537 if Bool(a.appProperties.Use_embedded_dex) {
538 return true
539 }
540
Colin Cross53a87f52019-06-25 13:35:30 -0700541 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
542 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900543 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000544 return true
545 }
546
Colin Cross53a87f52019-06-25 13:35:30 -0700547 if ctx.Config().UnbundledBuild() {
548 return false
549 }
550
Spandan Dase21a8d42024-01-23 23:56:29 +0000551 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700552}
553
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700554func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900555 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000556 Bool(a.appProperties.Updatable) ||
557 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000558}
559
Liz Kammer9f9fd022020-06-18 19:44:06 +0000560func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
561 aaptFlags := []string{"--rename-manifest-package " + packageName}
562 if renameResourcesPackage {
563 // Required to rename the package name in the resources table.
564 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
565 }
566 return aaptFlags
567}
568
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900569func (a *AndroidApp) OverriddenManifestPackageName() string {
570 return a.overriddenManifestPackageName
571}
572
Liz Kammer9f9fd022020-06-18 19:44:06 +0000573func (a *AndroidApp) renameResourcesPackage() bool {
574 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
575}
576
Jihoon Kang9049c272024-03-19 21:57:36 +0000577func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Yu Liu460cf372025-01-10 00:34:06 +0000578 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000579 tag := ctx.OtherModuleDependencyTag(dep)
580 switch tag {
581 case staticLibTag:
582 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
583 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
584 }
585
586 case aconfigDeclarationTag:
587 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
588 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
589 } else {
590 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
591 "flags_packages property, but %s is not aconfig_declarations module type",
592 dep.Name(),
593 )
594 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000595 }
596 })
597
Jihoon Kang9aef7772024-06-14 23:45:06 +0000598 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000599}
600
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800601func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900602 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900603 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900604 usePlatformAPI = true
605 }
606 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000607
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700608 // Ask manifest_fixer to add or update the application element indicating this app has no code.
609 a.aapt.hasNoCode = !a.hasCode(ctx)
610
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800611 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800612
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800613 // 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 +0900614 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800615 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900616 characteristics := ctx.Config().ProductAAPTCharacteristics()
617 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
618 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700619 }
620
Dan Willemsen72be5902018-10-24 20:24:57 -0700621 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
622 // Product AAPT config
623 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800624 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700625 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700626
Dan Willemsen72be5902018-10-24 20:24:57 -0700627 // Product AAPT preferred config
628 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800629 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700630 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700631 }
632
Jiyong Park7f67f482019-01-05 12:57:48 +0900633 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700634 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
635 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700636 // The product override variable has a priority over the package_name property.
637 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700638 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700639 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000640 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900641 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900642 }
643
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800644 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
645
Colin Crosse560c4a2019-03-19 16:03:11 -0700646 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800647 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100648 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000649 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
650 a.aapt.defaultManifestVersion = override
651 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000652 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000653 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100654 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000655
Rico Winda2fa2632024-03-13 13:09:17 +0100656 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200657 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000658
659 aconfigTextFilePaths := getAconfigFilePaths(ctx)
660
Alixf7a10272023-09-27 16:47:56 +0000661 a.aapt.buildActions(ctx,
662 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000663 sdkContext: android.SdkContext(a),
664 classLoaderContexts: a.classLoaderContexts,
665 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
666 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100667 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000668 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000669 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000670 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000671 },
672 )
Colin Cross30e076a2015-04-13 13:58:27 -0700673
Colin Cross46c9b8b2017-06-22 16:51:17 -0700674 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700675 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000676
677 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
678 AconfigTextFiles: aconfigTextFilePaths,
679 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800680}
Colin Cross30e076a2015-04-13 13:58:27 -0700681
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800682func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700683 var staticLibProguardFlagFiles android.Paths
684 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800685 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400686 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
687 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
688 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700689 }
690 })
691
692 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
693
Colin Cross312634e2023-11-21 15:13:56 -0800694 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200695 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100696 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
697 // live for code references and (transitively) mark these as live.
698 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
699 // dead code alive)
700 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
701 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800702}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800703
Colin Cross403cc152020-07-06 14:15:24 -0700704func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800705 var installDir string
706 if ctx.ModuleName() == "framework-res" {
707 // framework-res.apk is installed as system/framework/framework-res.apk
708 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900709 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800710 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800711 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800712 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800713 }
Colin Cross403cc152020-07-06 14:15:24 -0700714
715 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
716}
717
Rico Wind98e7fa82023-11-27 09:44:03 +0100718func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700719 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000720 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700721 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100722 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700723 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100724 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700725 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700726 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100727 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700728 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800729 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700730
Rico Wind98e7fa82023-11-27 09:44:03 +0100731 var packageResources = a.exportPackage
732
Yu Liu460cf372025-01-10 00:34:06 +0000733 javaInfo := &JavaInfo{}
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800734 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200735 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100736 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
737 aapt2Convert(ctx, protoFile, packageResources, "proto")
738 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
739 }
740
Colin Cross4eae06d2023-06-20 22:40:02 -0700741 var extraSrcJars android.Paths
742 var extraClasspathJars android.Paths
743 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800744 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700745 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
746 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
747 // classpath when compiling everything else, and add it to the final classes jar.
748 extraClasspathJars = android.Paths{a.aapt.rJar}
749 extraCombinedJars = android.Paths{a.aapt.rJar}
750 } else {
751 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
752 // R.java files for the app's package and the packages from all transitive static android_library
753 // dependencies. Compile the srcjar alongside the rest of the sources.
754 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
755 }
756
Yu Liu460cf372025-01-10 00:34:06 +0000757 javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200758 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100759 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
760 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
761 packageResources = binaryResources
762 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800763 }
Yu Liu460cf372025-01-10 00:34:06 +0000764 if javaInfo != nil {
765 setExtraJavaInfo(ctx, a, javaInfo)
766 android.SetProvider(ctx, JavaInfoProvider, javaInfo)
767 }
Colin Cross30e076a2015-04-13 13:58:27 -0700768
Rico Wind98e7fa82023-11-27 09:44:03 +0100769 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800770}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800771
Sam Delmerico82602492022-06-10 17:05:42 +0000772func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700773 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000774 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700775 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700776 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700777 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800778 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000779 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700780 for _, jni := range jniLibs {
781 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700782 // Only collect coverage for the first target arch if this is a multilib target.
783 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
784 // data file path collisions since the current coverage file path format doesn't contain
785 // arch-related strings. This is fine for now though; the code coverage team doesn't use
786 // multi-arch targets such as test_suite_* for coverage collections yet.
787 //
788 // Work with the team to come up with a new format that handles multilib modules properly
789 // and change this.
790 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700791 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700792 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
793 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700794 }
795 }
Colin Cross403cc152020-07-06 14:15:24 -0700796 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700797 }
798 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800799 return jniJarFile
800}
Colin Crossa4f08812018-10-02 22:03:40 -0700801
Colin Cross403cc152020-07-06 14:15:24 -0700802func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
803 var jniSymbols android.RuleBuilderInstalls
804 for _, jniLib := range a.jniLibs {
805 if jniLib.unstrippedFile != nil {
806 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
807 From: jniLib.unstrippedFile,
808 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
809 })
810 }
811 }
812 return jniSymbols
813}
814
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700815// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
816// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700817func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
818 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700819 if android.SrcIsModule(certPropValue) == "" {
820 var mainCert Certificate
821 if certPropValue != "" {
822 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
823 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800824 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
825 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700826 }
827 } else {
828 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800829 mainCert = Certificate{
830 Pem: pem,
831 Key: key,
832 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700833 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700834 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700835 }
836
Colin Crossbc2c8a72022-09-14 12:45:42 -0700837 if len(certificates) > 0 {
838 mainCertificate = certificates[0]
839 } else {
840 // This can be reached with an empty certificate list if AllowMissingDependencies is set
841 // and the certificate property for this module is a module reference to a missing module.
842 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
843 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
844 }
845 // Set a certificate to avoid panics later when accessing it.
846 mainCertificate = Certificate{
847 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000848 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700849 }
850 }
851
Zyan Wub7550aa2023-05-18 15:46:31 +0800852 if !m.Platform() {
853 certPath := mainCertificate.Pem.String()
854 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
855 if strings.HasPrefix(certPath, systemCertPath) {
856 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
857 allowed := ctx.Config().EnforceSystemCertificateAllowList()
858
859 if enforceSystemCert && !inList(m.Name(), allowed) {
860 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
861 }
862 }
863 }
864
Colin Crossbc2c8a72022-09-14 12:45:42 -0700865 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800866}
867
Jooyung Han39ee1192020-03-23 20:21:11 +0900868func (a *AndroidApp) InstallApkName() string {
869 return a.installApkName
870}
871
Sam Delmerico15809f82023-05-15 17:21:47 -0400872func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000873 if a.appProperties.Privapp_allowlist == nil {
874 return nil
875 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400876
877 isOverrideApp := a.GetOverriddenBy() != ""
878 if !isOverrideApp {
879 // if this is not an override, we don't need to rewrite the existing privapp allowlist
880 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
881 }
882
Cole Faust258b96f2024-10-04 10:48:24 -0700883 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
884 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000885 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
886 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400887
Cole Faust258b96f2024-10-04 10:48:24 -0700888 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000889 fileName := "privapp_allowlist_" + packageName + ".xml"
Cole Faust4e9f5922024-11-13 16:09:23 -0800890 outPath := android.PathForModuleOut(ctx, fileName)
Andrei Onea580636b2022-08-17 16:53:46 +0000891 ctx.Build(pctx, android.BuildParams{
892 Rule: modifyAllowlist,
893 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
894 Output: outPath,
895 Args: map[string]string{
896 "packageName": packageName,
897 },
898 })
Cole Faust4e9f5922024-11-13 16:09:23 -0800899 return outPath
Andrei Onea580636b2022-08-17 16:53:46 +0000900}
901
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800902func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700903 var apkDeps android.Paths
904
Colin Crossff694a82023-12-13 15:54:49 -0800905 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
906 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700907 a.hideApexVariantFromMake = true
908 }
909
Jeongik Cha538c0d02019-07-11 15:54:27 +0900910 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
911 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
912
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000913 // Unlike installApkName, a.stem should respect base module name for override_android_app.
914 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000915 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000916
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800917 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000918 // Both android_app and override_android_app module are expected to possess
919 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
920 // from the base module. Therefore, use a.Name() which represents
921 // the module name for both android_app and override_android_app.
922 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000923 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800924
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700925 if ctx.ModuleName() == "framework-res" {
926 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700927 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900928 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700929 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
930 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800931 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700932 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700933 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700934 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700935 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700936
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100937 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000938 if a.usesLibrary.shouldDisableDexpreopt {
939 a.dexpreopter.disableDexpreopt()
940 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000941
Colin Cross61fb62e2022-06-23 10:46:28 -0700942 var noticeAssetPath android.WritablePath
943 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
944 // The rule to create the notice file can't be generated yet, as the final output path
945 // for the apk isn't known yet. Add the path where the notice file will be generated to the
946 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
947 // be generated later.
948 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
949 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
950 }
951
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000952 // For apps targeting latest target_sdk_version
953 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
954 a.SetEnforceDefaultTargetSdkVersion(true)
955 }
956
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800957 // Process all building blocks, from AAPT to certificates.
958 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100959 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700960 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100961
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100962 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700963 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000964 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
965 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700966 apkDeps = append(apkDeps, manifestCheckFile)
967 }
968
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800969 a.proguardBuildActions(ctx)
970
Colin Cross014489c2020-06-02 20:09:13 -0700971 a.linter.mergedManifest = a.aapt.mergedManifestFile
972 a.linter.manifest = a.aapt.manifestPath
973 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700974 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700975
Rico Wind98e7fa82023-11-27 09:44:03 +0100976 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800977
Jiyong Park92d84042024-05-17 22:58:54 +0000978 // No need to check the SDK version of the JNI deps unless we embed them
979 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
980 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000981 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800982
983 if ctx.Failed() {
984 return
985 }
986
Colin Crossbc2c8a72022-09-14 12:45:42 -0700987 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800988
989 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800990 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700991 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
992 var v4SignatureFile android.WritablePath = nil
993 if v4SigningRequested {
994 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
995 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700996 var lineageFile android.Path
997 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
998 lineageFile = android.PathForModuleSrc(ctx, lineage)
999 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -04001000 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
1001
Rico Wind98e7fa82023-11-27 09:44:03 +01001002 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001003 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -07001004 if v4SigningRequested {
1005 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1006 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001007
Colin Cross61fb62e2022-06-23 10:46:28 -07001008 if a.aapt.noticeFile.Valid() {
1009 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -07001010 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -07001011 android.BuildNoticeHtmlOutputFromLicenseMetadata(
1012 ctx, noticeFile, "", "",
1013 []string{
1014 a.installDir.String() + "/",
1015 android.PathForModuleInstall(ctx).String() + "/",
1016 a.outputFile.String(),
1017 })
Bob Badoureef4c1c2022-05-16 12:20:04 -07001018 builder := android.NewRuleBuilder(pctx, ctx)
1019 builder.Command().Text("cp").
1020 Input(noticeFile).
1021 Output(noticeAssetPath)
1022 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -07001023 }
1024
Colin Crosse560c4a2019-03-19 16:03:11 -07001025 for _, split := range a.aapt.splits {
1026 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -08001027 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001028 if v4SigningRequested {
1029 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
1030 }
Rico Wind98e7fa82023-11-27 09:44:03 +01001031 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -07001032 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -07001033 if v4SigningRequested {
1034 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1035 }
Colin Crosse560c4a2019-03-19 16:03:11 -07001036 }
1037
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001038 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -07001039 bundleFile := android.PathForModuleOut(ctx, "base.zip")
1040 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1041 a.bundleFile = bundleFile
1042
Andrei Onea580636b2022-08-17 16:53:46 +00001043 allowlist := a.createPrivappAllowlist(ctx)
1044 if allowlist != nil {
1045 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1046 }
1047
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001048 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001049 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1050 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001051 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001052 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1053 allowlistInstallFilename := a.installApkName + ".xml"
1054 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001055 }
1056
Colin Cross09ad3a62023-11-15 12:29:33 -08001057 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001058 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001059 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1060 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001061 }
Jiyong Park25b92222024-05-17 22:58:54 +00001062 // If we don't embed jni libs, make sure that those are installed along with the
1063 // app, and also place symlinks to the installed paths under the lib/<arch>
1064 // directory of the app installation directory. ex:
1065 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1066 if !a.embeddedJniLibs {
1067 for _, jniLib := range jniLibs {
1068 archStr := jniLib.target.Arch.ArchType.String()
1069 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1070 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001071 // install the symlink itself
1072 symlinkName := installedLib.Base()
1073 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1074 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1075 }
1076 }
1077 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001078 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001079 }
Artur Satayev1111b842020-04-27 19:05:28 +01001080
Colin Crossa6182ab2024-08-21 10:47:44 -07001081 ctx.CheckbuildFile(a.outputFile)
1082
Artur Satayev1111b842020-04-27 19:05:28 +01001083 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001084
1085 providePrebuiltInfo(ctx,
1086 prebuiltInfoProps{
1087 baseModuleName: a.BaseModuleName(),
1088 isPrebuilt: false,
1089 },
1090 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001091
1092 a.setOutputFiles(ctx)
1093}
1094
1095func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1096 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1097 if a.aaptSrcJar != nil {
1098 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1099 }
1100 if a.rJar != nil {
1101 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1102 }
1103 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1104 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1105 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1106 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001107}
1108
Colin Crossc2d24052020-05-13 11:05:02 -07001109type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001110 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001111 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001112 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1113}
1114
1115func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1116 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001117 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001118
Colin Crossc2d24052020-05-13 11:05:02 -07001119 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001120 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1121 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001122 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001123 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
Spandan Das10c41362024-12-03 01:33:09 +00001124 checkNativeSdkVersion, func(parent, child android.Module) bool {
1125 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
1126 childLinkable, _ := child.(cc.LinkableInterface)
1127 parentLinkable, _ := parent.(cc.LinkableInterface)
1128 useStubsOfDep := childLinkable.IsStubs()
1129 if apkInApex && parentLinkable != nil {
Ivan Lozano9eaacc82024-10-30 14:28:17 +00001130 vintf := childLinkable.(cc.VersionedLinkableInterface).VersionedInterface()
Spandan Das10c41362024-12-03 01:33:09 +00001131 // APK-in-APEX
1132 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
Ivan Lozano9eaacc82024-10-30 14:28:17 +00001133 useStubsOfDep = useStubsOfDep || (vintf.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child))
Spandan Das10c41362024-12-03 01:33:09 +00001134 }
1135 return !childLinkable.IsNdk(ctx.Config()) && !useStubsOfDep
1136 })
Makoto Onuki2ca84272024-02-10 00:15:21 +00001137
1138 var certificates []Certificate
1139
Colin Crossb614cd42024-10-11 12:52:21 -07001140 var directImplementationDeps android.Paths
1141 var transitiveImplementationDeps []depset.DepSet[android.Path]
Makoto Onuki2ca84272024-02-10 00:15:21 +00001142 ctx.VisitDirectDeps(func(module android.Module) {
1143 otherName := ctx.OtherModuleName(module)
1144 tag := ctx.OtherModuleDependencyTag(module)
1145
1146 if tag == certificateTag {
1147 if dep, ok := module.(*AndroidAppCertificate); ok {
1148 certificates = append(certificates, dep.Certificate)
1149 } else {
1150 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1151 }
1152 }
Colin Crossb614cd42024-10-11 12:52:21 -07001153
1154 if IsJniDepTag(tag) {
1155 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1156 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1157 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1158 }
1159 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001160 })
Colin Crossb614cd42024-10-11 12:52:21 -07001161 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1162 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1163 })
1164
Makoto Onuki2ca84272024-02-10 00:15:21 +00001165 return jniLib, prebuiltJniPackages, certificates
1166}
1167
1168func collectJniDeps(ctx android.ModuleContext,
1169 shouldCollectRecursiveNativeDeps bool,
1170 checkNativeSdkVersion bool,
Spandan Das10c41362024-12-03 01:33:09 +00001171 filter func(parent, child android.Module) bool) ([]jniLib, android.Paths) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001172 var jniLibs []jniLib
1173 var prebuiltJniPackages android.Paths
1174 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001175
Peter Collingbournead84f972019-12-17 16:46:18 -08001176 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001177 otherName := ctx.OtherModuleName(module)
1178 tag := ctx.OtherModuleDependencyTag(module)
1179
Colin Crossf0913fb2020-07-29 12:59:39 -07001180 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001181 if dep, ok := module.(cc.LinkableInterface); ok {
Spandan Das10c41362024-12-03 01:33:09 +00001182 if filter != nil && !filter(parent, module) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001183 return false
1184 }
1185
Colin Crossa4f08812018-10-02 22:03:40 -07001186 lib := dep.OutputFile()
1187 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001188 path := lib.Path()
1189 if seenModulePaths[path.String()] {
1190 return false
1191 }
1192 seenModulePaths[path.String()] = true
1193
1194 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1195 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1196 otherName)
1197 }
1198
Colin Crossa4f08812018-10-02 22:03:40 -07001199 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001200 name: ctx.OtherModuleName(module),
1201 path: path,
1202 target: module.Target(),
1203 coverageFile: dep.CoverageOutputFile(),
1204 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001205 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001206 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001207 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001208 } else if ctx.Config().AllowMissingDependencies() {
1209 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001210 } else {
1211 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1212 }
1213 } else {
1214 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001215 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001216
1217 return shouldCollectRecursiveNativeDeps
1218 }
1219
Colin Cross313aa542023-12-13 13:47:44 -08001220 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001221 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1222 }
1223
Peter Collingbournead84f972019-12-17 16:46:18 -08001224 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001225 })
1226
Makoto Onuki2ca84272024-02-10 00:15:21 +00001227 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001228}
1229
Colin Cross8bf14fc2024-09-25 16:41:31 -07001230func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001231 ctx.WalkDeps(func(child, parent android.Module) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001232 // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
1233 // heuristics to every transitive dependency, when it should probably be using the heuristics of the
1234 // immediate parent.
1235 isExternal := !a.OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
Artur Satayev1111b842020-04-27 19:05:28 +01001236 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001237 if !do(ctx, parent, am, isExternal) {
1238 return false
1239 }
Artur Satayev1111b842020-04-27 19:05:28 +01001240 }
1241 return !isExternal
1242 })
1243}
1244
1245func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1246 if ctx.Host() {
1247 return
1248 }
1249
1250 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross9cf55a52024-12-05 14:26:03 -08001251 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001252 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001253
1254 // Skip dependencies that are only available to APEXes; they are developed with updatability
1255 // in mind and don't need manual approval.
1256 if to.(android.ApexModule).NotAvailableForPlatform() {
1257 return true
1258 }
1259
Artur Satayev1111b842020-04-27 19:05:28 +01001260 if info, exist := depsInfo[depName]; exist {
1261 info.From = append(info.From, from.Name())
1262 info.IsExternal = info.IsExternal && externalDep
1263 depsInfo[depName] = info
1264 } else {
1265 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001266 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001267 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001268 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001269 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1270 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001271 }
Jiyong Park92315372021-04-02 08:45:46 +09001272 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1273 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1274 // string
1275 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001276 toMinSdkVersion = v
1277 }
Artur Satayev1111b842020-04-27 19:05:28 +01001278 }
1279 depsInfo[depName] = android.ApexModuleDepInfo{
1280 To: depName,
1281 From: []string{from.Name()},
1282 IsExternal: externalDep,
1283 MinSdkVersion: toMinSdkVersion,
1284 }
1285 }
Jooyung Han749dc692020-04-15 11:03:39 +09001286 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001287 })
1288
Jiyong Park92315372021-04-02 08:45:46 +09001289 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001290}
1291
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001292func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1293 return a.appProperties.EnforceDefaultTargetSdkVersion
1294}
1295
1296func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1297 a.appProperties.EnforceDefaultTargetSdkVersion = val
1298}
1299
Artur Satayev849f8442020-04-28 14:57:42 +01001300func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001301 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001302}
1303
Colin Cross0ea8ba82019-06-06 14:33:29 -07001304func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001305 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1306 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001307 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001308 }
Cole Fausteb9c1482024-11-18 16:49:19 -08001309 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001310}
1311
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001312func (a *AndroidApp) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
1313 if IsJniDepTag(tag) {
Jiyong Park0f80c182020-01-31 02:49:53 +09001314 return true
1315 }
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001316 return a.Library.OutgoingDepIsInSameApex(tag)
Jiyong Park0f80c182020-01-31 02:49:53 +09001317}
1318
Jiyong Parkf7487312019-10-17 12:54:30 +09001319func (a *AndroidApp) Privileged() bool {
1320 return Bool(a.appProperties.Privileged)
1321}
1322
Colin Crosse1a85552024-06-14 12:17:37 -07001323func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001324 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001325}
1326
Ivan Lozanod7586b62021-04-01 09:49:36 -04001327func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001328 a.appProperties.PreventInstall = true
1329}
1330
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001331func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1332 a.appProperties.IsCoverageVariant = coverage
1333}
1334
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001335func (a *AndroidApp) EnableCoverageIfNeeded() {}
1336
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001337var _ cc.Coverage = (*AndroidApp)(nil)
1338
Cole Faustb36d31d2024-08-27 16:04:28 -07001339func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1340 a.Library.IDEInfo(ctx, dpInfo)
1341 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001342}
1343
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001344func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1345 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1346}
1347
1348func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1349 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1350}
1351
Colin Cross1b16b0e2019-02-12 14:41:32 -08001352// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001353func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001354 module := &AndroidApp{}
1355
Liz Kammera7a64f32020-07-09 15:16:41 -07001356 module.Module.dexProperties.Optimize.EnabledByDefault = true
1357 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001358 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001359
Colin Crossae5caf52018-05-22 11:11:52 -07001360 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001361 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001362 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001363
Colin Crossce6734e2020-06-15 16:09:53 -07001364 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001365 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001366 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001367 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001368 &module.overridableAppProperties,
1369 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001370
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001371 module.usesLibrary.enforce = true
1372
Colin Crossa4f08812018-10-02 22:03:40 -07001373 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1374 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001375 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001376 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001377
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001378 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1379 a := ctx.Module().(*AndroidApp)
1380
1381 characteristics := ctx.Config().ProductAAPTCharacteristics()
1382 if characteristics == "default" || characteristics == "" {
1383 module.appProperties.Generate_product_characteristics_rro = nil
1384 // no need to create RRO
1385 return
1386 }
1387
1388 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1389 return
1390 }
1391
1392 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1393 rroManifestName := rroPackageName + "_manifest"
1394
1395 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1396 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1397
1398 rroManifestProperties := struct {
1399 Name *string
1400 Tools []string
1401 Out []string
1402 Srcs []string
1403 Cmd *string
1404 }{
1405 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001406 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001407 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001408 Srcs: []string{":" + a.Name() + "{.apk}"},
1409 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001410 }
Cole Fauste19d3352024-10-17 10:30:57 -07001411 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001412
1413 rroProperties := struct {
1414 Name *string
1415 Filter_product *string
1416 Aaptflags []string
1417 Manifest *string
Cole Faust5b989772024-11-06 11:03:16 -08001418 Resource_dirs proptools.Configurable[[]string]
Jihoon Kangf62f4222024-10-21 23:06:41 +00001419 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001420 }{
1421 Name: proptools.StringPtr(rroPackageName),
1422 Filter_product: proptools.StringPtr(characteristics),
1423 Aaptflags: []string{"--auto-add-overlay"},
1424 Manifest: proptools.StringPtr(":" + rroManifestName),
1425 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001426 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001427 }
优秀d75e9982024-05-09 07:15:55 +00001428 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1429 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1430 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1431 }
1432 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001433 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
Spandan Dasde588a32024-12-03 22:52:24 +00001434
1435 })
1436
1437 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1438 createInternalRuntimeOverlays(ctx, module.ModuleBase)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001439 })
1440
Colin Cross36242852017-06-23 15:06:31 -07001441 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001442}
Colin Crossae5caf52018-05-22 11:11:52 -07001443
Spandan Das71be42d2024-11-20 18:34:16 +00001444func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1445 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1446}
1447
Spandan Dasde588a32024-12-03 22:52:24 +00001448type createModuleContext interface {
1449 android.EarlyModuleContext
1450 CreateModule(android.ModuleFactory, ...interface{}) android.Module
1451}
1452
1453func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
1454 if !ctx.Config().HasDeviceProduct() {
1455 return
1456 }
1457 // vendor
1458 vendorOverlayProps := struct {
1459 Name *string
1460 Base *string
1461 Vendor *bool
1462 Product_specific *bool
1463 System_ext_specific *bool
1464 Manifest *string
1465 Sdk_version *string
1466 Compile_multilib *string
1467 Enabled proptools.Configurable[bool]
1468 }{
1469 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")),
1470 Base: proptools.StringPtr(a.Name()),
1471 Vendor: proptools.BoolPtr(true),
1472 Product_specific: proptools.BoolPtr(false),
1473 System_ext_specific: proptools.BoolPtr(false),
1474 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1475 Sdk_version: proptools.StringPtr("current"),
1476 Compile_multilib: proptools.StringPtr("first"),
1477 Enabled: a.EnabledProperty().Clone(),
1478 }
1479 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
1480
1481 // product
1482 productOverlayProps := struct {
1483 Name *string
1484 Base *string
1485 Vendor *bool
1486 Proprietary *bool
1487 Soc_specific *bool
1488 Product_specific *bool
1489 System_ext_specific *bool
1490 Manifest *string
1491 Sdk_version *string
1492 Compile_multilib *string
1493 Enabled proptools.Configurable[bool]
1494 }{
1495 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
1496 Base: proptools.StringPtr(a.Name()),
1497 Vendor: proptools.BoolPtr(false),
1498 Proprietary: proptools.BoolPtr(false),
1499 Soc_specific: proptools.BoolPtr(false),
1500 Product_specific: proptools.BoolPtr(true),
1501 System_ext_specific: proptools.BoolPtr(false),
1502 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1503 Sdk_version: proptools.StringPtr("current"),
1504 Compile_multilib: proptools.StringPtr("first"),
1505 Enabled: a.EnabledProperty().Clone(),
1506 }
1507 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
1508}
1509
Alix96ea88452023-08-31 15:48:23 +00001510// A dictionary of values to be overridden in the manifest.
1511type Manifest_values struct {
1512 // Overrides the value of package_name in the manifest
1513 ApplicationId *string
1514}
1515
Colin Crossae5caf52018-05-22 11:11:52 -07001516type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001517 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001518 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001519
Seth Moorec6f4b532023-02-02 13:22:26 -08001520 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001521 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001522
1523 // If specified, the mainline module package name in the test config is overwritten by it.
1524 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001525
1526 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001527}
1528
1529type AndroidTest struct {
1530 AndroidApp
1531
1532 appTestProperties appTestProperties
1533
1534 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001535
Dan Shi95d19422020-08-15 12:24:26 -07001536 testConfig android.Path
1537 extraTestConfigs android.Paths
1538 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001539}
1540
Jaewoong Jung0949f312019-09-11 10:25:18 -07001541func (a *AndroidTest) InstallInTestcases() bool {
1542 return true
1543}
1544
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001545type androidTestApp interface {
1546 includedInTestSuite(searchPrefix string) bool
1547}
1548
1549func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1550 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1551}
1552
1553func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1554 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1555}
1556
Colin Crossae5caf52018-05-22 11:11:52 -07001557func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001558 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001559 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001560 if a.appTestProperties.Instrumentation_target_package != nil {
1561 a.additionalAaptFlags = append(a.additionalAaptFlags,
1562 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1563 } else if a.appTestProperties.Instrumentation_for != nil {
1564 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001565 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1566 if overridden {
1567 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1568 }
1569 }
Alix96ea88452023-08-31 15:48:23 +00001570 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1571 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001572 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1573 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001574 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1575 }
1576 a.aapt.manifestValues.applicationId = *applicationId
1577 }
Colin Crossae5caf52018-05-22 11:11:52 -07001578 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001579
Jiyong Parkf528b702024-12-30 16:01:58 +09001580 for _, c := range a.testProperties.Test_options.Tradefed_options {
1581 configs = append(configs, c)
1582 }
easoncylee5bcff5d2020-04-30 14:57:06 +08001583 for _, module := range a.testProperties.Test_mainline_modules {
1584 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1585 }
1586
Jaewoong Jung39982342020-01-14 10:27:18 -08001587 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001588 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1589 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001590 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001591 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001592 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001593 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1594 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001595 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001596
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001597 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001598 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001599 OutputFile: a.OutputFile(),
1600 TestConfig: a.testConfig,
1601 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001602 TestSuites: a.testProperties.Test_suites,
1603 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001604 LocalCertificate: a.certificate.AndroidMkString(),
1605 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001606 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1607 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001608 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001609 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1610 TestOnly: true,
1611 TopLevelTarget: true,
1612 })
1613
Colin Cross303e21f2018-08-07 16:49:25 -07001614}
1615
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001616func testcaseRel(paths android.Paths) []string {
1617 relPaths := []string{}
1618 for _, p := range paths {
1619 relPaths = append(relPaths, p.Rel())
1620 }
1621 return relPaths
1622}
1623
Jaewoong Jung39982342020-01-14 10:27:18 -08001624func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1625 if testConfig == nil {
1626 return nil
1627 }
1628
1629 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001630 rule := android.NewRuleBuilder(pctx, ctx)
1631 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001632 fixNeeded := false
1633
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001634 // 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 -08001635 if ctx.ModuleName() != a.installApkName {
1636 fixNeeded = true
1637 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1638 }
1639
Cole Faust258b96f2024-10-04 10:48:24 -07001640 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1641 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001642 fixNeeded = true
1643 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001644 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001645 }
1646
Seth Moorec6f4b532023-02-02 13:22:26 -08001647 if a.appTestProperties.Mainline_package_name != nil {
1648 fixNeeded = true
1649 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1650 }
1651
Jaewoong Jung39982342020-01-14 10:27:18 -08001652 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001653 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001654 return fixedConfig
1655 }
1656 return testConfig
1657}
1658
Yihan Dong8be09c22024-08-29 15:32:13 +08001659func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1660 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1661 // Instrument the android_test_helper target to log potential API calls at the run time.
1662 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1663 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1664 a.setApiMapper(true)
1665 }
1666 a.AndroidApp.DepsMutator(ctx)
1667}
1668
Colin Cross303e21f2018-08-07 16:49:25 -07001669func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001670 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1671 // Instrument the android_test_helper target to log potential API calls at the run time.
1672 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1673 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1674 a.setApiMapper(true)
1675 }
Colin Cross303e21f2018-08-07 16:49:25 -07001676 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001677}
1678
1679func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1680 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001681 if a.appTestProperties.Instrumentation_for != nil {
1682 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1683 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1684 // use instrumentationForTag instead of libTag.
1685 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1686 }
Colin Crossae5caf52018-05-22 11:11:52 -07001687}
1688
Colin Cross1b16b0e2019-02-12 14:41:32 -08001689// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1690// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001691func AndroidTestFactory() android.Module {
1692 module := &AndroidTest{}
1693
Jared Duke63a3da92022-06-02 19:11:14 +00001694 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001695
1696 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001697 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001698 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001699 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1700 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001701 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001702 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001703
Colin Crossce6734e2020-06-15 16:09:53 -07001704 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001705 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001706 &module.aaptProperties,
1707 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001708 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001709 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001710 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001711
Colin Crossa4f08812018-10-02 22:03:40 -07001712 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1713 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001714 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001715
Colin Crossae5caf52018-05-22 11:11:52 -07001716 return module
1717}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001718
Colin Cross252fc6f2018-10-04 15:22:03 -07001719type appTestHelperAppProperties struct {
1720 // list of compatibility suites (for example "cts", "vts") that the module should be
1721 // installed into.
1722 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001723
1724 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1725 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1726 // explicitly.
1727 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001728
1729 // Install the test into a folder named for the module in all test suites.
1730 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001731
1732 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001733}
1734
1735type AndroidTestHelperApp struct {
1736 AndroidApp
1737
1738 appTestHelperAppProperties appTestHelperAppProperties
1739}
1740
Jaewoong Jung326a9412019-11-21 10:41:00 -08001741func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1742 return true
1743}
1744
Colin Cross1b16b0e2019-02-12 14:41:32 -08001745// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1746// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1747// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001748func AndroidTestHelperAppFactory() android.Module {
1749 module := &AndroidTestHelperApp{}
1750
Jared Duke63a3da92022-06-02 19:11:14 +00001751 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001752 module.Module.dexProperties.Optimize.EnabledByDefault = true
Christoffer Adamsenc8fd1f12025-01-06 19:04:03 +01001753 module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
1754 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross252fc6f2018-10-04 15:22:03 -07001755
1756 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001757 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1758 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001759 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001760 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001761
Colin Crossce6734e2020-06-15 16:09:53 -07001762 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001763 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001764 &module.aaptProperties,
1765 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001766 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001767 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001768
1769 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1770 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001771 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001772 return module
1773}
1774
Colin Crossbd01e2a2018-10-04 15:21:03 -07001775type AndroidAppCertificate struct {
1776 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001777
Colin Crossbd01e2a2018-10-04 15:21:03 -07001778 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001779 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001780}
1781
1782type AndroidAppCertificateProperties struct {
1783 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1784 Certificate *string
1785}
1786
Colin Cross1b16b0e2019-02-12 14:41:32 -08001787// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1788// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001789func AndroidAppCertificateFactory() android.Module {
1790 module := &AndroidAppCertificate{}
1791 module.AddProperties(&module.properties)
1792 android.InitAndroidModule(module)
1793 return module
1794}
1795
Colin Crossbd01e2a2018-10-04 15:21:03 -07001796func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1797 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001798 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001799 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1800 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001801 }
1802}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001803
1804type OverrideAndroidApp struct {
1805 android.ModuleBase
1806 android.OverrideModuleBase
1807}
1808
Sasha Smundak613cbb12020-06-05 10:27:23 -07001809func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001810 // All the overrides happen in the base module.
1811 // TODO(jungjw): Check the base module type.
1812}
1813
1814// override_android_app is used to create an android_app module based on another android_app by overriding
1815// some of its properties.
1816func OverrideAndroidAppModuleFactory() android.Module {
1817 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001818 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001819 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001820 &overridableAppProperties{},
1821 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001822
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001823 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001824 android.InitOverrideModule(m)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001825 android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) {
Spandan Dasde588a32024-12-03 22:52:24 +00001826 createInternalRuntimeOverlays(ctx, m.ModuleBase)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001827 }, 1) // Run after soong config load hoook
Spandan Dasde588a32024-12-03 22:52:24 +00001828
Jaewoong Jung525443a2019-02-28 15:35:54 -08001829 return m
1830}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001831
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001832type OverrideAndroidTest struct {
1833 android.ModuleBase
1834 android.OverrideModuleBase
1835}
1836
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001837func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001838 // All the overrides happen in the base module.
1839 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001840 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1841 TestOnly: true,
1842 TopLevelTarget: true,
1843 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001844}
1845
1846// override_android_test is used to create an android_app module based on another android_test by overriding
1847// some of its properties.
1848func OverrideAndroidTestModuleFactory() android.Module {
1849 m := &OverrideAndroidTest{}
1850 m.AddProperties(&overridableAppProperties{})
1851 m.AddProperties(&appTestProperties{})
1852
1853 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1854 android.InitOverrideModule(m)
1855 return m
1856}
1857
Colin Cross50ddcc42019-05-16 12:28:22 -07001858type UsesLibraryProperties struct {
1859 // 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 -07001860 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001861
1862 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1863 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001864 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001865
1866 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1867 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1868 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001869
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001870 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1871 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1872 // normally is the same as the module name, but there are exceptions.
1873 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001874
1875 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1876 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1877 // added to the APK's manifest's <uses-library> elements.
1878 //
1879 // Care must be taken when using this as it could result in runtime errors if the APK actually
1880 // uses classes provided by the library and which are not provided in any other way.
1881 //
1882 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1883 // android.test.base shared library (and related libraries) but which depend on some common
1884 // libraries that depend on the android.test.base library. Without this those tests will end up
1885 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1886 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1887 // test altogether by providing access to classes that the tests were not expecting. Those tests
1888 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1889 // with the classes provided by the android.test.base library.
1890 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001891
1892 // The module names of optional uses-library libraries that are missing from the source tree.
1893 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001894}
1895
1896// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1897// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1898// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1899// with knowledge of their shared libraries.
1900type usesLibrary struct {
1901 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001902
1903 // Whether to enforce verify_uses_library check.
1904 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001905
1906 // Whether dexpreopt should be disabled
1907 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001908}
1909
Colin Cross4a80a152022-12-21 21:51:52 -08001910func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001911 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07001912 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001913 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1914 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001915 // Only add these extra dependencies if the module is an app that depends on framework
1916 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001917 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001918 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001919 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1920 // class loader context for dex2oat. Add them as a dependency with a special tag.
1921 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1922 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1923 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001924 }
Cole Faust64f2d842024-10-17 13:28:34 -07001925 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001926 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001927 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07001928 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001929 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001930 }
1931}
1932
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001933// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001934func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07001935 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001936 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001937 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001938 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1939 }
1940 return exists
1941 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001942 return optionalUsesLibs
1943}
1944
Ulya Trafimovich24446712021-07-15 14:59:34 +01001945// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1946// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001947func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1948 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001949
1950 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1951 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1952 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1953 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001954 }
1955
Ulya Trafimovich24446712021-07-15 14:59:34 +01001956 ctx.VisitDirectDeps(func(m android.Module) {
1957 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1958 if !isUsesLibTag {
1959 return
1960 }
1961
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001962 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001963
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001964 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1965 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1966 // from implementation libraries by their name, which is different as it has a suffix.
1967 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1968 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1969 return
1970 }
1971 }
1972
Ulya Trafimovich24446712021-07-15 14:59:34 +01001973 if lib, ok := m.(UsesLibraryDependency); ok {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001974 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1975 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1976 // This will be restricted to optional_uses_libs
1977 if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
1978 u.shouldDisableDexpreopt = true
1979 return
1980 }
1981 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001982 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001983 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001984 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001985 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001986 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001987 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001988 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001989 } else if ctx.Config().AllowMissingDependencies() {
1990 ctx.AddMissingDependencies([]string{dep})
1991 } else {
1992 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1993 }
1994 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001995 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001996}
1997
1998// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1999// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
2000// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07002001func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
2002 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
2003 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002004 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002005}
2006
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002007// 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 -07002008func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
2009 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002010 u.usesLibraryProperties.Enforce_uses_libs = &enforce
2011}
2012
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002013// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
2014// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
2015// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
2016// extension: APKs are supposed to end with '.apk').
2017func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00002018 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002019
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002020 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07002021
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002022 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
2023 // check is not necessary, and although it is good to have, it is difficult to maintain on
2024 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
2025 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01002026 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00002027 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002028 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002029 }
2030
Colin Crossf1a035e2020-11-16 17:32:30 -08002031 rule := android.NewRuleBuilder(pctx, ctx)
2032 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07002033 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002034 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002035 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00002036 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002037
2038 if outputFile != nil {
2039 cmd.FlagWithOutput("-o ", outputFile)
2040 }
Colin Cross50ddcc42019-05-16 12:28:22 -07002041
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002042 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
2043 cmd.Flag("--enforce-uses-libraries-relax")
2044 }
2045
Jiakai Zhangf98da192024-04-15 11:15:41 +00002046 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
2047 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002048 cmd.FlagWithArg("--uses-library ", lib)
2049 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00002050 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002051 cmd.FlagWithArg("--optional-uses-library ", lib)
2052 }
2053
Jiakai Zhangf98da192024-04-15 11:15:41 +00002054 // Also add missing optional uses libs, as the manifest check expects them.
2055 // Note that what we add here are the module names of those missing libs, not library names, while
2056 // the manifest check actually expects library names. However, the case where a library is missing
2057 // and the module name != the library name is too rare for us to handle.
2058 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
2059 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
2060 }
2061
Colin Crossf1a035e2020-11-16 17:32:30 -08002062 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002063 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002064}
Colin Cross50ddcc42019-05-16 12:28:22 -07002065
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002066// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
2067// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002068func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
2069 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002070 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00002071 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07002072}
2073
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002074// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
2075// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002076func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
2077 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
2078 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07002079}