blob: 34a172e8a7ee74949aaa6b75b7b4ce94f41d4357 [file] [log] [blame]
Colin Cross30e076a2015-04-13 13:58:27 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
Jaewoong Jungf9b44652020-12-21 12:29:12 -080017// This file contains the module implementations for android_app, android_test, and some more
18// related module types, including their override variants.
Colin Cross30e076a2015-04-13 13:58:27 -070019
20import (
Jiakai Zhang4f65a032023-06-01 15:16:58 +010021 "fmt"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070022 "path/filepath"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070023 "strings"
Colin Cross30e076a2015-04-13 13:58:27 -070024
Colin Cross50ddcc42019-05-16 12:28:22 -070025 "github.com/google/blueprint"
Colin Crossa14fb6a2024-10-23 16:57:06 -070026 "github.com/google/blueprint/depset"
Colin Cross50ddcc42019-05-16 12:28:22 -070027 "github.com/google/blueprint/proptools"
28
Colin Cross635c3b02016-05-18 15:37:25 -070029 "android/soong/android"
Colin Crossa4f08812018-10-02 22:03:40 -070030 "android/soong/cc"
Ulya Trafimovichd4bcea42020-06-03 14:57:22 +010031 "android/soong/dexpreopt"
Colin Cross303e21f2018-08-07 16:49:25 -070032 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070033)
34
Colin Cross3bc7ffa2017-11-22 16:19:37 -080035func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000036 RegisterAppBuildComponents(android.InitRegistrationContext)
Andrei Onea580636b2022-08-17 16:53:46 +000037 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080038}
39
Andrei Onea580636b2022-08-17 16:53:46 +000040var (
41 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
42 blueprint.RuleParams{
43 Command: "${ModifyAllowlistCmd} $in $packageName $out",
44 CommandDeps: []string{"${ModifyAllowlistCmd}"},
45 }, "packageName")
46)
47
Jihoon Kang9aef7772024-06-14 23:45:06 +000048type FlagsPackages struct {
49 // Paths to the aconfig dump output text files that are consumed by aapt2
50 AconfigTextFiles android.Paths
51}
52
53var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
54
Paul Duffinf9b1da02019-12-18 19:51:55 +000055func RegisterAppBuildComponents(ctx android.RegistrationContext) {
56 ctx.RegisterModuleType("android_app", AndroidAppFactory)
57 ctx.RegisterModuleType("android_test", AndroidTestFactory)
58 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
59 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
60 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
61 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000062}
63
Colin Cross99939e92024-10-01 16:02:46 -070064type AppInfo struct {
65 // Updatable is set to the value of the updatable property
66 Updatable bool
67
68 // TestHelperApp is true if the module is a android_test_helper_app
69 TestHelperApp bool
Colin Crossb614cd42024-10-11 12:52:21 -070070
71 // EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
72 EmbeddedJNILibs android.Paths
Colin Cross99939e92024-10-01 16:02:46 -070073}
74
75var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
76
Colin Cross30e076a2015-04-13 13:58:27 -070077// AndroidManifest.xml merging
78// package splits
79
Colin Crossfabb6082018-02-20 17:22:23 -080080type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070081 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070082 Additional_certificates []string
83
84 // If set, create package-export.apk, which other packages can
85 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080086 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070087
Colin Cross16056062017-12-13 22:46:28 -080088 // Specifies that this app should be installed to the priv-app directory,
89 // where the system will grant it additional privileges not available to
90 // normal apps.
91 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070092
93 // list of resource labels to generate individual resource packages
94 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040095
Colin Crossa4f08812018-10-02 22:03:40 -070096 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +000097 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -070098
Colin Cross7204cf02020-05-06 17:51:39 -070099 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -0800100 // sdk_version.
101 Jni_uses_platform_apis *bool
102
Colin Cross7204cf02020-05-06 17:51:39 -0700103 // if true, use JNI libraries that link against SDK APIs even if this module does not set
104 // sdk_version.
105 Jni_uses_sdk_apis *bool
106
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700107 // STL library to use for JNI libraries.
108 Stl *string `android:"arch_variant"`
109
Colin Crosse4246ab2019-02-05 21:55:21 -0800110 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900111 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
112 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
113 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
114 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800115 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800116
117 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
118 // they are used from inside the APK at runtime.
119 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700120
Jiyong Parkd044bb42024-05-15 02:09:54 +0900121 // Forces native libraries to always be packaged into the APK,
122 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
123 // True for android_test* modules.
124 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700125
126 // If set, find and merge all NOTICE files that this module and its dependencies have and store
127 // it in the APK as an asset.
128 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700129
130 // cc.Coverage related properties
131 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700132 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100133
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000134 // It can be set to test the behaviour of default target sdk version.
135 // Only required when updatable: false. It is an error if updatable: true and this is false.
136 Enforce_default_target_sdk_version *bool
137
138 // If set, the targetSdkVersion for the target is set to the latest default API level.
139 // This would be by default false, unless updatable: true or
140 // enforce_default_target_sdk_version: true in which case this defaults to true.
141 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
142
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100143 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100144 // additional rules to make sure an app can safely be updated. Default is false.
145 // Prefer using other specific properties if build behaviour must be changed; avoid using this
146 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100147 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000148
149 // Specifies the file that contains the allowlist for this app.
150 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900151
152 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
153 // and install the RRO package to /product partition, instead of passing --product argument
154 // to aapt2. Default is false.
155 // Setting this will make this APK identical to all targets, regardless of
156 // PRODUCT_CHARACTERISTICS.
157 Generate_product_characteristics_rro *bool
158
159 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
160 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700161}
162
Jaewoong Jung525443a2019-02-28 15:35:54 -0800163// android_app properties that can be overridden by override_android_app
164type overridableAppProperties struct {
165 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
166 // or an android_app_certificate module name in the form ":module".
Cole Fausteb9c1482024-11-18 16:49:19 -0800167 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700168
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800169 // Name of the signing certificate lineage file or filegroup module.
170 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700171
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400172 // For overriding the --rotation-min-sdk-version property of apksig
173 RotationMinSdkVersion *string
174
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700175 // the package name of this app. The package name in the manifest file is used if one was not given.
Cole Faust258b96f2024-10-04 10:48:24 -0700176 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800177
178 // the logging parent of this app.
179 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000180
181 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
182 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000183
184 // Names of modules to be overridden. Listed modules can only be other binaries
185 // (in Make or Soong).
186 // This does not completely prevent installation of the overridden binaries, but if both
187 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
188 // from PRODUCT_PACKAGES.
189 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800190}
191
Colin Cross30e076a2015-04-13 13:58:27 -0700192type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700193 Library
194 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800195 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700196
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900197 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700198
Colin Crossfabb6082018-02-20 17:22:23 -0800199 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700200
Jaewoong Jung525443a2019-02-28 15:35:54 -0800201 overridableAppProperties overridableAppProperties
202
Colin Cross403cc152020-07-06 14:15:24 -0700203 jniLibs []jniLib
204 installPathForJNISymbols android.Path
205 embeddedJniLibs bool
206 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700207
208 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800209
210 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
211 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800212
Colin Cross70dda7e2019-10-01 22:05:35 -0700213 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700214
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700215 onDeviceDir string
216
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800217 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700218
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900219 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100220
221 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000222
223 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000224
225 privAppAllowlist android.OptionalPath
Spandan Dasde588a32024-12-03 22:52:24 +0000226
227 requiredModuleNames []string
Colin Crosse1731a52017-12-14 11:22:55 -0800228}
229
Martin Stjernholm6d415272020-01-31 17:10:36 +0000230func (a *AndroidApp) IsInstallable() bool {
231 return Bool(a.properties.Installable)
232}
233
Colin Crossa14fb6a2024-10-23 16:57:06 -0700234func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] {
Colin Crossab8d1382023-07-14 17:23:41 +0000235 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700236}
237
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900238func (a *AndroidApp) OutputFile() android.Path {
239 return a.outputFile
240}
241
Colin Cross503c1d02020-01-28 14:00:53 -0800242func (a *AndroidApp) Certificate() Certificate {
243 return a.certificate
244}
245
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700246func (a *AndroidApp) JniCoverageOutputs() android.Paths {
247 return a.jniCoverageOutputs
248}
249
Andrei Onea580636b2022-08-17 16:53:46 +0000250func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
251 return a.privAppAllowlist
252}
253
Colin Crossa97c5d32018-03-28 14:58:31 -0700254var _ AndroidLibraryDependency = (*AndroidApp)(nil)
255
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900256type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800257 Pem, Key android.Path
258 presigned bool
259}
260
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700261var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800262
263func (c Certificate) AndroidMkString() string {
264 if c.presigned {
265 return "PRESIGNED"
266 } else {
267 return c.Pem.String()
268 }
Colin Cross30e076a2015-04-13 13:58:27 -0700269}
270
Colin Cross46c9b8b2017-06-22 16:51:17 -0700271func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900272 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700273 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
274 }
275
Jiyong Parkf1691d22021-03-29 20:11:58 +0900276 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000277 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
278 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100279 if sdkDep.hasFrameworkLibs() {
280 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700281 }
Colin Crossa4f08812018-10-02 22:03:40 -0700282
Jiyong Park92315372021-04-02 08:45:46 +0900283 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700284
285 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
286 ctx.PropertyErrorf("jni_uses_sdk_apis",
287 "can only be set for modules that do not set sdk_version")
288 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
289 ctx.PropertyErrorf("jni_uses_platform_apis",
290 "can only be set for modules that set sdk_version")
291 }
292
Colin Crossa4f08812018-10-02 22:03:40 -0700293 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700294 variation := append(jniTarget.Variations(),
295 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000296
Jiyong Park92d84042024-05-17 22:58:54 +0000297 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
298 // Many factors are considered here.
299 // 1. Basically, the selection follows whether the app has sdk_version set or not.
300 jniUsesSdkVariant := usesSDK
301 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
302 if Bool(a.appProperties.Jni_uses_sdk_apis) {
303 jniUsesSdkVariant = true
304 }
305 if Bool(a.appProperties.Jni_uses_platform_apis) {
306 jniUsesSdkVariant = false
307 }
308 // 3. Then the use of SDK variant is again prohibited for the following cases:
309 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
310 // partition (not only the app) is considered unbudled, there's no need to use the
311 // SDK variant.
312 // 3.2. the app doesn't support embedding the JNI libs
313 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
314 jniUsesSdkVariant = false
315 }
316 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000317 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
318 }
Jiyong Park92d84042024-05-17 22:58:54 +0000319
320 // Use the installable dep tag when the JNIs are not embedded
321 var tag dependencyTag
322 if a.shouldEmbedJnis(ctx) {
323 tag = jniLibTag
324 } else {
325 tag = jniInstallTag
326 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000327 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700328 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000329 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
330 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
331 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700332}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700333
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700334func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800335 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700336 if cert != "" {
337 ctx.AddDependency(ctx.Module(), certificateTag, cert)
338 }
339
Andrei Onea580636b2022-08-17 16:53:46 +0000340 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000341 // There are a few uids that are explicitly considered privileged regardless of their
342 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
343 // but for now, allow it not to be in priv-app.
344 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
345 if !privilegedBecauseOfUid {
346 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
347 }
Andrei Onea580636b2022-08-17 16:53:46 +0000348 }
349
Colin Crossbd01e2a2018-10-04 15:21:03 -0700350 for _, cert := range a.appProperties.Additional_certificates {
351 cert = android.SrcIsModule(cert)
352 if cert != "" {
353 ctx.AddDependency(ctx.Module(), certificateTag, cert)
354 } else {
355 ctx.PropertyErrorf("additional_certificates",
356 `must be names of android_app_certificate modules in the form ":module"`)
357 }
358 }
Colin Cross30e076a2015-04-13 13:58:27 -0700359}
360
Spandan Dasb0410872024-06-25 03:30:03 +0000361// TODO(b/156476221): Remove this allowlist
362var (
363 missingMinSdkVersionMtsAllowlist = []string{
364 "CellBroadcastReceiverGoogleUnitTests",
365 "CellBroadcastReceiverUnitTests",
366 "CtsBatterySavingTestCases",
367 "CtsDeviceAndProfileOwnerApp23",
368 "CtsDeviceAndProfileOwnerApp30",
369 "CtsIntentSenderApp",
370 "CtsJobSchedulerTestCases",
371 "CtsMimeMapTestCases",
372 "CtsTareTestCases",
373 "LibStatsPullTests",
374 "MediaProviderClientTests",
375 "TeleServiceTests",
376 "TestExternalImsServiceApp",
377 "TestSmsRetrieverApp",
378 "TetheringPrivilegedTests",
379 }
380)
381
382func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
383 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
384 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
385 }
386}
387
Jeongik Cha538c0d02019-07-11 15:54:27 +0900388func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000389 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000390 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
391 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700392 packageName := a.overridableAppProperties.Package_name.Get(ctx)
393 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000394 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
395 }
396 a.aapt.manifestValues.applicationId = *applicationId
397 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900398 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700399 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
400 TestOnly: true,
401 })
Colin Cross99939e92024-10-01 16:02:46 -0700402 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
403 Updatable: Bool(a.appProperties.Updatable),
404 TestHelperApp: true,
405 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900406}
407
Colin Cross46c9b8b2017-06-22 16:51:17 -0700408func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100409 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000410 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700411 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000412 a.generateJavaUsedByApex(ctx)
Colin Crossb614cd42024-10-11 12:52:21 -0700413
414 var embeddedJniLibs []android.Path
415
416 if a.embeddedJniLibs {
417 for _, jni := range a.jniLibs {
418 embeddedJniLibs = append(embeddedJniLibs, jni.path)
419 }
420 }
Colin Cross99939e92024-10-01 16:02:46 -0700421 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
Colin Crossb614cd42024-10-11 12:52:21 -0700422 Updatable: Bool(a.appProperties.Updatable),
423 TestHelperApp: false,
424 EmbeddedJNILibs: embeddedJniLibs,
Colin Cross99939e92024-10-01 16:02:46 -0700425 })
Spandan Dasde588a32024-12-03 22:52:24 +0000426
427 a.requiredModuleNames = a.getRequiredModuleNames(ctx)
428}
429
430func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
431 var required []string
432 if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) {
433 required = []string{a.productCharacteristicsRROPackageName()}
434 }
435 // Install the vendor overlay variant if this app is installed.
436 if len(filterRRO(a.rroDirsDepSet, device)) > 0 {
437 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor"))
438 }
439 // Install the product overlay variant if this app is installed.
440 if len(filterRRO(a.rroDirsDepSet, product)) > 0 {
441 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product"))
442 }
443 return required
Colin Crossae5caf52018-05-22 11:11:52 -0700444}
445
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100446func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100447 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900448 if !a.SdkVersion(ctx).Stable() {
449 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100450 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000451 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100452 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
453 }
Jooyung Han749dc692020-04-15 11:03:39 +0900454
Jiyong Park92315372021-04-02 08:45:46 +0900455 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900456 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000457 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900458 } else {
459 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
460 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000461
462 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
463 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
464 }
465 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
466 if a.deviceProperties.Target_sdk_version == nil {
467 a.SetEnforceDefaultTargetSdkVersion(true)
468 }
469 }
470
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100471 a.checkPlatformAPI(ctx)
472 a.checkSdkVersions(ctx)
473}
474
Jiyong Park970c5242024-05-17 22:58:54 +0000475// Ensures that use_embedded_native_libs are set for apk-in-apex
476func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
477 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
478 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000479 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000480
481 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
482 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
483 }
484}
485
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900486// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
487// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900488func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900489 // 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 +0000490 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900491 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
492 return
493 }
Yu Liufc8d5c12025-01-09 00:19:06 +0000494 if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
495 panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
496 }
497 commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
498 if !ok {
499 panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
500 }
Jooyung Han652d5b32020-05-20 17:12:13 +0900501 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900502 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
503 // handled properly regardless of sdk finalization.
Yu Liufc8d5c12025-01-09 00:19:06 +0000504 jniSdkVersion, err := android.SdkSpecFrom(ctx, commonInfo.MinSdkVersion).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900505 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Yu Liufc8d5c12025-01-09 00:19:06 +0000506 ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
507 commonInfo.MinSdkVersion, minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900508 return
509 }
510
511 })
512}
513
Sasha Smundak6ad77252019-05-01 13:16:22 -0700514// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800515// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700516func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900517 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800518 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900519 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800520 }
521
Jiyong Parkd044bb42024-05-15 02:09:54 +0900522 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
523 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
524 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800525}
526
Colin Cross43f08db2018-11-12 10:13:39 -0800527// Returns whether this module should have the dex file stored uncompressed in the APK.
528func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800529 if Bool(a.appProperties.Use_embedded_dex) {
530 return true
531 }
532
Colin Cross53a87f52019-06-25 13:35:30 -0700533 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
534 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900535 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000536 return true
537 }
538
Colin Cross53a87f52019-06-25 13:35:30 -0700539 if ctx.Config().UnbundledBuild() {
540 return false
541 }
542
Spandan Dase21a8d42024-01-23 23:56:29 +0000543 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700544}
545
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700546func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900547 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000548 Bool(a.appProperties.Updatable) ||
549 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000550}
551
Liz Kammer9f9fd022020-06-18 19:44:06 +0000552func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
553 aaptFlags := []string{"--rename-manifest-package " + packageName}
554 if renameResourcesPackage {
555 // Required to rename the package name in the resources table.
556 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
557 }
558 return aaptFlags
559}
560
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900561func (a *AndroidApp) OverriddenManifestPackageName() string {
562 return a.overriddenManifestPackageName
563}
564
Liz Kammer9f9fd022020-06-18 19:44:06 +0000565func (a *AndroidApp) renameResourcesPackage() bool {
566 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
567}
568
Jihoon Kang9049c272024-03-19 21:57:36 +0000569func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Yu Liu460cf372025-01-10 00:34:06 +0000570 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000571 tag := ctx.OtherModuleDependencyTag(dep)
572 switch tag {
573 case staticLibTag:
574 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
575 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
576 }
577
578 case aconfigDeclarationTag:
579 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
580 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
581 } else {
582 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
583 "flags_packages property, but %s is not aconfig_declarations module type",
584 dep.Name(),
585 )
586 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000587 }
588 })
589
Jihoon Kang9aef7772024-06-14 23:45:06 +0000590 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000591}
592
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800593func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900594 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900595 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900596 usePlatformAPI = true
597 }
598 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000599
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700600 // Ask manifest_fixer to add or update the application element indicating this app has no code.
601 a.aapt.hasNoCode = !a.hasCode(ctx)
602
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800603 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800604
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800605 // 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 +0900606 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800607 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900608 characteristics := ctx.Config().ProductAAPTCharacteristics()
609 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
610 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700611 }
612
Dan Willemsen72be5902018-10-24 20:24:57 -0700613 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
614 // Product AAPT config
615 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800616 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700617 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700618
Dan Willemsen72be5902018-10-24 20:24:57 -0700619 // Product AAPT preferred config
620 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800621 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700622 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700623 }
624
Jiyong Park7f67f482019-01-05 12:57:48 +0900625 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700626 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
627 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700628 // The product override variable has a priority over the package_name property.
629 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700630 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700631 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000632 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900633 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900634 }
635
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800636 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
637
Colin Crosse560c4a2019-03-19 16:03:11 -0700638 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800639 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100640 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000641 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
642 a.aapt.defaultManifestVersion = override
643 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000644 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000645 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100646 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000647
Rico Winda2fa2632024-03-13 13:09:17 +0100648 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200649 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000650
651 aconfigTextFilePaths := getAconfigFilePaths(ctx)
652
Alixf7a10272023-09-27 16:47:56 +0000653 a.aapt.buildActions(ctx,
654 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000655 sdkContext: android.SdkContext(a),
656 classLoaderContexts: a.classLoaderContexts,
657 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
658 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100659 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000660 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000661 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000662 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000663 },
664 )
Colin Cross30e076a2015-04-13 13:58:27 -0700665
Colin Cross46c9b8b2017-06-22 16:51:17 -0700666 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700667 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000668
669 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
670 AconfigTextFiles: aconfigTextFilePaths,
671 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800672}
Colin Cross30e076a2015-04-13 13:58:27 -0700673
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800674func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700675 var staticLibProguardFlagFiles android.Paths
Yu Liu80b68c42025-01-15 18:14:34 +0000676 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Colin Cross313aa542023-12-13 13:47:44 -0800677 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400678 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
679 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
680 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700681 }
682 })
683
684 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
685
Colin Cross312634e2023-11-21 15:13:56 -0800686 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200687 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100688 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
689 // live for code references and (transitively) mark these as live.
690 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
691 // dead code alive)
692 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
693 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800694}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800695
Colin Cross403cc152020-07-06 14:15:24 -0700696func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800697 var installDir string
698 if ctx.ModuleName() == "framework-res" {
699 // framework-res.apk is installed as system/framework/framework-res.apk
700 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900701 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800702 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800703 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800704 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800705 }
Colin Cross403cc152020-07-06 14:15:24 -0700706
707 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
708}
709
Rico Wind98e7fa82023-11-27 09:44:03 +0100710func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700711 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000712 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700713 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100714 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700715 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100716 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700717 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Cole Faust64f2d842024-10-17 13:28:34 -0700718 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100719 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700720 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800721 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700722
Rico Wind98e7fa82023-11-27 09:44:03 +0100723 var packageResources = a.exportPackage
724
Yu Liu460cf372025-01-10 00:34:06 +0000725 javaInfo := &JavaInfo{}
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800726 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200727 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100728 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
729 aapt2Convert(ctx, protoFile, packageResources, "proto")
730 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
731 }
732
Colin Cross4eae06d2023-06-20 22:40:02 -0700733 var extraSrcJars android.Paths
734 var extraClasspathJars android.Paths
735 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800736 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700737 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
738 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
739 // classpath when compiling everything else, and add it to the final classes jar.
740 extraClasspathJars = android.Paths{a.aapt.rJar}
741 extraCombinedJars = android.Paths{a.aapt.rJar}
742 } else {
743 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
744 // R.java files for the app's package and the packages from all transitive static android_library
745 // dependencies. Compile the srcjar alongside the rest of the sources.
746 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
747 }
748
Yu Liu460cf372025-01-10 00:34:06 +0000749 javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200750 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100751 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
752 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
753 packageResources = binaryResources
754 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800755 }
Yu Liu460cf372025-01-10 00:34:06 +0000756 if javaInfo != nil {
757 setExtraJavaInfo(ctx, a, javaInfo)
758 android.SetProvider(ctx, JavaInfoProvider, javaInfo)
759 }
Colin Cross30e076a2015-04-13 13:58:27 -0700760
Rico Wind98e7fa82023-11-27 09:44:03 +0100761 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800762}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800763
Sam Delmerico82602492022-06-10 17:05:42 +0000764func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700765 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000766 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700767 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700768 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700769 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800770 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000771 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700772 for _, jni := range jniLibs {
773 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700774 // Only collect coverage for the first target arch if this is a multilib target.
775 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
776 // data file path collisions since the current coverage file path format doesn't contain
777 // arch-related strings. This is fine for now though; the code coverage team doesn't use
778 // multi-arch targets such as test_suite_* for coverage collections yet.
779 //
780 // Work with the team to come up with a new format that handles multilib modules properly
781 // and change this.
782 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700783 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700784 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
785 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700786 }
787 }
Colin Cross403cc152020-07-06 14:15:24 -0700788 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700789 }
790 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800791 return jniJarFile
792}
Colin Crossa4f08812018-10-02 22:03:40 -0700793
Colin Cross403cc152020-07-06 14:15:24 -0700794func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
795 var jniSymbols android.RuleBuilderInstalls
796 for _, jniLib := range a.jniLibs {
797 if jniLib.unstrippedFile != nil {
798 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
799 From: jniLib.unstrippedFile,
800 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
801 })
802 }
803 }
804 return jniSymbols
805}
806
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700807// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
808// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700809func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
810 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700811 if android.SrcIsModule(certPropValue) == "" {
812 var mainCert Certificate
813 if certPropValue != "" {
814 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
815 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800816 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
817 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700818 }
819 } else {
820 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800821 mainCert = Certificate{
822 Pem: pem,
823 Key: key,
824 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700825 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700826 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700827 }
828
Colin Crossbc2c8a72022-09-14 12:45:42 -0700829 if len(certificates) > 0 {
830 mainCertificate = certificates[0]
831 } else {
832 // This can be reached with an empty certificate list if AllowMissingDependencies is set
833 // and the certificate property for this module is a module reference to a missing module.
834 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
835 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
836 }
837 // Set a certificate to avoid panics later when accessing it.
838 mainCertificate = Certificate{
839 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000840 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700841 }
842 }
843
Zyan Wub7550aa2023-05-18 15:46:31 +0800844 if !m.Platform() {
845 certPath := mainCertificate.Pem.String()
846 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
847 if strings.HasPrefix(certPath, systemCertPath) {
848 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
849 allowed := ctx.Config().EnforceSystemCertificateAllowList()
850
851 if enforceSystemCert && !inList(m.Name(), allowed) {
852 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
853 }
854 }
855 }
856
Colin Crossbc2c8a72022-09-14 12:45:42 -0700857 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800858}
859
Jooyung Han39ee1192020-03-23 20:21:11 +0900860func (a *AndroidApp) InstallApkName() string {
861 return a.installApkName
862}
863
Sam Delmerico15809f82023-05-15 17:21:47 -0400864func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000865 if a.appProperties.Privapp_allowlist == nil {
866 return nil
867 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400868
869 isOverrideApp := a.GetOverriddenBy() != ""
870 if !isOverrideApp {
871 // if this is not an override, we don't need to rewrite the existing privapp allowlist
872 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
873 }
874
Cole Faust258b96f2024-10-04 10:48:24 -0700875 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
876 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000877 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
878 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400879
Cole Faust258b96f2024-10-04 10:48:24 -0700880 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000881 fileName := "privapp_allowlist_" + packageName + ".xml"
Cole Faust4e9f5922024-11-13 16:09:23 -0800882 outPath := android.PathForModuleOut(ctx, fileName)
Andrei Onea580636b2022-08-17 16:53:46 +0000883 ctx.Build(pctx, android.BuildParams{
884 Rule: modifyAllowlist,
885 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
886 Output: outPath,
887 Args: map[string]string{
888 "packageName": packageName,
889 },
890 })
Cole Faust4e9f5922024-11-13 16:09:23 -0800891 return outPath
Andrei Onea580636b2022-08-17 16:53:46 +0000892}
893
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800894func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700895 var apkDeps android.Paths
896
Colin Crossff694a82023-12-13 15:54:49 -0800897 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
898 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700899 a.hideApexVariantFromMake = true
900 }
901
Jeongik Cha538c0d02019-07-11 15:54:27 +0900902 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
903 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
904
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000905 // Unlike installApkName, a.stem should respect base module name for override_android_app.
906 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000907 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000908
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800909 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000910 // Both android_app and override_android_app module are expected to possess
911 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
912 // from the base module. Therefore, use a.Name() which represents
913 // the module name for both android_app and override_android_app.
914 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000915 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800916
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700917 if ctx.ModuleName() == "framework-res" {
918 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700919 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900920 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700921 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
922 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800923 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700924 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700925 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700926 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700927 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700928
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100929 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000930 if a.usesLibrary.shouldDisableDexpreopt {
931 a.dexpreopter.disableDexpreopt()
932 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000933
Colin Cross61fb62e2022-06-23 10:46:28 -0700934 var noticeAssetPath android.WritablePath
935 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
936 // The rule to create the notice file can't be generated yet, as the final output path
937 // for the apk isn't known yet. Add the path where the notice file will be generated to the
938 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
939 // be generated later.
940 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
941 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
942 }
943
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000944 // For apps targeting latest target_sdk_version
945 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
946 a.SetEnforceDefaultTargetSdkVersion(true)
947 }
948
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800949 // Process all building blocks, from AAPT to certificates.
950 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100951 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
Cole Faust64f2d842024-10-17 13:28:34 -0700952 a.usesLibrary.freezeEnforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100953
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100954 // Check that the <uses-library> list is coherent with the manifest.
Cole Faust64f2d842024-10-17 13:28:34 -0700955 if a.usesLibrary.enforceUsesLibraries(ctx) {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000956 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
957 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700958 apkDeps = append(apkDeps, manifestCheckFile)
959 }
960
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800961 a.proguardBuildActions(ctx)
962
Colin Cross014489c2020-06-02 20:09:13 -0700963 a.linter.mergedManifest = a.aapt.mergedManifestFile
964 a.linter.manifest = a.aapt.manifestPath
965 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700966 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700967
Rico Wind98e7fa82023-11-27 09:44:03 +0100968 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800969
Jiyong Park92d84042024-05-17 22:58:54 +0000970 // No need to check the SDK version of the JNI deps unless we embed them
971 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
972 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000973 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800974
975 if ctx.Failed() {
976 return
977 }
978
Colin Crossbc2c8a72022-09-14 12:45:42 -0700979 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800980
981 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800982 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700983 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
984 var v4SignatureFile android.WritablePath = nil
985 if v4SigningRequested {
986 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
987 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700988 var lineageFile android.Path
989 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
990 lineageFile = android.PathForModuleSrc(ctx, lineage)
991 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400992 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
993
Rico Wind98e7fa82023-11-27 09:44:03 +0100994 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800995 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700996 if v4SigningRequested {
997 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
998 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800999
Colin Cross61fb62e2022-06-23 10:46:28 -07001000 if a.aapt.noticeFile.Valid() {
1001 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -07001002 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -07001003 android.BuildNoticeHtmlOutputFromLicenseMetadata(
1004 ctx, noticeFile, "", "",
1005 []string{
1006 a.installDir.String() + "/",
1007 android.PathForModuleInstall(ctx).String() + "/",
1008 a.outputFile.String(),
1009 })
Bob Badoureef4c1c2022-05-16 12:20:04 -07001010 builder := android.NewRuleBuilder(pctx, ctx)
1011 builder.Command().Text("cp").
1012 Input(noticeFile).
1013 Output(noticeAssetPath)
1014 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -07001015 }
1016
Colin Crosse560c4a2019-03-19 16:03:11 -07001017 for _, split := range a.aapt.splits {
1018 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -08001019 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -07001020 if v4SigningRequested {
1021 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
1022 }
Rico Wind98e7fa82023-11-27 09:44:03 +01001023 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -07001024 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -07001025 if v4SigningRequested {
1026 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
1027 }
Colin Crosse560c4a2019-03-19 16:03:11 -07001028 }
1029
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001030 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -07001031 bundleFile := android.PathForModuleOut(ctx, "base.zip")
1032 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
1033 a.bundleFile = bundleFile
1034
Andrei Onea580636b2022-08-17 16:53:46 +00001035 allowlist := a.createPrivappAllowlist(ctx)
1036 if allowlist != nil {
1037 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
1038 }
1039
Jaewoong Jung590b1ae2019-01-22 16:40:58 -08001040 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001041 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1042 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001043 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001044 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1045 allowlistInstallFilename := a.installApkName + ".xml"
1046 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001047 }
1048
Colin Cross09ad3a62023-11-15 12:29:33 -08001049 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001050 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001051 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1052 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001053 }
Jiyong Park25b92222024-05-17 22:58:54 +00001054 // If we don't embed jni libs, make sure that those are installed along with the
1055 // app, and also place symlinks to the installed paths under the lib/<arch>
1056 // directory of the app installation directory. ex:
1057 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1058 if !a.embeddedJniLibs {
1059 for _, jniLib := range jniLibs {
1060 archStr := jniLib.target.Arch.ArchType.String()
1061 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1062 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001063 // install the symlink itself
1064 symlinkName := installedLib.Base()
1065 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1066 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1067 }
1068 }
1069 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001070 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001071 }
Artur Satayev1111b842020-04-27 19:05:28 +01001072
Colin Crossa6182ab2024-08-21 10:47:44 -07001073 ctx.CheckbuildFile(a.outputFile)
1074
Artur Satayev1111b842020-04-27 19:05:28 +01001075 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001076
1077 providePrebuiltInfo(ctx,
1078 prebuiltInfoProps{
1079 baseModuleName: a.BaseModuleName(),
1080 isPrebuilt: false,
1081 },
1082 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001083
1084 a.setOutputFiles(ctx)
1085}
1086
1087func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1088 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1089 if a.aaptSrcJar != nil {
1090 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1091 }
1092 if a.rJar != nil {
1093 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1094 }
1095 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1096 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1097 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1098 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001099}
1100
Colin Crossc2d24052020-05-13 11:05:02 -07001101type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001102 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001103 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001104 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1105}
1106
1107func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1108 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001109 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001110
Colin Crossc2d24052020-05-13 11:05:02 -07001111 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001112 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1113 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001114 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001115 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
Yu Liuf6f85492025-01-13 21:02:36 +00001116 checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool {
Spandan Das10c41362024-12-03 01:33:09 +00001117 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
Yu Liuf6f85492025-01-13 21:02:36 +00001118 childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
1119 parentIsLinkable := false
1120 if ctx.EqualModules(ctx.Module(), parent) {
1121 parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
1122 parentIsLinkable = parentLinkable != nil
1123 } else {
1124 _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider)
1125 }
1126 useStubsOfDep := childLinkable.IsStubs
1127 if apkInApex && parentIsLinkable {
Spandan Das10c41362024-12-03 01:33:09 +00001128 // APK-in-APEX
1129 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
Yu Liuf6f85492025-01-13 21:02:36 +00001130 useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child))
Spandan Das10c41362024-12-03 01:33:09 +00001131 }
Yu Liuf6f85492025-01-13 21:02:36 +00001132 return !childLinkable.IsNdk && !useStubsOfDep
Spandan Das10c41362024-12-03 01:33:09 +00001133 })
Makoto Onuki2ca84272024-02-10 00:15:21 +00001134
1135 var certificates []Certificate
1136
Colin Crossb614cd42024-10-11 12:52:21 -07001137 var directImplementationDeps android.Paths
1138 var transitiveImplementationDeps []depset.DepSet[android.Path]
Yu Liu728da7c2025-01-11 00:54:32 +00001139 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001140 otherName := ctx.OtherModuleName(module)
1141 tag := ctx.OtherModuleDependencyTag(module)
1142
1143 if tag == certificateTag {
Yu Liu728da7c2025-01-11 00:54:32 +00001144 if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001145 certificates = append(certificates, dep.Certificate)
1146 } else {
1147 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1148 }
1149 }
Colin Crossb614cd42024-10-11 12:52:21 -07001150
1151 if IsJniDepTag(tag) {
1152 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, ""))
1153 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok {
1154 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1155 }
1156 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001157 })
Colin Crossb614cd42024-10-11 12:52:21 -07001158 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1159 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1160 })
1161
Makoto Onuki2ca84272024-02-10 00:15:21 +00001162 return jniLib, prebuiltJniPackages, certificates
1163}
1164
1165func collectJniDeps(ctx android.ModuleContext,
1166 shouldCollectRecursiveNativeDeps bool,
1167 checkNativeSdkVersion bool,
Yu Liuf6f85492025-01-13 21:02:36 +00001168 filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001169 var jniLibs []jniLib
1170 var prebuiltJniPackages android.Paths
1171 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001172
Yu Liuf6f85492025-01-13 21:02:36 +00001173 ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
Yu Liub732c842025-01-16 00:15:54 +00001174 if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
1175 return false
1176 }
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) {
Yu Liuf6f85492025-01-13 21:02:36 +00001181 if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); 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
Yu Liuf6f85492025-01-13 21:02:36 +00001186 lib := dep.OutputFile
Colin Crossa4f08812018-10-02 22:03:40 -07001187 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
Yu Liuf6f85492025-01-13 21:02:36 +00001194 commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
1195 if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
Cole Faust64cb7c92021-09-14 17:32:49 -07001196 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1197 otherName)
1198 }
1199
Colin Crossa4f08812018-10-02 22:03:40 -07001200 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001201 name: ctx.OtherModuleName(module),
1202 path: path,
Yu Liuf6f85492025-01-13 21:02:36 +00001203 target: commonInfo.Target,
1204 coverageFile: dep.CoverageOutputFile,
1205 unstrippedFile: dep.UnstrippedOutputFile,
1206 partition: dep.Partition,
1207 installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001208 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001209 } else if ctx.Config().AllowMissingDependencies() {
1210 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001211 } else {
1212 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1213 }
1214 } else {
1215 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001216 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001217
1218 return shouldCollectRecursiveNativeDeps
1219 }
1220
Colin Cross313aa542023-12-13 13:47:44 -08001221 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001222 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1223 }
1224
Peter Collingbournead84f972019-12-17 16:46:18 -08001225 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001226 })
1227
Makoto Onuki2ca84272024-02-10 00:15:21 +00001228 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001229}
1230
Colin Cross8bf14fc2024-09-25 16:41:31 -07001231func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001232 ctx.WalkDeps(func(child, parent android.Module) bool {
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001233 // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
1234 // heuristics to every transitive dependency, when it should probably be using the heuristics of the
1235 // immediate parent.
1236 isExternal := !a.OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
Artur Satayev1111b842020-04-27 19:05:28 +01001237 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001238 if !do(ctx, parent, am, isExternal) {
1239 return false
1240 }
Artur Satayev1111b842020-04-27 19:05:28 +01001241 }
1242 return !isExternal
1243 })
1244}
1245
1246func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1247 if ctx.Host() {
1248 return
1249 }
1250
1251 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross9cf55a52024-12-05 14:26:03 -08001252 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001253 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001254
1255 // Skip dependencies that are only available to APEXes; they are developed with updatability
1256 // in mind and don't need manual approval.
1257 if to.(android.ApexModule).NotAvailableForPlatform() {
1258 return true
1259 }
1260
Artur Satayev1111b842020-04-27 19:05:28 +01001261 if info, exist := depsInfo[depName]; exist {
1262 info.From = append(info.From, from.Name())
1263 info.IsExternal = info.IsExternal && externalDep
1264 depsInfo[depName] = info
1265 } else {
1266 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001267 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001268 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001269 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001270 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1271 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001272 }
Jiyong Park92315372021-04-02 08:45:46 +09001273 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1274 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1275 // string
1276 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001277 toMinSdkVersion = v
1278 }
Artur Satayev1111b842020-04-27 19:05:28 +01001279 }
1280 depsInfo[depName] = android.ApexModuleDepInfo{
1281 To: depName,
1282 From: []string{from.Name()},
1283 IsExternal: externalDep,
1284 MinSdkVersion: toMinSdkVersion,
1285 }
1286 }
Jooyung Han749dc692020-04-15 11:03:39 +09001287 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001288 })
1289
Jiyong Park92315372021-04-02 08:45:46 +09001290 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001291}
1292
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001293func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1294 return a.appProperties.EnforceDefaultTargetSdkVersion
1295}
1296
1297func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1298 a.appProperties.EnforceDefaultTargetSdkVersion = val
1299}
1300
Artur Satayev849f8442020-04-28 14:57:42 +01001301func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001302 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001303}
1304
Colin Cross0ea8ba82019-06-06 14:33:29 -07001305func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001306 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1307 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001308 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001309 }
Cole Fausteb9c1482024-11-18 16:49:19 -08001310 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001311}
1312
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001313func (a *AndroidApp) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
1314 if IsJniDepTag(tag) {
Jiyong Park0f80c182020-01-31 02:49:53 +09001315 return true
1316 }
Colin Crossf7bbd2f2024-12-05 13:57:10 -08001317 return a.Library.OutgoingDepIsInSameApex(tag)
Jiyong Park0f80c182020-01-31 02:49:53 +09001318}
1319
Jiyong Parkf7487312019-10-17 12:54:30 +09001320func (a *AndroidApp) Privileged() bool {
1321 return Bool(a.appProperties.Privileged)
1322}
1323
Colin Crosse1a85552024-06-14 12:17:37 -07001324func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001325 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001326}
1327
Ivan Lozanod7586b62021-04-01 09:49:36 -04001328func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001329 a.appProperties.PreventInstall = true
1330}
1331
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001332func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1333 a.appProperties.IsCoverageVariant = coverage
1334}
1335
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001336func (a *AndroidApp) EnableCoverageIfNeeded() {}
1337
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001338var _ cc.Coverage = (*AndroidApp)(nil)
1339
Cole Faustb36d31d2024-08-27 16:04:28 -07001340func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1341 a.Library.IDEInfo(ctx, dpInfo)
1342 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001343}
1344
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001345func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1346 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1347}
1348
1349func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1350 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1351}
1352
Colin Cross1b16b0e2019-02-12 14:41:32 -08001353// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001354func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001355 module := &AndroidApp{}
1356
Liz Kammera7a64f32020-07-09 15:16:41 -07001357 module.Module.dexProperties.Optimize.EnabledByDefault = true
1358 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001359 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001360
Colin Crossae5caf52018-05-22 11:11:52 -07001361 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001362 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001363 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001364
Colin Crossce6734e2020-06-15 16:09:53 -07001365 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001366 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001367 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001368 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001369 &module.overridableAppProperties,
1370 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001371
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001372 module.usesLibrary.enforce = true
1373
Colin Crossa4f08812018-10-02 22:03:40 -07001374 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1375 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001376 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001377 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001378
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001379 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1380 a := ctx.Module().(*AndroidApp)
1381
1382 characteristics := ctx.Config().ProductAAPTCharacteristics()
1383 if characteristics == "default" || characteristics == "" {
1384 module.appProperties.Generate_product_characteristics_rro = nil
1385 // no need to create RRO
1386 return
1387 }
1388
1389 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1390 return
1391 }
1392
1393 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1394 rroManifestName := rroPackageName + "_manifest"
1395
1396 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1397 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1398
1399 rroManifestProperties := struct {
1400 Name *string
1401 Tools []string
1402 Out []string
1403 Srcs []string
1404 Cmd *string
1405 }{
1406 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001407 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001408 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001409 Srcs: []string{":" + a.Name() + "{.apk}"},
1410 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001411 }
Cole Fauste19d3352024-10-17 10:30:57 -07001412 ctx.CreateModule(GenRuleFactory, &rroManifestProperties)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001413
1414 rroProperties := struct {
1415 Name *string
1416 Filter_product *string
1417 Aaptflags []string
1418 Manifest *string
Cole Faust5b989772024-11-06 11:03:16 -08001419 Resource_dirs proptools.Configurable[[]string]
Jihoon Kangf62f4222024-10-21 23:06:41 +00001420 Flags_packages []string
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001421 }{
1422 Name: proptools.StringPtr(rroPackageName),
1423 Filter_product: proptools.StringPtr(characteristics),
1424 Aaptflags: []string{"--auto-add-overlay"},
1425 Manifest: proptools.StringPtr(":" + rroManifestName),
1426 Resource_dirs: a.aaptProperties.Resource_dirs,
Jihoon Kangf62f4222024-10-21 23:06:41 +00001427 Flags_packages: a.aaptProperties.Flags_packages,
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001428 }
优秀d75e9982024-05-09 07:15:55 +00001429 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1430 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1431 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1432 }
1433 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001434 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
Spandan Dasde588a32024-12-03 22:52:24 +00001435
1436 })
1437
1438 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1439 createInternalRuntimeOverlays(ctx, module.ModuleBase)
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001440 })
1441
Colin Cross36242852017-06-23 15:06:31 -07001442 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001443}
Colin Crossae5caf52018-05-22 11:11:52 -07001444
Spandan Das71be42d2024-11-20 18:34:16 +00001445func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
1446 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
1447}
1448
Spandan Dasde588a32024-12-03 22:52:24 +00001449type createModuleContext interface {
1450 android.EarlyModuleContext
1451 CreateModule(android.ModuleFactory, ...interface{}) android.Module
1452}
1453
1454func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) {
1455 if !ctx.Config().HasDeviceProduct() {
1456 return
1457 }
1458 // vendor
1459 vendorOverlayProps := struct {
1460 Name *string
1461 Base *string
1462 Vendor *bool
1463 Product_specific *bool
1464 System_ext_specific *bool
1465 Manifest *string
1466 Sdk_version *string
1467 Compile_multilib *string
1468 Enabled proptools.Configurable[bool]
1469 }{
1470 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")),
1471 Base: proptools.StringPtr(a.Name()),
1472 Vendor: proptools.BoolPtr(true),
1473 Product_specific: proptools.BoolPtr(false),
1474 System_ext_specific: proptools.BoolPtr(false),
1475 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1476 Sdk_version: proptools.StringPtr("current"),
1477 Compile_multilib: proptools.StringPtr("first"),
1478 Enabled: a.EnabledProperty().Clone(),
1479 }
1480 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps)
1481
1482 // product
1483 productOverlayProps := struct {
1484 Name *string
1485 Base *string
1486 Vendor *bool
1487 Proprietary *bool
1488 Soc_specific *bool
1489 Product_specific *bool
1490 System_ext_specific *bool
1491 Manifest *string
1492 Sdk_version *string
1493 Compile_multilib *string
1494 Enabled proptools.Configurable[bool]
1495 }{
1496 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")),
1497 Base: proptools.StringPtr(a.Name()),
1498 Vendor: proptools.BoolPtr(false),
1499 Proprietary: proptools.BoolPtr(false),
1500 Soc_specific: proptools.BoolPtr(false),
1501 Product_specific: proptools.BoolPtr(true),
1502 System_ext_specific: proptools.BoolPtr(false),
1503 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"),
1504 Sdk_version: proptools.StringPtr("current"),
1505 Compile_multilib: proptools.StringPtr("first"),
1506 Enabled: a.EnabledProperty().Clone(),
1507 }
1508 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps)
1509}
1510
Alix96ea88452023-08-31 15:48:23 +00001511// A dictionary of values to be overridden in the manifest.
1512type Manifest_values struct {
1513 // Overrides the value of package_name in the manifest
1514 ApplicationId *string
1515}
1516
Colin Crossae5caf52018-05-22 11:11:52 -07001517type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001518 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001519 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001520
Seth Moorec6f4b532023-02-02 13:22:26 -08001521 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001522 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001523
1524 // If specified, the mainline module package name in the test config is overwritten by it.
1525 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001526
1527 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001528}
1529
1530type AndroidTest struct {
1531 AndroidApp
1532
1533 appTestProperties appTestProperties
1534
1535 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001536
Dan Shi95d19422020-08-15 12:24:26 -07001537 testConfig android.Path
1538 extraTestConfigs android.Paths
1539 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001540}
1541
Jaewoong Jung0949f312019-09-11 10:25:18 -07001542func (a *AndroidTest) InstallInTestcases() bool {
1543 return true
1544}
1545
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001546type androidTestApp interface {
1547 includedInTestSuite(searchPrefix string) bool
1548}
1549
1550func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1551 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1552}
1553
1554func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1555 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1556}
1557
Colin Crossae5caf52018-05-22 11:11:52 -07001558func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001559 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001560 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001561 if a.appTestProperties.Instrumentation_target_package != nil {
1562 a.additionalAaptFlags = append(a.additionalAaptFlags,
1563 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1564 } else if a.appTestProperties.Instrumentation_for != nil {
1565 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001566 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1567 if overridden {
1568 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1569 }
1570 }
Alix96ea88452023-08-31 15:48:23 +00001571 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1572 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001573 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1574 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001575 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1576 }
1577 a.aapt.manifestValues.applicationId = *applicationId
1578 }
Colin Crossae5caf52018-05-22 11:11:52 -07001579 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001580
Jiyong Parkf528b702024-12-30 16:01:58 +09001581 for _, c := range a.testProperties.Test_options.Tradefed_options {
1582 configs = append(configs, c)
1583 }
easoncylee5bcff5d2020-04-30 14:57:06 +08001584 for _, module := range a.testProperties.Test_mainline_modules {
1585 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1586 }
1587
Jaewoong Jung39982342020-01-14 10:27:18 -08001588 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001589 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1590 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001591 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001592 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001593 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Cole Faust65cb40a2024-10-21 15:41:42 -07001594 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
1595 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
Cole Faust18f03f12024-10-23 14:51:11 -07001596 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001597
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001598 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001599 TestcaseRelDataFiles: testcaseRel(a.data),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001600 OutputFile: a.OutputFile(),
1601 TestConfig: a.testConfig,
1602 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001603 TestSuites: a.testProperties.Test_suites,
1604 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001605 LocalCertificate: a.certificate.AndroidMkString(),
1606 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001607 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
1608 MkAppClass: "APPS",
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001609 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001610 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1611 TestOnly: true,
1612 TopLevelTarget: true,
1613 })
1614
Colin Cross303e21f2018-08-07 16:49:25 -07001615}
1616
Ronald Braunsteinf424c9a2024-10-22 01:41:20 +00001617func testcaseRel(paths android.Paths) []string {
1618 relPaths := []string{}
1619 for _, p := range paths {
1620 relPaths = append(relPaths, p.Rel())
1621 }
1622 return relPaths
1623}
1624
Jaewoong Jung39982342020-01-14 10:27:18 -08001625func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1626 if testConfig == nil {
1627 return nil
1628 }
1629
1630 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001631 rule := android.NewRuleBuilder(pctx, ctx)
1632 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001633 fixNeeded := false
1634
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001635 // 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 -08001636 if ctx.ModuleName() != a.installApkName {
1637 fixNeeded = true
1638 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1639 }
1640
Cole Faust258b96f2024-10-04 10:48:24 -07001641 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1642 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001643 fixNeeded = true
1644 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001645 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001646 }
1647
Seth Moorec6f4b532023-02-02 13:22:26 -08001648 if a.appTestProperties.Mainline_package_name != nil {
1649 fixNeeded = true
1650 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1651 }
1652
Jaewoong Jung39982342020-01-14 10:27:18 -08001653 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001654 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001655 return fixedConfig
1656 }
1657 return testConfig
1658}
1659
Yihan Dong8be09c22024-08-29 15:32:13 +08001660func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1661 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1662 // Instrument the android_test_helper target to log potential API calls at the run time.
1663 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1664 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1665 a.setApiMapper(true)
1666 }
1667 a.AndroidApp.DepsMutator(ctx)
1668}
1669
Colin Cross303e21f2018-08-07 16:49:25 -07001670func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001671 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1672 // Instrument the android_test_helper target to log potential API calls at the run time.
1673 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1674 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1675 a.setApiMapper(true)
1676 }
Colin Cross303e21f2018-08-07 16:49:25 -07001677 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001678}
1679
1680func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1681 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001682 if a.appTestProperties.Instrumentation_for != nil {
1683 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1684 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1685 // use instrumentationForTag instead of libTag.
1686 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1687 }
Colin Crossae5caf52018-05-22 11:11:52 -07001688}
1689
Colin Cross1b16b0e2019-02-12 14:41:32 -08001690// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1691// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001692func AndroidTestFactory() android.Module {
1693 module := &AndroidTest{}
1694
Jared Duke63a3da92022-06-02 19:11:14 +00001695 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001696
1697 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001698 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001699 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001700 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1701 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001702 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001703 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001704
Colin Crossce6734e2020-06-15 16:09:53 -07001705 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001706 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001707 &module.aaptProperties,
1708 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001709 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001710 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001711 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001712
Colin Crossa4f08812018-10-02 22:03:40 -07001713 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1714 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001715 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001716
Colin Crossae5caf52018-05-22 11:11:52 -07001717 return module
1718}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001719
Colin Cross252fc6f2018-10-04 15:22:03 -07001720type appTestHelperAppProperties struct {
1721 // list of compatibility suites (for example "cts", "vts") that the module should be
1722 // installed into.
1723 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001724
1725 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1726 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1727 // explicitly.
1728 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001729
1730 // Install the test into a folder named for the module in all test suites.
1731 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001732
1733 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001734}
1735
1736type AndroidTestHelperApp struct {
1737 AndroidApp
1738
1739 appTestHelperAppProperties appTestHelperAppProperties
1740}
1741
Jaewoong Jung326a9412019-11-21 10:41:00 -08001742func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1743 return true
1744}
1745
Colin Cross1b16b0e2019-02-12 14:41:32 -08001746// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1747// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1748// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001749func AndroidTestHelperAppFactory() android.Module {
1750 module := &AndroidTestHelperApp{}
1751
Jared Duke63a3da92022-06-02 19:11:14 +00001752 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001753 module.Module.dexProperties.Optimize.EnabledByDefault = true
Christoffer Adamsenc8fd1f12025-01-06 19:04:03 +01001754 module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
1755 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross252fc6f2018-10-04 15:22:03 -07001756
1757 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001758 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1759 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001760 module.Module.dexpreopter.isTest = true
Cole Faustc7315282025-01-10 15:37:01 -08001761 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001762
Colin Crossce6734e2020-06-15 16:09:53 -07001763 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001764 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001765 &module.aaptProperties,
1766 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001767 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001768 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001769
1770 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1771 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001772 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001773 return module
1774}
1775
Colin Crossbd01e2a2018-10-04 15:21:03 -07001776type AndroidAppCertificate struct {
1777 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001778
Colin Crossbd01e2a2018-10-04 15:21:03 -07001779 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001780 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001781}
1782
1783type AndroidAppCertificateProperties struct {
1784 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1785 Certificate *string
1786}
1787
Yu Liu728da7c2025-01-11 00:54:32 +00001788type AndroidAppCertificateInfo struct {
1789 Certificate Certificate
1790}
1791
1792var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]()
1793
Colin Cross1b16b0e2019-02-12 14:41:32 -08001794// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1795// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001796func AndroidAppCertificateFactory() android.Module {
1797 module := &AndroidAppCertificate{}
1798 module.AddProperties(&module.properties)
1799 android.InitAndroidModule(module)
1800 return module
1801}
1802
Colin Crossbd01e2a2018-10-04 15:21:03 -07001803func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1804 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001805 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001806 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1807 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001808 }
Yu Liu728da7c2025-01-11 00:54:32 +00001809
1810 android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{
1811 Certificate: c.Certificate,
1812 })
Colin Crossbd01e2a2018-10-04 15:21:03 -07001813}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001814
1815type OverrideAndroidApp struct {
1816 android.ModuleBase
1817 android.OverrideModuleBase
1818}
1819
Sasha Smundak613cbb12020-06-05 10:27:23 -07001820func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001821 // All the overrides happen in the base module.
1822 // TODO(jungjw): Check the base module type.
1823}
1824
1825// override_android_app is used to create an android_app module based on another android_app by overriding
1826// some of its properties.
1827func OverrideAndroidAppModuleFactory() android.Module {
1828 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001829 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001830 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001831 &overridableAppProperties{},
1832 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001833
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001834 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001835 android.InitOverrideModule(m)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001836 android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) {
Spandan Dasde588a32024-12-03 22:52:24 +00001837 createInternalRuntimeOverlays(ctx, m.ModuleBase)
Spandan Dasef8b3b22024-12-04 01:34:34 +00001838 }, 1) // Run after soong config load hoook
Spandan Dasde588a32024-12-03 22:52:24 +00001839
Jaewoong Jung525443a2019-02-28 15:35:54 -08001840 return m
1841}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001842
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001843type OverrideAndroidTest struct {
1844 android.ModuleBase
1845 android.OverrideModuleBase
1846}
1847
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001848func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001849 // All the overrides happen in the base module.
1850 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001851 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1852 TestOnly: true,
1853 TopLevelTarget: true,
1854 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001855}
1856
1857// override_android_test is used to create an android_app module based on another android_test by overriding
1858// some of its properties.
1859func OverrideAndroidTestModuleFactory() android.Module {
1860 m := &OverrideAndroidTest{}
1861 m.AddProperties(&overridableAppProperties{})
1862 m.AddProperties(&appTestProperties{})
1863
1864 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1865 android.InitOverrideModule(m)
1866 return m
1867}
1868
Colin Cross50ddcc42019-05-16 12:28:22 -07001869type UsesLibraryProperties struct {
1870 // 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 -07001871 Uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001872
1873 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1874 // required=false.
Cole Faust64f2d842024-10-17 13:28:34 -07001875 Optional_uses_libs proptools.Configurable[[]string]
Colin Cross50ddcc42019-05-16 12:28:22 -07001876
1877 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1878 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1879 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001880
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001881 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1882 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1883 // normally is the same as the module name, but there are exceptions.
1884 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001885
1886 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1887 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1888 // added to the APK's manifest's <uses-library> elements.
1889 //
1890 // Care must be taken when using this as it could result in runtime errors if the APK actually
1891 // uses classes provided by the library and which are not provided in any other way.
1892 //
1893 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1894 // android.test.base shared library (and related libraries) but which depend on some common
1895 // libraries that depend on the android.test.base library. Without this those tests will end up
1896 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1897 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1898 // test altogether by providing access to classes that the tests were not expecting. Those tests
1899 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1900 // with the classes provided by the android.test.base library.
1901 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001902
1903 // The module names of optional uses-library libraries that are missing from the source tree.
1904 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001905}
1906
1907// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1908// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1909// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1910// with knowledge of their shared libraries.
1911type usesLibrary struct {
1912 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001913
1914 // Whether to enforce verify_uses_library check.
1915 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001916
1917 // Whether dexpreopt should be disabled
1918 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001919}
1920
Colin Cross4a80a152022-12-21 21:51:52 -08001921func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001922 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Cole Faust64f2d842024-10-17 13:28:34 -07001923 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001924 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1925 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001926 // Only add these extra dependencies if the module is an app that depends on framework
1927 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001928 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001929 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001930 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1931 // class loader context for dex2oat. Add them as a dependency with a special tag.
1932 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1933 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1934 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001935 }
Cole Faust64f2d842024-10-17 13:28:34 -07001936 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001937 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001938 } else {
Cole Faust64f2d842024-10-17 13:28:34 -07001939 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001940 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001941 }
1942}
1943
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001944// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001945func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Cole Faust64f2d842024-10-17 13:28:34 -07001946 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001947 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001948 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001949 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1950 }
1951 return exists
1952 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001953 return optionalUsesLibs
1954}
1955
Ulya Trafimovich24446712021-07-15 14:59:34 +01001956// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1957// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001958func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1959 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001960
1961 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1962 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1963 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1964 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001965 }
1966
Yu Liu27b74aa2025-01-11 00:04:41 +00001967 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
Ulya Trafimovich24446712021-07-15 14:59:34 +01001968 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1969 if !isUsesLibTag {
1970 return
1971 }
1972
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001973 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001974
Yu Liu27b74aa2025-01-11 00:04:41 +00001975 javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
1976 if !ok {
1977 return
1978 }
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001979 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1980 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1981 // from implementation libraries by their name, which is different as it has a suffix.
Yu Liu27b74aa2025-01-11 00:04:41 +00001982 if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
1983 if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001984 return
1985 }
1986 }
1987
Yu Liu27b74aa2025-01-11 00:04:41 +00001988 if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001989 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1990 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1991 // This will be restricted to optional_uses_libs
Yu Liu27b74aa2025-01-11 00:04:41 +00001992 if tag == usesLibOptTag && lib.DexJarBuildPath.PathOrNil() == nil {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001993 u.shouldDisableDexpreopt = true
1994 return
1995 }
1996 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001997 libName := dep
Yu Liu27b74aa2025-01-11 00:04:41 +00001998 if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil {
1999 libName = *ulib.ProvidesUsesLib
Ulya Trafimovich24446712021-07-15 14:59:34 +01002000 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01002001 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Yu Liu27b74aa2025-01-11 00:04:41 +00002002 lib.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath,
2003 lib.ClassLoaderContexts)
Ulya Trafimovich24446712021-07-15 14:59:34 +01002004 } else if ctx.Config().AllowMissingDependencies() {
2005 ctx.AddMissingDependencies([]string{dep})
2006 } else {
2007 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
2008 }
2009 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00002010 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07002011}
2012
2013// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
2014// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
2015// unconditionally in the future.
Cole Faust64f2d842024-10-17 13:28:34 -07002016func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
2017 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
2018 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00002019 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07002020}
2021
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002022// 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 -07002023func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
2024 enforce := u.enforceUsesLibraries(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01002025 u.usesLibraryProperties.Enforce_uses_libs = &enforce
2026}
2027
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002028// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
2029// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
2030// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
2031// extension: APKs are supposed to end with '.apk').
2032func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00002033 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002034
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002035 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07002036
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002037 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
2038 // check is not necessary, and although it is good to have, it is difficult to maintain on
2039 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
2040 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01002041 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00002042 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002043 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00002044 }
2045
Colin Crossf1a035e2020-11-16 17:32:30 -08002046 rule := android.NewRuleBuilder(pctx, ctx)
2047 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07002048 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002049 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002050 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00002051 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002052
2053 if outputFile != nil {
2054 cmd.FlagWithOutput("-o ", outputFile)
2055 }
Colin Cross50ddcc42019-05-16 12:28:22 -07002056
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00002057 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
2058 cmd.Flag("--enforce-uses-libraries-relax")
2059 }
2060
Jiakai Zhangf98da192024-04-15 11:15:41 +00002061 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
2062 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002063 cmd.FlagWithArg("--uses-library ", lib)
2064 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00002065 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07002066 cmd.FlagWithArg("--optional-uses-library ", lib)
2067 }
2068
Jiakai Zhangf98da192024-04-15 11:15:41 +00002069 // Also add missing optional uses libs, as the manifest check expects them.
2070 // Note that what we add here are the module names of those missing libs, not library names, while
2071 // the manifest check actually expects library names. However, the case where a library is missing
2072 // and the module name != the library name is too rare for us to handle.
2073 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
2074 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
2075 }
2076
Colin Crossf1a035e2020-11-16 17:32:30 -08002077 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00002078 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002079}
Colin Cross50ddcc42019-05-16 12:28:22 -07002080
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002081// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
2082// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002083func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
2084 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002085 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00002086 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07002087}
2088
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00002089// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
2090// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00002091func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
2092 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
2093 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07002094}