blob: dd99675163e7bb93b8e2ec5525e2d247194332de [file] [log] [blame]
Colin Cross30e076a2015-04-13 13:58:27 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
Jaewoong Jungf9b44652020-12-21 12:29:12 -080017// This file contains the module implementations for android_app, android_test, and some more
18// related module types, including their override variants.
Colin Cross30e076a2015-04-13 13:58:27 -070019
20import (
Jiakai Zhang4f65a032023-06-01 15:16:58 +010021 "fmt"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070022 "path/filepath"
Jaewoong Junga5e5abc2019-04-26 14:31:50 -070023 "strings"
Colin Cross30e076a2015-04-13 13:58:27 -070024
Aditya Choudhary9b593522023-10-06 19:54:58 +000025 "android/soong/testing"
Jihoon Kang84b25892023-12-01 22:01:06 +000026
Colin Cross50ddcc42019-05-16 12:28:22 -070027 "github.com/google/blueprint"
28 "github.com/google/blueprint/proptools"
29
Colin Cross635c3b02016-05-18 15:37:25 -070030 "android/soong/android"
Colin Crossa4f08812018-10-02 22:03:40 -070031 "android/soong/cc"
Ulya Trafimovichd4bcea42020-06-03 14:57:22 +010032 "android/soong/dexpreopt"
Romain Jobredeaux9973ace2023-08-30 00:27:09 -040033 "android/soong/genrule"
Colin Cross303e21f2018-08-07 16:49:25 -070034 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070035)
36
Colin Cross3bc7ffa2017-11-22 16:19:37 -080037func init() {
Paul Duffinf9b1da02019-12-18 19:51:55 +000038 RegisterAppBuildComponents(android.InitRegistrationContext)
Andrei Onea580636b2022-08-17 16:53:46 +000039 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080040}
41
Andrei Onea580636b2022-08-17 16:53:46 +000042var (
43 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
44 blueprint.RuleParams{
45 Command: "${ModifyAllowlistCmd} $in $packageName $out",
46 CommandDeps: []string{"${ModifyAllowlistCmd}"},
47 }, "packageName")
48)
49
Jihoon Kang9aef7772024-06-14 23:45:06 +000050type FlagsPackages struct {
51 // Paths to the aconfig dump output text files that are consumed by aapt2
52 AconfigTextFiles android.Paths
53}
54
55var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
56
Paul Duffinf9b1da02019-12-18 19:51:55 +000057func RegisterAppBuildComponents(ctx android.RegistrationContext) {
58 ctx.RegisterModuleType("android_app", AndroidAppFactory)
59 ctx.RegisterModuleType("android_test", AndroidTestFactory)
60 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
61 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
62 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
63 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +000064}
65
Colin Cross99939e92024-10-01 16:02:46 -070066type AppInfo struct {
67 // Updatable is set to the value of the updatable property
68 Updatable bool
69
70 // TestHelperApp is true if the module is a android_test_helper_app
71 TestHelperApp bool
72}
73
74var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
75
Colin Cross30e076a2015-04-13 13:58:27 -070076// AndroidManifest.xml merging
77// package splits
78
Colin Crossfabb6082018-02-20 17:22:23 -080079type appProperties struct {
Colin Crossbd01e2a2018-10-04 15:21:03 -070080 // Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Colin Cross7d5136f2015-05-11 13:39:40 -070081 Additional_certificates []string
82
83 // If set, create package-export.apk, which other packages can
84 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080085 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070086
Colin Cross16056062017-12-13 22:46:28 -080087 // Specifies that this app should be installed to the priv-app directory,
88 // where the system will grant it additional privileges not available to
89 // normal apps.
90 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070091
92 // list of resource labels to generate individual resource packages
93 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040094
Colin Crossa4f08812018-10-02 22:03:40 -070095 // list of native libraries that will be provided in or alongside the resulting jar
Jihoon Kang371a0372024-10-01 16:44:41 +000096 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"`
Colin Crossa4f08812018-10-02 22:03:40 -070097
Colin Cross7204cf02020-05-06 17:51:39 -070098 // if true, use JNI libraries that link against platform APIs even if this module sets
Colin Crossee87c602020-02-19 16:57:15 -080099 // sdk_version.
100 Jni_uses_platform_apis *bool
101
Colin Cross7204cf02020-05-06 17:51:39 -0700102 // if true, use JNI libraries that link against SDK APIs even if this module does not set
103 // sdk_version.
104 Jni_uses_sdk_apis *bool
105
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700106 // STL library to use for JNI libraries.
107 Stl *string `android:"arch_variant"`
108
Colin Crosse4246ab2019-02-05 21:55:21 -0800109 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
Jiyong Parkd044bb42024-05-15 02:09:54 +0900110 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
111 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
112 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native
113 // libraries are generally preinstalled outside the APK.
Colin Crosse4246ab2019-02-05 21:55:21 -0800114 Use_embedded_native_libs *bool
Colin Cross46abdad2019-02-07 13:07:08 -0800115
116 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
117 // they are used from inside the APK at runtime.
118 Use_embedded_dex *bool
Colin Cross47fa9d32019-03-26 10:51:39 -0700119
Jiyong Parkd044bb42024-05-15 02:09:54 +0900120 // Forces native libraries to always be packaged into the APK,
121 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
122 // True for android_test* modules.
123 AlwaysPackageNativeLibs bool `blueprint:"mutated"`
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700124
125 // If set, find and merge all NOTICE files that this module and its dependencies have and store
126 // it in the APK as an asset.
127 Embed_notices *bool
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700128
129 // cc.Coverage related properties
130 PreventInstall bool `blueprint:"mutated"`
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700131 IsCoverageVariant bool `blueprint:"mutated"`
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100132
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000133 // It can be set to test the behaviour of default target sdk version.
134 // Only required when updatable: false. It is an error if updatable: true and this is false.
135 Enforce_default_target_sdk_version *bool
136
137 // If set, the targetSdkVersion for the target is set to the latest default API level.
138 // This would be by default false, unless updatable: true or
139 // enforce_default_target_sdk_version: true in which case this defaults to true.
140 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`
141
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100142 // Whether this app is considered mainline updatable or not. When set to true, this will enforce
Artur Satayevf40fc852020-04-16 13:43:02 +0100143 // additional rules to make sure an app can safely be updated. Default is false.
144 // Prefer using other specific properties if build behaviour must be changed; avoid using this
145 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100146 Updatable *bool
Andrei Onea580636b2022-08-17 16:53:46 +0000147
148 // Specifies the file that contains the allowlist for this app.
149 Privapp_allowlist *string `android:"path"`
Inseob Kim34dc4cd2023-11-07 13:37:14 +0900150
151 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS
152 // and install the RRO package to /product partition, instead of passing --product argument
153 // to aapt2. Default is false.
154 // Setting this will make this APK identical to all targets, regardless of
155 // PRODUCT_CHARACTERISTICS.
156 Generate_product_characteristics_rro *bool
157
158 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"`
159 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700160}
161
Jaewoong Jung525443a2019-02-28 15:35:54 -0800162// android_app properties that can be overridden by override_android_app
163type overridableAppProperties struct {
164 // The name of a certificate in the default certificate directory, blank to use the default product certificate,
165 // or an android_app_certificate module name in the form ":module".
166 Certificate *string
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700167
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800168 // Name of the signing certificate lineage file or filegroup module.
169 Lineage *string `android:"path"`
Liz Kammere2b27f42020-05-07 13:24:05 -0700170
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400171 // For overriding the --rotation-min-sdk-version property of apksig
172 RotationMinSdkVersion *string
173
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700174 // 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 -0700175 Package_name proptools.Configurable[string]
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800176
177 // the logging parent of this app.
178 Logging_parent *string
Liz Kammer9f9fd022020-06-18 19:44:06 +0000179
180 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
181 Rename_resources_package *bool
zhidou198f5892022-02-17 02:33:12 +0000182
183 // Names of modules to be overridden. Listed modules can only be other binaries
184 // (in Make or Soong).
185 // This does not completely prevent installation of the overridden binaries, but if both
186 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
187 // from PRODUCT_PACKAGES.
188 Overrides []string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800189}
190
Colin Cross30e076a2015-04-13 13:58:27 -0700191type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -0700192 Library
193 aapt
Jaewoong Jung525443a2019-02-28 15:35:54 -0800194 android.OverridableModuleBase
Colin Crossa97c5d32018-03-28 14:58:31 -0700195
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900196 certificate Certificate
Colin Cross30e076a2015-04-13 13:58:27 -0700197
Colin Crossfabb6082018-02-20 17:22:23 -0800198 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -0700199
Jaewoong Jung525443a2019-02-28 15:35:54 -0800200 overridableAppProperties overridableAppProperties
201
Colin Cross403cc152020-07-06 14:15:24 -0700202 jniLibs []jniLib
203 installPathForJNISymbols android.Path
204 embeddedJniLibs bool
205 jniCoverageOutputs android.Paths
Colin Crossf6237212018-10-29 23:14:58 -0700206
207 bundleFile android.Path
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800208
209 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
210 installApkName string
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800211
Colin Cross70dda7e2019-10-01 22:05:35 -0700212 installDir android.InstallPath
Jaewoong Jung0949f312019-09-11 10:25:18 -0700213
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700214 onDeviceDir string
215
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800216 additionalAaptFlags []string
Jaewoong Jung98772792019-07-01 17:15:13 -0700217
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900218 overriddenManifestPackageName string
Artur Satayev1111b842020-04-27 19:05:28 +0100219
220 android.ApexBundleDepsInfo
Matt Banda8c801262022-04-01 17:48:31 +0000221
222 javaApiUsedByOutputFile android.ModuleOutPath
Andrei Onea580636b2022-08-17 16:53:46 +0000223
224 privAppAllowlist android.OptionalPath
Colin Crosse1731a52017-12-14 11:22:55 -0800225}
226
Martin Stjernholm6d415272020-01-31 17:10:36 +0000227func (a *AndroidApp) IsInstallable() bool {
228 return Bool(a.properties.Installable)
229}
230
Colin Crossab8d1382023-07-14 17:23:41 +0000231func (a *AndroidApp) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
232 return a.aapt.resourcesNodesDepSet
Colin Cross66f78822018-05-02 12:58:28 -0700233}
234
Sundong Ahne1f05aa2019-08-27 13:55:42 +0900235func (a *AndroidApp) OutputFile() android.Path {
236 return a.outputFile
237}
238
Colin Cross503c1d02020-01-28 14:00:53 -0800239func (a *AndroidApp) Certificate() Certificate {
240 return a.certificate
241}
242
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700243func (a *AndroidApp) JniCoverageOutputs() android.Paths {
244 return a.jniCoverageOutputs
245}
246
Andrei Onea580636b2022-08-17 16:53:46 +0000247func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
248 return a.privAppAllowlist
249}
250
Colin Crossa97c5d32018-03-28 14:58:31 -0700251var _ AndroidLibraryDependency = (*AndroidApp)(nil)
252
Jiyong Parkc00cbd92018-10-30 21:20:05 +0900253type Certificate struct {
Colin Cross503c1d02020-01-28 14:00:53 -0800254 Pem, Key android.Path
255 presigned bool
256}
257
Sasha Smundak18d98bc2020-05-27 16:36:07 -0700258var PresignedCertificate = Certificate{presigned: true}
Colin Cross503c1d02020-01-28 14:00:53 -0800259
260func (c Certificate) AndroidMkString() string {
261 if c.presigned {
262 return "PRESIGNED"
263 } else {
264 return c.Pem.String()
265 }
Colin Cross30e076a2015-04-13 13:58:27 -0700266}
267
Colin Cross46c9b8b2017-06-22 16:51:17 -0700268func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park92315372021-04-02 08:45:46 +0900269 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700270 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
271 }
272
Jiyong Parkf1691d22021-03-29 20:11:58 +0900273 sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
Jiakai Zhangf98da192024-04-15 11:15:41 +0000274 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
275 a.Module.deps(ctx)
Paul Duffin250e6192019-06-07 10:44:37 +0100276 if sdkDep.hasFrameworkLibs() {
277 a.aapt.deps(ctx, sdkDep)
Colin Cross30e076a2015-04-13 13:58:27 -0700278 }
Colin Crossa4f08812018-10-02 22:03:40 -0700279
Jiyong Park92315372021-04-02 08:45:46 +0900280 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
Colin Cross3c007702020-05-08 11:20:24 -0700281
282 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
283 ctx.PropertyErrorf("jni_uses_sdk_apis",
284 "can only be set for modules that do not set sdk_version")
285 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
286 ctx.PropertyErrorf("jni_uses_platform_apis",
287 "can only be set for modules that set sdk_version")
288 }
289
Colin Crossa4f08812018-10-02 22:03:40 -0700290 for _, jniTarget := range ctx.MultiTargets() {
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700291 variation := append(jniTarget.Variations(),
292 blueprint.Variation{Mutator: "link", Variation: "shared"})
Colin Crossc511bc52020-04-07 16:50:32 +0000293
Jiyong Park92d84042024-05-17 22:58:54 +0000294 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
295 // Many factors are considered here.
296 // 1. Basically, the selection follows whether the app has sdk_version set or not.
297 jniUsesSdkVariant := usesSDK
298 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
299 if Bool(a.appProperties.Jni_uses_sdk_apis) {
300 jniUsesSdkVariant = true
301 }
302 if Bool(a.appProperties.Jni_uses_platform_apis) {
303 jniUsesSdkVariant = false
304 }
305 // 3. Then the use of SDK variant is again prohibited for the following cases:
306 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
307 // partition (not only the app) is considered unbudled, there's no need to use the
308 // SDK variant.
309 // 3.2. the app doesn't support embedding the JNI libs
310 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
311 jniUsesSdkVariant = false
312 }
313 if jniUsesSdkVariant {
Colin Crossc511bc52020-04-07 16:50:32 +0000314 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
315 }
Jiyong Park92d84042024-05-17 22:58:54 +0000316
317 // Use the installable dep tag when the JNIs are not embedded
318 var tag dependencyTag
319 if a.shouldEmbedJnis(ctx) {
320 tag = jniLibTag
321 } else {
322 tag = jniInstallTag
323 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000324 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...)
Colin Crossa4f08812018-10-02 22:03:40 -0700325 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000326 for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
327 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
328 }
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700329}
Colin Crossbd01e2a2018-10-04 15:21:03 -0700330
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700331func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800332 cert := android.SrcIsModule(a.getCertString(ctx))
Colin Crossbd01e2a2018-10-04 15:21:03 -0700333 if cert != "" {
334 ctx.AddDependency(ctx.Module(), certificateTag, cert)
335 }
336
Andrei Onea580636b2022-08-17 16:53:46 +0000337 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
Anton Hanssone3f31cf2023-06-03 08:53:47 +0000338 // There are a few uids that are explicitly considered privileged regardless of their
339 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
340 // but for now, allow it not to be in priv-app.
341 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
342 if !privilegedBecauseOfUid {
343 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
344 }
Andrei Onea580636b2022-08-17 16:53:46 +0000345 }
346
Colin Crossbd01e2a2018-10-04 15:21:03 -0700347 for _, cert := range a.appProperties.Additional_certificates {
348 cert = android.SrcIsModule(cert)
349 if cert != "" {
350 ctx.AddDependency(ctx.Module(), certificateTag, cert)
351 } else {
352 ctx.PropertyErrorf("additional_certificates",
353 `must be names of android_app_certificate modules in the form ":module"`)
354 }
355 }
Colin Cross30e076a2015-04-13 13:58:27 -0700356}
357
Spandan Dasb0410872024-06-25 03:30:03 +0000358// TODO(b/156476221): Remove this allowlist
359var (
360 missingMinSdkVersionMtsAllowlist = []string{
361 "CellBroadcastReceiverGoogleUnitTests",
362 "CellBroadcastReceiverUnitTests",
363 "CtsBatterySavingTestCases",
364 "CtsDeviceAndProfileOwnerApp23",
365 "CtsDeviceAndProfileOwnerApp30",
366 "CtsIntentSenderApp",
367 "CtsJobSchedulerTestCases",
368 "CtsMimeMapTestCases",
369 "CtsTareTestCases",
370 "LibStatsPullTests",
371 "MediaProviderClientTests",
372 "TeleServiceTests",
373 "TestExternalImsServiceApp",
374 "TestSmsRetrieverApp",
375 "TetheringPrivilegedTests",
376 }
377)
378
379func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
380 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) {
381 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS")
382 }
383}
384
Jeongik Cha538c0d02019-07-11 15:54:27 +0900385func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +0000386 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
Alix96ea88452023-08-31 15:48:23 +0000387 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId
388 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -0700389 packageName := a.overridableAppProperties.Package_name.Get(ctx)
390 if packageName.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +0000391 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
392 }
393 a.aapt.manifestValues.applicationId = *applicationId
394 }
Jeongik Cha538c0d02019-07-11 15:54:27 +0900395 a.generateAndroidBuildActions(ctx)
Ronald Braunsteincdc66f42024-04-12 11:23:19 -0700396 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
397 TestOnly: true,
398 })
Colin Cross99939e92024-10-01 16:02:46 -0700399 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
400 Updatable: Bool(a.appProperties.Updatable),
401 TestHelperApp: true,
402 })
Jeongik Cha538c0d02019-07-11 15:54:27 +0900403}
404
Colin Cross46c9b8b2017-06-22 16:51:17 -0700405func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100406 a.checkAppSdkVersions(ctx)
Jiyong Park970c5242024-05-17 22:58:54 +0000407 a.checkEmbedJnis(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700408 a.generateAndroidBuildActions(ctx)
Matt Banda8c801262022-04-01 17:48:31 +0000409 a.generateJavaUsedByApex(ctx)
Colin Cross99939e92024-10-01 16:02:46 -0700410 android.SetProvider(ctx, AppInfoProvider, &AppInfo{
411 Updatable: Bool(a.appProperties.Updatable),
412 TestHelperApp: false,
413 })
Colin Crossae5caf52018-05-22 11:11:52 -0700414}
415
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100416func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
Artur Satayev849f8442020-04-28 14:57:42 +0100417 if a.Updatable() {
Jiyong Park92315372021-04-02 08:45:46 +0900418 if !a.SdkVersion(ctx).Stable() {
419 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100420 }
Spandan Dasb9c58352024-05-13 18:29:45 +0000421 if String(a.overridableProperties.Min_sdk_version) == "" {
Artur Satayevf40fc852020-04-16 13:43:02 +0100422 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
423 }
Jooyung Han749dc692020-04-15 11:03:39 +0900424
Jiyong Park92315372021-04-02 08:45:46 +0900425 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900426 a.checkJniLibsSdkVersion(ctx, minSdkVersion)
satayevb3fd4112021-12-02 13:59:35 +0000427 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900428 } else {
429 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
430 }
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000431
432 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
433 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
434 }
435 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
436 if a.deviceProperties.Target_sdk_version == nil {
437 a.SetEnforceDefaultTargetSdkVersion(true)
438 }
439 }
440
Artur Satayev2db1c3f2020-04-08 19:09:30 +0100441 a.checkPlatformAPI(ctx)
442 a.checkSdkVersions(ctx)
443}
444
Jiyong Park970c5242024-05-17 22:58:54 +0000445// Ensures that use_embedded_native_libs are set for apk-in-apex
446func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
447 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
448 apkInApex := !apexInfo.IsForPlatform()
Jihoon Kang371a0372024-10-01 16:44:41 +0000449 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0
Jiyong Park970c5242024-05-17 22:58:54 +0000450
451 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
452 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
453 }
454}
455
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900456// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
457// This check is enforced for "updatable" APKs (including APK-in-APEX).
Jiyong Park54105c42021-03-31 18:17:53 +0900458func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900459 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
460 ctx.VisitDirectDeps(func(m android.Module) {
461 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
462 return
463 }
464 dep, _ := m.(*cc.Module)
Jooyung Han652d5b32020-05-20 17:12:13 +0900465 // The domain of cc.sdk_version is "current" and <number>
Jiyong Parkf1691d22021-03-29 20:11:58 +0900466 // We can rely on android.SdkSpec to convert it to <number> so that "current" is
467 // handled properly regardless of sdk finalization.
Spandan Das2e8c0442022-05-08 00:39:35 +0000468 jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
Jiyong Park54105c42021-03-31 18:17:53 +0900469 if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
Spandan Das2e8c0442022-05-08 00:39:35 +0000470 ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
471 dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
Jooyung Hanbbc3fb72020-04-29 14:01:06 +0900472 return
473 }
474
475 })
476}
477
Sasha Smundak6ad77252019-05-01 13:16:22 -0700478// Returns true if the native libraries should be stored in the APK uncompressed and the
Colin Crosse4246ab2019-02-05 21:55:21 -0800479// extractNativeLibs application flag should be set to false in the manifest.
Sasha Smundak6ad77252019-05-01 13:16:22 -0700480func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
Jiyong Park92315372021-04-02 08:45:46 +0900481 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800482 if err != nil {
Jiyong Park92315372021-04-02 08:45:46 +0900483 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800484 }
485
Jiyong Parkd044bb42024-05-15 02:09:54 +0900486 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
487 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
488 !apexInfo.IsForPlatform()
Colin Crosse4246ab2019-02-05 21:55:21 -0800489}
490
Colin Cross43f08db2018-11-12 10:13:39 -0800491// Returns whether this module should have the dex file stored uncompressed in the APK.
492func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
Colin Cross46abdad2019-02-07 13:07:08 -0800493 if Bool(a.appProperties.Use_embedded_dex) {
494 return true
495 }
496
Colin Cross53a87f52019-06-25 13:35:30 -0700497 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
498 // be preinstalled as prebuilts).
Jiyong Parkf7487312019-10-17 12:54:30 +0900499 if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
Nicolas Geoffrayfa6e9ec2019-02-12 13:12:16 +0000500 return true
501 }
502
Colin Cross53a87f52019-06-25 13:35:30 -0700503 if ctx.Config().UnbundledBuild() {
504 return false
505 }
506
Spandan Dase21a8d42024-01-23 23:56:29 +0000507 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
Colin Cross5a0dcd52018-10-05 14:20:06 -0700508}
509
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700510func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
Jiyong Parkd044bb42024-05-15 02:09:54 +0900511 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
Jiyong Park970c5242024-05-17 22:58:54 +0000512 Bool(a.appProperties.Updatable) ||
513 a.appProperties.AlwaysPackageNativeLibs
Jiyong Parkef5511f2024-05-08 09:54:22 +0000514}
515
Liz Kammer9f9fd022020-06-18 19:44:06 +0000516func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
517 aaptFlags := []string{"--rename-manifest-package " + packageName}
518 if renameResourcesPackage {
519 // Required to rename the package name in the resources table.
520 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
521 }
522 return aaptFlags
523}
524
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900525func (a *AndroidApp) OverriddenManifestPackageName() string {
526 return a.overriddenManifestPackageName
527}
528
Liz Kammer9f9fd022020-06-18 19:44:06 +0000529func (a *AndroidApp) renameResourcesPackage() bool {
530 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
531}
532
Jihoon Kang9049c272024-03-19 21:57:36 +0000533func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
Jihoon Kang9aef7772024-06-14 23:45:06 +0000534 ctx.VisitDirectDeps(func(dep android.Module) {
535 tag := ctx.OtherModuleDependencyTag(dep)
536 switch tag {
537 case staticLibTag:
538 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
539 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
540 }
541
542 case aconfigDeclarationTag:
543 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
544 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
545 } else {
546 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
547 "flags_packages property, but %s is not aconfig_declarations module type",
548 dep.Name(),
549 )
550 }
Jihoon Kang9049c272024-03-19 21:57:36 +0000551 }
552 })
553
Jihoon Kang9aef7772024-06-14 23:45:06 +0000554 return android.FirstUniquePaths(aconfigTextFilePaths)
Jihoon Kang9049c272024-03-19 21:57:36 +0000555}
556
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800557func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900558 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
Jiyong Park92315372021-04-02 08:45:46 +0900559 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
Lorenzo Colittifa9b3f32021-03-30 10:38:26 +0900560 usePlatformAPI = true
561 }
562 a.aapt.usesNonSdkApis = usePlatformAPI
David Brazdild25060a2019-02-18 18:24:16 +0000563
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700564 // Ask manifest_fixer to add or update the application element indicating this app has no code.
565 a.aapt.hasNoCode = !a.hasCode(ctx)
566
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800567 aaptLinkFlags := []string{}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800568
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800569 // 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 +0900570 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro)
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800571 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
Inseob Kim10af6ed2024-02-13 12:56:46 +0900572 characteristics := ctx.Config().ProductAAPTCharacteristics()
573 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" {
574 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics)
Colin Crosse78dcd32018-04-19 15:25:19 -0700575 }
576
Dan Willemsen72be5902018-10-24 20:24:57 -0700577 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
578 // Product AAPT config
579 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800580 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
Dan Willemsen72be5902018-10-24 20:24:57 -0700581 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700582
Dan Willemsen72be5902018-10-24 20:24:57 -0700583 // Product AAPT preferred config
584 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
Jaewoong Jungde4c02f2019-01-22 11:19:56 -0800585 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Dan Willemsen72be5902018-10-24 20:24:57 -0700586 }
Colin Crosse78dcd32018-04-19 15:25:19 -0700587 }
588
Jiyong Park7f67f482019-01-05 12:57:48 +0900589 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
Cole Faust258b96f2024-10-04 10:48:24 -0700590 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
591 if overridden || packageNameProp.IsPresent() {
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700592 // The product override variable has a priority over the package_name property.
593 if !overridden {
Cole Faust258b96f2024-10-04 10:48:24 -0700594 manifestPackageName = packageNameProp.Get()
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700595 }
Liz Kammer9f9fd022020-06-18 19:44:06 +0000596 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
Jiyong Parkcfaa1642020-02-28 16:51:07 +0900597 a.overriddenManifestPackageName = manifestPackageName
Jiyong Park7f67f482019-01-05 12:57:48 +0900598 }
599
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800600 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
601
Colin Crosse560c4a2019-03-19 16:03:11 -0700602 a.aapt.splitNames = a.appProperties.Package_splits
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800603 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100604 if a.Updatable() {
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000605 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
606 a.aapt.defaultManifestVersion = override
607 } else {
Alyssa Ketpreechasawat3a6eced2024-08-22 15:09:16 +0000608 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion()
Alyssa Ketpreechasawatee8b44e2024-07-04 10:45:04 +0000609 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100610 }
Jihoon Kang84b25892023-12-01 22:01:06 +0000611
Rico Winda2fa2632024-03-13 13:09:17 +0100612 // Use non final ids if we are doing optimized shrinking and are using R8.
Rico Wind936754c2024-05-07 09:08:31 +0200613 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
Jihoon Kang9aef7772024-06-14 23:45:06 +0000614
615 aconfigTextFilePaths := getAconfigFilePaths(ctx)
616
Alixf7a10272023-09-27 16:47:56 +0000617 a.aapt.buildActions(ctx,
618 aaptBuildActionOptions{
Jihoon Kang84b25892023-12-01 22:01:06 +0000619 sdkContext: android.SdkContext(a),
620 classLoaderContexts: a.classLoaderContexts,
621 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
622 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
Rico Winda2fa2632024-03-13 13:09:17 +0100623 forceNonFinalResourceIDs: nonFinalIds,
Jihoon Kang84b25892023-12-01 22:01:06 +0000624 extraLinkFlags: aaptLinkFlags,
Jihoon Kang9aef7772024-06-14 23:45:06 +0000625 aconfigTextFiles: aconfigTextFilePaths,
Jiakai Zhang36937082024-04-15 11:15:50 +0000626 usesLibrary: &a.usesLibrary,
Alixf7a10272023-09-27 16:47:56 +0000627 },
628 )
Colin Cross30e076a2015-04-13 13:58:27 -0700629
Colin Cross46c9b8b2017-06-22 16:51:17 -0700630 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700631 a.properties.Manifest = nil
Jihoon Kang9aef7772024-06-14 23:45:06 +0000632
633 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
634 AconfigTextFiles: aconfigTextFilePaths,
635 })
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800636}
Colin Cross30e076a2015-04-13 13:58:27 -0700637
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800638func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
Colin Cross89c31582018-04-30 15:55:11 -0700639 var staticLibProguardFlagFiles android.Paths
640 ctx.VisitDirectDeps(func(m android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800641 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
Sam Delmerico95d70942023-08-02 18:00:35 -0400642 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
643 if ctx.OtherModuleDependencyTag(m) == staticLibTag {
644 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...)
Colin Cross89c31582018-04-30 15:55:11 -0700645 }
646 })
647
648 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
649
Colin Cross312634e2023-11-21 15:13:56 -0800650 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
Rico Wind936754c2024-05-07 09:08:31 +0200651 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
Rico Winda2fa2632024-03-13 13:09:17 +0100652 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
653 // live for code references and (transitively) mark these as live.
654 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
655 // dead code alive)
656 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
657 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800658}
Colin Cross66dbc0b2017-12-28 12:23:20 -0800659
Colin Cross403cc152020-07-06 14:15:24 -0700660func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
Colin Cross43f08db2018-11-12 10:13:39 -0800661 var installDir string
662 if ctx.ModuleName() == "framework-res" {
663 // framework-res.apk is installed as system/framework/framework-res.apk
664 installDir = "framework"
Jiyong Parkf7487312019-10-17 12:54:30 +0900665 } else if a.Privileged() {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800666 installDir = filepath.Join("priv-app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800667 } else {
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800668 installDir = filepath.Join("app", a.installApkName)
Colin Cross43f08db2018-11-12 10:13:39 -0800669 }
Colin Cross403cc152020-07-06 14:15:24 -0700670
671 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
672}
673
Rico Wind98e7fa82023-11-27 09:44:03 +0100674func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
Colin Cross403cc152020-07-06 14:15:24 -0700675 a.dexpreopter.installPath = a.installPath(ctx)
Ulya Trafimovich76b08522021-01-14 17:52:43 +0000676 a.dexpreopter.isApp = true
Liz Kammera7a64f32020-07-09 15:16:41 -0700677 if a.dexProperties.Uncompress_dex == nil {
David Srbeckye033cba2020-05-20 22:20:28 +0100678 // If the value was not force-set by the user, use reasonable default based on the module.
Liz Kammera7a64f32020-07-09 15:16:41 -0700679 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
David Srbeckye033cba2020-05-20 22:20:28 +0100680 }
Liz Kammera7a64f32020-07-09 15:16:41 -0700681 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
Colin Cross50ddcc42019-05-16 12:28:22 -0700682 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100683 a.dexpreopter.classLoaderContexts = a.classLoaderContexts
Colin Cross50ddcc42019-05-16 12:28:22 -0700684 a.dexpreopter.manifestFile = a.mergedManifestFile
Colin Crossfa9bfcd2021-11-10 16:42:38 -0800685 a.dexpreopter.preventInstall = a.appProperties.PreventInstall
Colin Cross50ddcc42019-05-16 12:28:22 -0700686
Rico Wind98e7fa82023-11-27 09:44:03 +0100687 var packageResources = a.exportPackage
688
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800689 if ctx.ModuleName() != "framework-res" {
Rico Wind936754c2024-05-07 09:08:31 +0200690 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100691 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
692 aapt2Convert(ctx, protoFile, packageResources, "proto")
693 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
694 }
695
Colin Cross4eae06d2023-06-20 22:40:02 -0700696 var extraSrcJars android.Paths
697 var extraClasspathJars android.Paths
698 var extraCombinedJars android.Paths
Colin Cross8f1b0332024-01-25 13:39:06 -0800699 if a.useResourceProcessorBusyBox(ctx) {
Colin Cross4eae06d2023-06-20 22:40:02 -0700700 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
701 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
702 // classpath when compiling everything else, and add it to the final classes jar.
703 extraClasspathJars = android.Paths{a.aapt.rJar}
704 extraCombinedJars = android.Paths{a.aapt.rJar}
705 } else {
706 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
707 // R.java files for the app's package and the packages from all transitive static android_library
708 // dependencies. Compile the srcjar alongside the rest of the sources.
709 extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
710 }
711
Colin Crossfdaa6722024-08-23 11:58:08 -0700712 a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
Rico Wind936754c2024-05-07 09:08:31 +0200713 if a.dexProperties.resourceShrinkingEnabled(ctx) {
Rico Wind98e7fa82023-11-27 09:44:03 +0100714 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
715 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
716 packageResources = binaryResources
717 }
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800718 }
Colin Cross30e076a2015-04-13 13:58:27 -0700719
Rico Wind98e7fa82023-11-27 09:44:03 +0100720 return a.dexJarFile.PathOrNil(), packageResources
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800721}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800722
Sam Delmerico82602492022-06-10 17:05:42 +0000723func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
Colin Crossa4f08812018-10-02 22:03:40 -0700724 var jniJarFile android.WritablePath
Sam Delmerico82602492022-06-10 17:05:42 +0000725 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 {
Colin Cross403cc152020-07-06 14:15:24 -0700726 a.jniLibs = jniLibs
Jaewoong Jungbc625cd2019-05-06 15:48:44 -0700727 if a.shouldEmbedJnis(ctx) {
Colin Crossa4f08812018-10-02 22:03:40 -0700728 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
Colin Crossc68db4b2021-11-11 18:59:15 -0800729 a.installPathForJNISymbols = a.installPath(ctx)
Sam Delmerico82602492022-06-10 17:05:42 +0000730 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx))
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700731 for _, jni := range jniLibs {
732 if jni.coverageFile.Valid() {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700733 // Only collect coverage for the first target arch if this is a multilib target.
734 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
735 // data file path collisions since the current coverage file path format doesn't contain
736 // arch-related strings. This is fine for now though; the code coverage team doesn't use
737 // multi-arch targets such as test_suite_* for coverage collections yet.
738 //
739 // Work with the team to come up with a new format that handles multilib modules properly
740 // and change this.
741 if len(ctx.Config().Targets[android.Android]) == 1 ||
Jaewoong Jung642916f2020-10-09 17:25:15 -0700742 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
Jaewoong Jung46984ee2020-04-07 13:07:55 -0700743 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
744 }
Jaewoong Jung87a33e72020-03-26 14:01:48 -0700745 }
746 }
Colin Cross403cc152020-07-06 14:15:24 -0700747 a.embeddedJniLibs = true
Colin Crossa4f08812018-10-02 22:03:40 -0700748 }
749 }
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800750 return jniJarFile
751}
Colin Crossa4f08812018-10-02 22:03:40 -0700752
Colin Cross403cc152020-07-06 14:15:24 -0700753func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
754 var jniSymbols android.RuleBuilderInstalls
755 for _, jniLib := range a.jniLibs {
756 if jniLib.unstrippedFile != nil {
757 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
758 From: jniLib.unstrippedFile,
759 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
760 })
761 }
762 }
763 return jniSymbols
764}
765
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700766// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
767// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
Colin Crossbc2c8a72022-09-14 12:45:42 -0700768func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate,
769 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) {
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700770 if android.SrcIsModule(certPropValue) == "" {
771 var mainCert Certificate
772 if certPropValue != "" {
773 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
774 mainCert = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -0800775 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
776 Key: defaultDir.Join(ctx, certPropValue+".pk8"),
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700777 }
778 } else {
779 pem, key := ctx.Config().DefaultAppCertificate(ctx)
Colin Cross503c1d02020-01-28 14:00:53 -0800780 mainCert = Certificate{
781 Pem: pem,
782 Key: key,
783 }
Colin Crossbd01e2a2018-10-04 15:21:03 -0700784 }
Jaewoong Jungccbb3932019-04-15 09:48:31 -0700785 certificates = append([]Certificate{mainCert}, certificates...)
Colin Crossbd01e2a2018-10-04 15:21:03 -0700786 }
787
Colin Crossbc2c8a72022-09-14 12:45:42 -0700788 if len(certificates) > 0 {
789 mainCertificate = certificates[0]
790 } else {
791 // This can be reached with an empty certificate list if AllowMissingDependencies is set
792 // and the certificate property for this module is a module reference to a missing module.
793 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
794 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
795 }
796 // Set a certificate to avoid panics later when accessing it.
797 mainCertificate = Certificate{
798 Key: android.PathForModuleOut(ctx, "missing.pk8"),
Colin Crossa54f4b52022-11-21 04:35:53 +0000799 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
Colin Crossbc2c8a72022-09-14 12:45:42 -0700800 }
801 }
802
Zyan Wub7550aa2023-05-18 15:46:31 +0800803 if !m.Platform() {
804 certPath := mainCertificate.Pem.String()
805 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
806 if strings.HasPrefix(certPath, systemCertPath) {
807 enforceSystemCert := ctx.Config().EnforceSystemCertificate()
808 allowed := ctx.Config().EnforceSystemCertificateAllowList()
809
810 if enforceSystemCert && !inList(m.Name(), allowed) {
811 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
812 }
813 }
814 }
815
Colin Crossbc2c8a72022-09-14 12:45:42 -0700816 return mainCertificate, certificates
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800817}
818
Jooyung Han39ee1192020-03-23 20:21:11 +0900819func (a *AndroidApp) InstallApkName() string {
820 return a.installApkName
821}
822
Sam Delmerico15809f82023-05-15 17:21:47 -0400823func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
Andrei Onea580636b2022-08-17 16:53:46 +0000824 if a.appProperties.Privapp_allowlist == nil {
825 return nil
826 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400827
828 isOverrideApp := a.GetOverriddenBy() != ""
829 if !isOverrideApp {
830 // if this is not an override, we don't need to rewrite the existing privapp allowlist
831 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
832 }
833
Cole Faust258b96f2024-10-04 10:48:24 -0700834 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
835 if packageNameProp.IsEmpty() {
Andrei Onea580636b2022-08-17 16:53:46 +0000836 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
837 }
Sam Delmerico15809f82023-05-15 17:21:47 -0400838
Cole Faust258b96f2024-10-04 10:48:24 -0700839 packageName := packageNameProp.Get()
Andrei Onea580636b2022-08-17 16:53:46 +0000840 fileName := "privapp_allowlist_" + packageName + ".xml"
841 outPath := android.PathForModuleOut(ctx, fileName).OutputPath
842 ctx.Build(pctx, android.BuildParams{
843 Rule: modifyAllowlist,
844 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
845 Output: outPath,
846 Args: map[string]string{
847 "packageName": packageName,
848 },
849 })
850 return &outPath
851}
852
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800853func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross50ddcc42019-05-16 12:28:22 -0700854 var apkDeps android.Paths
855
Colin Crossff694a82023-12-13 15:54:49 -0800856 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
857 if !apexInfo.IsForPlatform() {
Colin Cross56a83212020-09-15 18:30:11 -0700858 a.hideApexVariantFromMake = true
859 }
860
Jeongik Cha538c0d02019-07-11 15:54:27 +0900861 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
862 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
863
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000864 // Unlike installApkName, a.stem should respect base module name for override_android_app.
865 // Therefore, use ctx.ModuleName() instead of a.Name().
yangbill2af0b6e2024-03-15 09:29:29 +0000866 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000867
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800868 // Check if the install APK name needs to be overridden.
Jihoon Kang1bfb6f22023-07-01 00:13:47 +0000869 // Both android_app and override_android_app module are expected to possess
870 // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
871 // from the base module. Therefore, use a.Name() which represents
872 // the module name for both android_app and override_android_app.
873 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
yangbill2af0b6e2024-03-15 09:29:29 +0000874 proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800875
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700876 if ctx.ModuleName() == "framework-res" {
877 // framework-res.apk is installed as system/framework/framework-res.apk
Jaewoong Jung0949f312019-09-11 10:25:18 -0700878 a.installDir = android.PathForModuleInstall(ctx, "framework")
Jiyong Parkf7487312019-10-17 12:54:30 +0900879 } else if a.Privileged() {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700880 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
881 } else if ctx.InstallInTestcases() {
Jaewoong Jung326a9412019-11-21 10:41:00 -0800882 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700883 } else {
Jaewoong Jung0949f312019-09-11 10:25:18 -0700884 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700885 }
Jaewoong Jung7dd4ae22019-09-27 17:13:15 -0700886 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
Jaewoong Jung5b425e22019-06-17 17:40:56 -0700887
Ulya Trafimovichb23d28c2020-10-08 12:53:58 +0100888 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
Spandan Das0727ba72024-02-13 16:37:43 +0000889 if a.usesLibrary.shouldDisableDexpreopt {
890 a.dexpreopter.disableDexpreopt()
891 }
Ulya Trafimovich18554242020-11-03 15:55:11 +0000892
Colin Cross61fb62e2022-06-23 10:46:28 -0700893 var noticeAssetPath android.WritablePath
894 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
895 // The rule to create the notice file can't be generated yet, as the final output path
896 // for the apk isn't known yet. Add the path where the notice file will be generated to the
897 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will
898 // be generated later.
899 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
900 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
901 }
902
Harshit Mahajan8f202ad2023-01-09 20:45:55 +0000903 // For apps targeting latest target_sdk_version
904 if Bool(a.appProperties.Enforce_default_target_sdk_version) {
905 a.SetEnforceDefaultTargetSdkVersion(true)
906 }
907
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800908 // Process all building blocks, from AAPT to certificates.
909 a.aaptBuildActions(ctx)
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100910 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
911 a.usesLibrary.freezeEnforceUsesLibraries()
912
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +0100913 // Check that the <uses-library> list is coherent with the manifest.
Colin Cross50ddcc42019-05-16 12:28:22 -0700914 if a.usesLibrary.enforceUsesLibraries() {
Jiakai Zhangf98da192024-04-15 11:15:41 +0000915 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
916 ctx, a.mergedManifestFile, &a.classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -0700917 apkDeps = append(apkDeps, manifestCheckFile)
918 }
919
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800920 a.proguardBuildActions(ctx)
921
Colin Cross014489c2020-06-02 20:09:13 -0700922 a.linter.mergedManifest = a.aapt.mergedManifestFile
923 a.linter.manifest = a.aapt.manifestPath
924 a.linter.resources = a.aapt.resourceFiles
Colin Crossc0efd1d2020-07-03 11:56:24 -0700925 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
Colin Cross014489c2020-06-02 20:09:13 -0700926
Rico Wind98e7fa82023-11-27 09:44:03 +0100927 dexJarFile, packageResources := a.dexBuildActions(ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800928
Jiyong Park92d84042024-05-17 22:58:54 +0000929 // No need to check the SDK version of the JNI deps unless we embed them
930 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
931 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
Sam Delmerico82602492022-06-10 17:05:42 +0000932 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800933
934 if ctx.Failed() {
935 return
936 }
937
Colin Crossbc2c8a72022-09-14 12:45:42 -0700938 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx)
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800939
940 // Build a final signed app package.
Jaewoong Jung5a498812019-11-07 14:14:38 -0800941 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700942 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
943 var v4SignatureFile android.WritablePath = nil
944 if v4SigningRequested {
945 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
946 }
Liz Kammere2b27f42020-05-07 13:24:05 -0700947 var lineageFile android.Path
948 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
949 lineageFile = android.PathForModuleSrc(ctx, lineage)
950 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400951 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
952
Rico Wind98e7fa82023-11-27 09:44:03 +0100953 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800954 a.outputFile = packageFile
Songchun Fan17d69e32020-03-24 20:32:24 -0700955 if v4SigningRequested {
956 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
957 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800958
Colin Cross61fb62e2022-06-23 10:46:28 -0700959 if a.aapt.noticeFile.Valid() {
960 // Generating the notice file rule has to be here after a.outputFile is known.
Bob Badoureef4c1c2022-05-16 12:20:04 -0700961 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz")
Bob Badourc6ec9fb2022-06-08 15:59:35 -0700962 android.BuildNoticeHtmlOutputFromLicenseMetadata(
963 ctx, noticeFile, "", "",
964 []string{
965 a.installDir.String() + "/",
966 android.PathForModuleInstall(ctx).String() + "/",
967 a.outputFile.String(),
968 })
Bob Badoureef4c1c2022-05-16 12:20:04 -0700969 builder := android.NewRuleBuilder(pctx, ctx)
970 builder.Command().Text("cp").
971 Input(noticeFile).
972 Output(noticeAssetPath)
973 builder.Build("notice_dir", "Building notice dir")
Bob Badoureef4c1c2022-05-16 12:20:04 -0700974 }
975
Colin Crosse560c4a2019-03-19 16:03:11 -0700976 for _, split := range a.aapt.splits {
977 // Sign the split APKs
Jaewoong Jung5a498812019-11-07 14:14:38 -0800978 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
Songchun Fan17d69e32020-03-24 20:32:24 -0700979 if v4SigningRequested {
980 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
981 }
Rico Wind98e7fa82023-11-27 09:44:03 +0100982 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
Colin Crosse560c4a2019-03-19 16:03:11 -0700983 a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
Songchun Fan17d69e32020-03-24 20:32:24 -0700984 if v4SigningRequested {
985 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
986 }
Colin Crosse560c4a2019-03-19 16:03:11 -0700987 }
988
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800989 // Build an app bundle.
Colin Crossf6237212018-10-29 23:14:58 -0700990 bundleFile := android.PathForModuleOut(ctx, "base.zip")
991 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
992 a.bundleFile = bundleFile
993
Andrei Onea580636b2022-08-17 16:53:46 +0000994 allowlist := a.createPrivappAllowlist(ctx)
995 if allowlist != nil {
996 a.privAppAllowlist = android.OptionalPathForPath(allowlist)
997 }
998
Jaewoong Jung590b1ae2019-01-22 16:40:58 -0800999 // Install the app package.
Andrei Onea580636b2022-08-17 16:53:46 +00001000 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
1001 if shouldInstallAppPackage {
Sam Delmericob1daccd2023-05-25 14:45:30 -04001002 if a.privAppAllowlist.Valid() {
Anton Hansson0e486a42023-06-01 16:38:35 +00001003 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
1004 allowlistInstallFilename := a.installApkName + ".xml"
1005 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
Sam Delmericob1daccd2023-05-25 14:45:30 -04001006 }
1007
Colin Cross09ad3a62023-11-15 12:29:33 -08001008 var extraInstalledPaths android.InstallPaths
Jiyong Park8ba50f92019-11-13 15:01:01 +09001009 for _, extra := range a.extraOutputFiles {
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001010 installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
1011 extraInstalledPaths = append(extraInstalledPaths, installed)
Jiyong Park8ba50f92019-11-13 15:01:01 +09001012 }
Jiyong Park25b92222024-05-17 22:58:54 +00001013 // If we don't embed jni libs, make sure that those are installed along with the
1014 // app, and also place symlinks to the installed paths under the lib/<arch>
1015 // directory of the app installation directory. ex:
1016 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
1017 if !a.embeddedJniLibs {
1018 for _, jniLib := range jniLibs {
1019 archStr := jniLib.target.Arch.ArchType.String()
1020 symlinkDir := a.installDir.Join(ctx, "lib", archStr)
1021 for _, installedLib := range jniLib.installPaths {
Jiyong Park25b92222024-05-17 22:58:54 +00001022 // install the symlink itself
1023 symlinkName := installedLib.Base()
1024 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
1025 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
1026 }
1027 }
1028 }
Colin Cross1d0eb7a2021-11-03 14:08:20 -07001029 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
Colin Cross5ab4e6d2017-11-22 16:20:45 -08001030 }
Artur Satayev1111b842020-04-27 19:05:28 +01001031
Colin Crossa6182ab2024-08-21 10:47:44 -07001032 ctx.CheckbuildFile(a.outputFile)
1033
Artur Satayev1111b842020-04-27 19:05:28 +01001034 a.buildAppDependencyInfo(ctx)
Spandan Das3490dfd2024-03-11 21:37:25 +00001035
1036 providePrebuiltInfo(ctx,
1037 prebuiltInfoProps{
1038 baseModuleName: a.BaseModuleName(),
1039 isPrebuilt: false,
1040 },
1041 )
mrziwang9f7b9f42024-07-10 12:18:06 -07001042
1043 a.setOutputFiles(ctx)
1044}
1045
1046func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
1047 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
1048 if a.aaptSrcJar != nil {
1049 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
1050 }
1051 if a.rJar != nil {
1052 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
1053 }
1054 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
1055 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
1056 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
1057 setOutputFiles(ctx, a.Library.Module)
Colin Cross30e076a2015-04-13 13:58:27 -07001058}
1059
Colin Crossc2d24052020-05-13 11:05:02 -07001060type appDepsInterface interface {
Jiyong Park92315372021-04-02 08:45:46 +09001061 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001062 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Colin Crossc2d24052020-05-13 11:05:02 -07001063 RequiresStableAPIs(ctx android.BaseModuleContext) bool
1064}
1065
1066func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
1067 shouldCollectRecursiveNativeDeps bool,
Sam Delmerico82602492022-06-10 17:05:42 +00001068 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) {
Colin Crossc2d24052020-05-13 11:05:02 -07001069
Colin Crossc2d24052020-05-13 11:05:02 -07001070 if checkNativeSdkVersion {
Jiyong Park92315372021-04-02 08:45:46 +09001071 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
1072 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
Colin Crossc2d24052020-05-13 11:05:02 -07001073 }
Makoto Onuki2ca84272024-02-10 00:15:21 +00001074 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
1075 checkNativeSdkVersion, func(dep cc.LinkableInterface) bool {
1076 return !dep.IsNdk(ctx.Config()) && !dep.IsStubs()
1077 })
1078
1079 var certificates []Certificate
1080
1081 ctx.VisitDirectDeps(func(module android.Module) {
1082 otherName := ctx.OtherModuleName(module)
1083 tag := ctx.OtherModuleDependencyTag(module)
1084
1085 if tag == certificateTag {
1086 if dep, ok := module.(*AndroidAppCertificate); ok {
1087 certificates = append(certificates, dep.Certificate)
1088 } else {
1089 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
1090 }
1091 }
1092 })
1093 return jniLib, prebuiltJniPackages, certificates
1094}
1095
1096func collectJniDeps(ctx android.ModuleContext,
1097 shouldCollectRecursiveNativeDeps bool,
1098 checkNativeSdkVersion bool,
1099 filter func(cc.LinkableInterface) bool) ([]jniLib, android.Paths) {
1100 var jniLibs []jniLib
1101 var prebuiltJniPackages android.Paths
1102 seenModulePaths := make(map[string]bool)
Colin Crossc2d24052020-05-13 11:05:02 -07001103
Peter Collingbournead84f972019-12-17 16:46:18 -08001104 ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
Colin Crossa4f08812018-10-02 22:03:40 -07001105 otherName := ctx.OtherModuleName(module)
1106 tag := ctx.OtherModuleDependencyTag(module)
1107
Colin Crossf0913fb2020-07-29 12:59:39 -07001108 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
Ivan Lozano7f67c2a2022-06-27 16:00:26 -04001109 if dep, ok := module.(cc.LinkableInterface); ok {
Makoto Onuki2ca84272024-02-10 00:15:21 +00001110 if filter != nil && !filter(dep) {
Peter Collingbournead84f972019-12-17 16:46:18 -08001111 return false
1112 }
1113
Colin Crossa4f08812018-10-02 22:03:40 -07001114 lib := dep.OutputFile()
1115 if lib.Valid() {
Cole Faust64cb7c92021-09-14 17:32:49 -07001116 path := lib.Path()
1117 if seenModulePaths[path.String()] {
1118 return false
1119 }
1120 seenModulePaths[path.String()] = true
1121
1122 if checkNativeSdkVersion && dep.SdkVersion() == "" {
1123 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
1124 otherName)
1125 }
1126
Colin Crossa4f08812018-10-02 22:03:40 -07001127 jniLibs = append(jniLibs, jniLib{
Colin Cross403cc152020-07-06 14:15:24 -07001128 name: ctx.OtherModuleName(module),
1129 path: path,
1130 target: module.Target(),
1131 coverageFile: dep.CoverageOutputFile(),
1132 unstrippedFile: dep.UnstrippedOutputFile(),
Jihoon Kangf78a8902022-09-01 22:47:07 +00001133 partition: dep.Partition(),
Yu Liud46e5ae2024-08-15 18:46:17 +00001134 installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
Colin Crossa4f08812018-10-02 22:03:40 -07001135 })
Colin Crossdd5261c2022-12-19 12:26:43 -08001136 } else if ctx.Config().AllowMissingDependencies() {
1137 ctx.AddMissingDependencies([]string{otherName})
Colin Crossa4f08812018-10-02 22:03:40 -07001138 } else {
1139 ctx.ModuleErrorf("dependency %q missing output file", otherName)
1140 }
1141 } else {
1142 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
Colin Crossa4f08812018-10-02 22:03:40 -07001143 }
Peter Collingbournead84f972019-12-17 16:46:18 -08001144
1145 return shouldCollectRecursiveNativeDeps
1146 }
1147
Colin Cross313aa542023-12-13 13:47:44 -08001148 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
Sam Delmerico82602492022-06-10 17:05:42 +00001149 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
1150 }
1151
Peter Collingbournead84f972019-12-17 16:46:18 -08001152 return false
Colin Crossa4f08812018-10-02 22:03:40 -07001153 })
1154
Makoto Onuki2ca84272024-02-10 00:15:21 +00001155 return jniLibs, prebuiltJniPackages
Colin Crossa4f08812018-10-02 22:03:40 -07001156}
1157
Colin Cross8bf14fc2024-09-25 16:41:31 -07001158func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
Artur Satayev1111b842020-04-27 19:05:28 +01001159 ctx.WalkDeps(func(child, parent android.Module) bool {
1160 isExternal := !a.DepIsInSameApex(ctx, child)
1161 if am, ok := child.(android.ApexModule); ok {
Jooyung Han749dc692020-04-15 11:03:39 +09001162 if !do(ctx, parent, am, isExternal) {
1163 return false
1164 }
Artur Satayev1111b842020-04-27 19:05:28 +01001165 }
1166 return !isExternal
1167 })
1168}
1169
1170func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
1171 if ctx.Host() {
1172 return
1173 }
1174
1175 depsInfo := android.DepNameToDepInfoMap{}
Colin Cross8bf14fc2024-09-25 16:41:31 -07001176 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
Artur Satayev1111b842020-04-27 19:05:28 +01001177 depName := to.Name()
Artur Satayev533b98c2021-03-11 18:03:42 +00001178
1179 // Skip dependencies that are only available to APEXes; they are developed with updatability
1180 // in mind and don't need manual approval.
1181 if to.(android.ApexModule).NotAvailableForPlatform() {
1182 return true
1183 }
1184
Artur Satayev1111b842020-04-27 19:05:28 +01001185 if info, exist := depsInfo[depName]; exist {
1186 info.From = append(info.From, from.Name())
1187 info.IsExternal = info.IsExternal && externalDep
1188 depsInfo[depName] = info
1189 } else {
1190 toMinSdkVersion := "(no version)"
Jiyong Park92315372021-04-02 08:45:46 +09001191 if m, ok := to.(interface {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001192 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
Jiyong Park92315372021-04-02 08:45:46 +09001193 }); ok {
Spandan Das8c9ae7e2023-03-03 21:20:36 +00001194 if v := m.MinSdkVersion(ctx); !v.IsNone() {
1195 toMinSdkVersion = v.String()
Artur Satayev1111b842020-04-27 19:05:28 +01001196 }
Jiyong Park92315372021-04-02 08:45:46 +09001197 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
1198 // TODO(b/175678607) eliminate the use of MinSdkVersion returning
1199 // string
1200 if v := m.MinSdkVersion(); v != "" {
Jiyong Parkf1691d22021-03-29 20:11:58 +09001201 toMinSdkVersion = v
1202 }
Artur Satayev1111b842020-04-27 19:05:28 +01001203 }
1204 depsInfo[depName] = android.ApexModuleDepInfo{
1205 To: depName,
1206 From: []string{from.Name()},
1207 IsExternal: externalDep,
1208 MinSdkVersion: toMinSdkVersion,
1209 }
1210 }
Jooyung Han749dc692020-04-15 11:03:39 +09001211 return true
Artur Satayev1111b842020-04-27 19:05:28 +01001212 })
1213
Jiyong Park92315372021-04-02 08:45:46 +09001214 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
Artur Satayev1111b842020-04-27 19:05:28 +01001215}
1216
Harshit Mahajan5b8b7302022-06-10 11:24:05 +00001217func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
1218 return a.appProperties.EnforceDefaultTargetSdkVersion
1219}
1220
1221func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
1222 a.appProperties.EnforceDefaultTargetSdkVersion = val
1223}
1224
Artur Satayev849f8442020-04-28 14:57:42 +01001225func (a *AndroidApp) Updatable() bool {
Colin Cross56a83212020-09-15 18:30:11 -07001226 return Bool(a.appProperties.Updatable)
Artur Satayev849f8442020-04-28 14:57:42 +01001227}
1228
Colin Cross0ea8ba82019-06-06 14:33:29 -07001229func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001230 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
1231 if overridden {
Jaewoong Jungacb6db32019-02-28 16:22:30 +00001232 return ":" + certificate
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001233 }
Jaewoong Jung525443a2019-02-28 15:35:54 -08001234 return String(a.overridableAppProperties.Certificate)
Jaewoong Jung2ad817c2019-01-18 14:27:16 -08001235}
1236
Jiyong Park0f80c182020-01-31 02:49:53 +09001237func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1238 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
1239 return true
1240 }
1241 return a.Library.DepIsInSameApex(ctx, dep)
1242}
1243
Jiyong Parkf7487312019-10-17 12:54:30 +09001244func (a *AndroidApp) Privileged() bool {
1245 return Bool(a.appProperties.Privileged)
1246}
1247
Colin Crosse1a85552024-06-14 12:17:37 -07001248func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
Colin Cross1a6acd42020-06-16 17:51:46 -07001249 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001250}
1251
Ivan Lozanod7586b62021-04-01 09:49:36 -04001252func (a *AndroidApp) SetPreventInstall() {
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001253 a.appProperties.PreventInstall = true
1254}
1255
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001256func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
1257 a.appProperties.IsCoverageVariant = coverage
1258}
1259
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -04001260func (a *AndroidApp) EnableCoverageIfNeeded() {}
1261
Jaewoong Jung87a33e72020-03-26 14:01:48 -07001262var _ cc.Coverage = (*AndroidApp)(nil)
1263
Cole Faustb36d31d2024-08-27 16:04:28 -07001264func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
1265 a.Library.IDEInfo(ctx, dpInfo)
1266 a.aapt.IDEInfo(ctx, dpInfo)
Colin Cross95b53b82023-10-17 13:21:02 -07001267}
1268
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001269func (a *AndroidApp) productCharacteristicsRROPackageName() string {
1270 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName)
1271}
1272
1273func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string {
1274 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName)
1275}
1276
Colin Cross1b16b0e2019-02-12 14:41:32 -08001277// android_app compiles sources and Android resources into an Android application package `.apk` file.
Colin Cross36242852017-06-23 15:06:31 -07001278func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -07001279 module := &AndroidApp{}
1280
Liz Kammera7a64f32020-07-09 15:16:41 -07001281 module.Module.dexProperties.Optimize.EnabledByDefault = true
1282 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
Jared Dukeaa88b3d2023-08-29 17:07:20 +00001283 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
Colin Cross66dbc0b2017-12-28 12:23:20 -08001284
Colin Crossae5caf52018-05-22 11:11:52 -07001285 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001286 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001287 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001288
Colin Crossce6734e2020-06-15 16:09:53 -07001289 module.addHostAndDeviceProperties()
Colin Cross36242852017-06-23 15:06:31 -07001290 module.AddProperties(
Colin Crossa97c5d32018-03-28 14:58:31 -07001291 &module.aaptProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001292 &module.appProperties,
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001293 &module.overridableAppProperties,
1294 &module.Library.sourceProperties)
Colin Cross36242852017-06-23 15:06:31 -07001295
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001296 module.usesLibrary.enforce = true
1297
Colin Crossa4f08812018-10-02 22:03:40 -07001298 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1299 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001300 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jiyong Park52cd06f2019-11-11 10:14:32 +09001301 android.InitApexModule(module)
Colin Crossa4f08812018-10-02 22:03:40 -07001302
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001303 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
1304 a := ctx.Module().(*AndroidApp)
1305
1306 characteristics := ctx.Config().ProductAAPTCharacteristics()
1307 if characteristics == "default" || characteristics == "" {
1308 module.appProperties.Generate_product_characteristics_rro = nil
1309 // no need to create RRO
1310 return
1311 }
1312
1313 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) {
1314 return
1315 }
1316
1317 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
1318 rroManifestName := rroPackageName + "_manifest"
1319
1320 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
1321 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName)
1322
1323 rroManifestProperties := struct {
1324 Name *string
1325 Tools []string
1326 Out []string
1327 Srcs []string
1328 Cmd *string
1329 }{
1330 Name: proptools.StringPtr(rroManifestName),
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001331 Tools: []string{"characteristics_rro_generator", "aapt2"},
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001332 Out: []string{"AndroidManifest.xml"},
Inseob Kim5b90d3a2024-02-14 16:55:33 +09001333 Srcs: []string{":" + a.Name() + "{.apk}"},
1334 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"),
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001335 }
1336 ctx.CreateModule(genrule.GenRuleFactory, &rroManifestProperties)
1337
1338 rroProperties := struct {
1339 Name *string
1340 Filter_product *string
1341 Aaptflags []string
1342 Manifest *string
1343 Resource_dirs []string
1344 }{
1345 Name: proptools.StringPtr(rroPackageName),
1346 Filter_product: proptools.StringPtr(characteristics),
1347 Aaptflags: []string{"--auto-add-overlay"},
1348 Manifest: proptools.StringPtr(":" + rroManifestName),
1349 Resource_dirs: a.aaptProperties.Resource_dirs,
1350 }
优秀d75e9982024-05-09 07:15:55 +00001351 if !Bool(a.aaptProperties.Aapt_include_all_resources) {
1352 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
1353 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
1354 }
1355 }
Inseob Kim34dc4cd2023-11-07 13:37:14 +09001356 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
1357 })
1358
Colin Cross36242852017-06-23 15:06:31 -07001359 return module
Colin Cross30e076a2015-04-13 13:58:27 -07001360}
Colin Crossae5caf52018-05-22 11:11:52 -07001361
Alix96ea88452023-08-31 15:48:23 +00001362// A dictionary of values to be overridden in the manifest.
1363type Manifest_values struct {
1364 // Overrides the value of package_name in the manifest
1365 ApplicationId *string
1366}
1367
Colin Crossae5caf52018-05-22 11:11:52 -07001368type appTestProperties struct {
Liz Kammer6b0c5522020-04-28 16:10:55 -07001369 // The name of the android_app module that the tests will run against.
Colin Crossae5caf52018-05-22 11:11:52 -07001370 Instrumentation_for *string
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001371
Seth Moorec6f4b532023-02-02 13:22:26 -08001372 // If specified, the instrumentation target package name in the manifest is overwritten by it.
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001373 Instrumentation_target_package *string
Seth Moorec6f4b532023-02-02 13:22:26 -08001374
1375 // If specified, the mainline module package name in the test config is overwritten by it.
1376 Mainline_package_name *string
Alix96ea88452023-08-31 15:48:23 +00001377
1378 Manifest_values Manifest_values
Colin Crossae5caf52018-05-22 11:11:52 -07001379}
1380
1381type AndroidTest struct {
1382 AndroidApp
1383
1384 appTestProperties appTestProperties
1385
1386 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -07001387
Dan Shi95d19422020-08-15 12:24:26 -07001388 testConfig android.Path
1389 extraTestConfigs android.Paths
1390 data android.Paths
Colin Crossae5caf52018-05-22 11:11:52 -07001391}
1392
Jaewoong Jung0949f312019-09-11 10:25:18 -07001393func (a *AndroidTest) InstallInTestcases() bool {
1394 return true
1395}
1396
Spandan Das9f7ae7f2022-07-25 00:34:18 +00001397type androidTestApp interface {
1398 includedInTestSuite(searchPrefix string) bool
1399}
1400
1401func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool {
1402 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix)
1403}
1404
1405func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool {
1406 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix)
1407}
1408
Colin Crossae5caf52018-05-22 11:11:52 -07001409func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Spandan Dasb0410872024-06-25 03:30:03 +00001410 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx))
easoncylee5bcff5d2020-04-30 14:57:06 +08001411 var configs []tradefed.Config
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001412 if a.appTestProperties.Instrumentation_target_package != nil {
1413 a.additionalAaptFlags = append(a.additionalAaptFlags,
1414 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
1415 } else if a.appTestProperties.Instrumentation_for != nil {
1416 // Check if the instrumentation target package is overridden.
Jaewoong Jung4102e5d2019-02-27 16:26:28 -08001417 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
1418 if overridden {
1419 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
1420 }
1421 }
Alix96ea88452023-08-31 15:48:23 +00001422 applicationId := a.appTestProperties.Manifest_values.ApplicationId
1423 if applicationId != nil {
Cole Faust258b96f2024-10-04 10:48:24 -07001424 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1425 if packageNameProp.IsPresent() {
Alix96ea88452023-08-31 15:48:23 +00001426 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.")
1427 }
1428 a.aapt.manifestValues.applicationId = *applicationId
1429 }
Colin Crossae5caf52018-05-22 11:11:52 -07001430 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -07001431
easoncylee5bcff5d2020-04-30 14:57:06 +08001432 for _, module := range a.testProperties.Test_mainline_modules {
1433 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
1434 }
1435
Jaewoong Jung39982342020-01-14 10:27:18 -08001436 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
Dan Shi4b34a722024-09-26 17:47:16 +00001437 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites,
1438 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options)
Jaewoong Jung39982342020-01-14 10:27:18 -08001439 a.testConfig = a.FixTestConfig(ctx, testConfig)
Dan Shi95d19422020-08-15 12:24:26 -07001440 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
Colin Cross8a497952019-03-05 22:25:09 -08001441 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
Colin Cross40213022023-12-13 15:19:49 -08001442 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001443 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1444 InstalledFiles: a.data,
1445 OutputFile: a.OutputFile(),
1446 TestConfig: a.testConfig,
1447 HostRequiredModuleNames: a.HostRequiredModuleNames(),
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +00001448 TestSuites: a.testProperties.Test_suites,
1449 IsHost: false,
Ronald Braunstein01d31bd2024-06-02 07:07:02 -07001450 LocalCertificate: a.certificate.AndroidMkString(),
1451 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test),
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001452 })
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001453 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1454 TestOnly: true,
1455 TopLevelTarget: true,
1456 })
1457
Colin Cross303e21f2018-08-07 16:49:25 -07001458}
1459
Jaewoong Jung39982342020-01-14 10:27:18 -08001460func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
1461 if testConfig == nil {
1462 return nil
1463 }
1464
1465 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
Colin Crossf1a035e2020-11-16 17:32:30 -08001466 rule := android.NewRuleBuilder(pctx, ctx)
1467 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
Jaewoong Jung39982342020-01-14 10:27:18 -08001468 fixNeeded := false
1469
Jooyung Han29e2f6d2022-01-08 12:13:59 +09001470 // 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 -08001471 if ctx.ModuleName() != a.installApkName {
1472 fixNeeded = true
1473 command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
1474 }
1475
Cole Faust258b96f2024-10-04 10:48:24 -07001476 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx)
1477 if packageNameProp.IsPresent() {
Jaewoong Jung39982342020-01-14 10:27:18 -08001478 fixNeeded = true
1479 command.FlagWithInput("--manifest ", a.manifestPath).
Cole Faust258b96f2024-10-04 10:48:24 -07001480 FlagWithArg("--package-name ", packageNameProp.Get())
Jaewoong Jung39982342020-01-14 10:27:18 -08001481 }
1482
Seth Moorec6f4b532023-02-02 13:22:26 -08001483 if a.appTestProperties.Mainline_package_name != nil {
1484 fixNeeded = true
1485 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name)
1486 }
1487
Jaewoong Jung39982342020-01-14 10:27:18 -08001488 if fixNeeded {
Colin Crossf1a035e2020-11-16 17:32:30 -08001489 rule.Build("fix_test_config", "fix test config")
Jaewoong Jung39982342020-01-14 10:27:18 -08001490 return fixedConfig
1491 }
1492 return testConfig
1493}
1494
Yihan Dong8be09c22024-08-29 15:32:13 +08001495func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
1496 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1497 // Instrument the android_test_helper target to log potential API calls at the run time.
1498 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1499 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1500 a.setApiMapper(true)
1501 }
1502 a.AndroidApp.DepsMutator(ctx)
1503}
1504
Colin Cross303e21f2018-08-07 16:49:25 -07001505func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
Yihan Dong8be09c22024-08-29 15:32:13 +08001506 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
1507 // Instrument the android_test_helper target to log potential API calls at the run time.
1508 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
1509 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
1510 a.setApiMapper(true)
1511 }
Colin Cross303e21f2018-08-07 16:49:25 -07001512 a.AndroidApp.DepsMutator(ctx)
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001513}
1514
1515func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
1516 a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
Colin Cross4b964c02018-10-15 16:18:06 -07001517 if a.appTestProperties.Instrumentation_for != nil {
1518 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
1519 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
1520 // use instrumentationForTag instead of libTag.
1521 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
1522 }
Colin Crossae5caf52018-05-22 11:11:52 -07001523}
1524
Colin Cross1b16b0e2019-02-12 14:41:32 -08001525// android_test compiles test sources and Android resources into an Android application package `.apk` file and
1526// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
Colin Crossae5caf52018-05-22 11:11:52 -07001527func AndroidTestFactory() android.Module {
1528 module := &AndroidTest{}
1529
Jared Duke63a3da92022-06-02 19:11:14 +00001530 module.Module.dexProperties.Optimize.EnabledByDefault = false
Colin Cross5067db92018-09-17 16:46:35 -07001531
1532 module.Module.properties.Instrument = true
Paul Duffin0038a8d2022-05-03 00:28:40 +00001533 module.Module.properties.Supports_static_instrumentation = true
Colin Cross9ae1b922018-06-26 17:59:05 -07001534 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001535 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1536 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001537 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001538 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -07001539
Colin Crossce6734e2020-06-15 16:09:53 -07001540 module.addHostAndDeviceProperties()
Colin Crossae5caf52018-05-22 11:11:52 -07001541 module.AddProperties(
Colin Crossae5caf52018-05-22 11:11:52 -07001542 &module.aaptProperties,
1543 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001544 &module.appTestProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001545 &module.overridableAppProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -07001546 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -07001547
Colin Crossa4f08812018-10-02 22:03:40 -07001548 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1549 android.InitDefaultableModule(module)
zhidou198f5892022-02-17 02:33:12 +00001550 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
Jingwen Chene12c0832023-08-25 09:00:16 +00001551
Colin Crossae5caf52018-05-22 11:11:52 -07001552 return module
1553}
Colin Crossbd01e2a2018-10-04 15:21:03 -07001554
Colin Cross252fc6f2018-10-04 15:22:03 -07001555type appTestHelperAppProperties struct {
1556 // list of compatibility suites (for example "cts", "vts") that the module should be
1557 // installed into.
1558 Test_suites []string `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -07001559
1560 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1561 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1562 // explicitly.
1563 Auto_gen_config *bool
Colin Crosscfb0f5e2021-09-24 15:47:17 -07001564
1565 // Install the test into a folder named for the module in all test suites.
1566 Per_testcase_directory *bool
Alix96ea88452023-08-31 15:48:23 +00001567
1568 Manifest_values Manifest_values
Colin Cross252fc6f2018-10-04 15:22:03 -07001569}
1570
1571type AndroidTestHelperApp struct {
1572 AndroidApp
1573
1574 appTestHelperAppProperties appTestHelperAppProperties
1575}
1576
Jaewoong Jung326a9412019-11-21 10:41:00 -08001577func (a *AndroidTestHelperApp) InstallInTestcases() bool {
1578 return true
1579}
1580
Colin Cross1b16b0e2019-02-12 14:41:32 -08001581// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
1582// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
1583// test.
Colin Cross252fc6f2018-10-04 15:22:03 -07001584func AndroidTestHelperAppFactory() android.Module {
1585 module := &AndroidTestHelperApp{}
1586
Jared Duke63a3da92022-06-02 19:11:14 +00001587 // TODO(b/192032291): Disable by default after auditing downstream usage.
Liz Kammera7a64f32020-07-09 15:16:41 -07001588 module.Module.dexProperties.Optimize.EnabledByDefault = true
Colin Cross252fc6f2018-10-04 15:22:03 -07001589
1590 module.Module.properties.Installable = proptools.BoolPtr(true)
Jiyong Parkd044bb42024-05-15 02:09:54 +09001591 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
1592 module.appProperties.AlwaysPackageNativeLibs = true
Colin Cross43f08db2018-11-12 10:13:39 -08001593 module.Module.dexpreopter.isTest = true
Cole Faustd57e8b22022-08-11 11:59:04 -07001594 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
Colin Cross252fc6f2018-10-04 15:22:03 -07001595
Colin Crossce6734e2020-06-15 16:09:53 -07001596 module.addHostAndDeviceProperties()
Colin Cross252fc6f2018-10-04 15:22:03 -07001597 module.AddProperties(
Colin Cross252fc6f2018-10-04 15:22:03 -07001598 &module.aaptProperties,
1599 &module.appProperties,
Jaewoong Jung525443a2019-02-28 15:35:54 -08001600 &module.appTestHelperAppProperties,
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001601 &module.overridableAppProperties)
Colin Cross252fc6f2018-10-04 15:22:03 -07001602
1603 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
1604 android.InitDefaultableModule(module)
Anton Hansson3d2b6b42020-01-10 15:06:01 +00001605 android.InitApexModule(module)
Colin Cross252fc6f2018-10-04 15:22:03 -07001606 return module
1607}
1608
Colin Crossbd01e2a2018-10-04 15:21:03 -07001609type AndroidAppCertificate struct {
1610 android.ModuleBase
Rupert Shuttleworth6e4950a2021-07-27 01:34:59 -04001611
Colin Crossbd01e2a2018-10-04 15:21:03 -07001612 properties AndroidAppCertificateProperties
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001613 Certificate Certificate
Colin Crossbd01e2a2018-10-04 15:21:03 -07001614}
1615
1616type AndroidAppCertificateProperties struct {
1617 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
1618 Certificate *string
1619}
1620
Colin Cross1b16b0e2019-02-12 14:41:32 -08001621// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
1622// the signing key.
Colin Crossbd01e2a2018-10-04 15:21:03 -07001623func AndroidAppCertificateFactory() android.Module {
1624 module := &AndroidAppCertificate{}
1625 module.AddProperties(&module.properties)
1626 android.InitAndroidModule(module)
1627 return module
1628}
1629
Colin Crossbd01e2a2018-10-04 15:21:03 -07001630func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1631 cert := String(c.properties.Certificate)
Jiyong Parkc00cbd92018-10-30 21:20:05 +09001632 c.Certificate = Certificate{
Colin Cross503c1d02020-01-28 14:00:53 -08001633 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
1634 Key: android.PathForModuleSrc(ctx, cert+".pk8"),
Colin Crossbd01e2a2018-10-04 15:21:03 -07001635 }
1636}
Jaewoong Jung525443a2019-02-28 15:35:54 -08001637
1638type OverrideAndroidApp struct {
1639 android.ModuleBase
1640 android.OverrideModuleBase
1641}
1642
Sasha Smundak613cbb12020-06-05 10:27:23 -07001643func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
Jaewoong Jung525443a2019-02-28 15:35:54 -08001644 // All the overrides happen in the base module.
1645 // TODO(jungjw): Check the base module type.
1646}
1647
1648// override_android_app is used to create an android_app module based on another android_app by overriding
1649// some of its properties.
1650func OverrideAndroidAppModuleFactory() android.Module {
1651 m := &OverrideAndroidApp{}
Jooyung Han01d80d82022-01-08 12:16:32 +09001652 m.AddProperties(
yangbill2af0b6e2024-03-15 09:29:29 +00001653 &OverridableProperties{},
Jooyung Han01d80d82022-01-08 12:16:32 +09001654 &overridableAppProperties{},
1655 )
Jaewoong Jung525443a2019-02-28 15:35:54 -08001656
Jaewoong Jungb639a6a2019-05-10 15:16:29 -07001657 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
Jaewoong Jung525443a2019-02-28 15:35:54 -08001658 android.InitOverrideModule(m)
1659 return m
1660}
Jaewoong Jungccbb3932019-04-15 09:48:31 -07001661
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001662type OverrideAndroidTest struct {
1663 android.ModuleBase
1664 android.OverrideModuleBase
1665}
1666
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001667func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001668 // All the overrides happen in the base module.
1669 // TODO(jungjw): Check the base module type.
Ronald Braunsteincdc66f42024-04-12 11:23:19 -07001670 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1671 TestOnly: true,
1672 TopLevelTarget: true,
1673 })
Jaewoong Jung26dedd32019-06-06 08:45:58 -07001674}
1675
1676// override_android_test is used to create an android_app module based on another android_test by overriding
1677// some of its properties.
1678func OverrideAndroidTestModuleFactory() android.Module {
1679 m := &OverrideAndroidTest{}
1680 m.AddProperties(&overridableAppProperties{})
1681 m.AddProperties(&appTestProperties{})
1682
1683 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
1684 android.InitOverrideModule(m)
1685 return m
1686}
1687
Colin Cross50ddcc42019-05-16 12:28:22 -07001688type UsesLibraryProperties struct {
1689 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
1690 Uses_libs []string
1691
1692 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
1693 // required=false.
1694 Optional_uses_libs []string
1695
1696 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
1697 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
1698 Enforce_uses_libs *bool
Ulya Trafimovich21a73752020-09-01 17:33:48 +01001699
Ulya Trafimovich54027b52020-09-09 14:08:23 +01001700 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK
1701 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
1702 // normally is the same as the module name, but there are exceptions.
1703 Provides_uses_lib *string
Paul Duffin06530572022-02-03 17:54:15 +00001704
1705 // A list of shared library names to exclude from the classpath of the APK. Adding a library here
1706 // will prevent it from being used when precompiling the APK and prevent it from being implicitly
1707 // added to the APK's manifest's <uses-library> elements.
1708 //
1709 // Care must be taken when using this as it could result in runtime errors if the APK actually
1710 // uses classes provided by the library and which are not provided in any other way.
1711 //
1712 // This is primarily intended for use by various CTS tests that check the runtime handling of the
1713 // android.test.base shared library (and related libraries) but which depend on some common
1714 // libraries that depend on the android.test.base library. Without this those tests will end up
1715 // with a <uses-library android:name="android.test.base"/> in their manifest which would either
1716 // render the tests worthless (as they would be testing the wrong behavior), or would break the
1717 // test altogether by providing access to classes that the tests were not expecting. Those tests
1718 // provide the android.test.base statically and use jarjar to rename them so they do not collide
1719 // with the classes provided by the android.test.base library.
1720 Exclude_uses_libs []string
Jiakai Zhangf98da192024-04-15 11:15:41 +00001721
1722 // The module names of optional uses-library libraries that are missing from the source tree.
1723 Missing_optional_uses_libs []string `blueprint:"mutated"`
Colin Cross50ddcc42019-05-16 12:28:22 -07001724}
1725
1726// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
1727// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
1728// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
1729// with knowledge of their shared libraries.
1730type usesLibrary struct {
1731 usesLibraryProperties UsesLibraryProperties
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001732
1733 // Whether to enforce verify_uses_library check.
1734 enforce bool
Spandan Das0727ba72024-02-13 16:37:43 +00001735
1736 // Whether dexpreopt should be disabled
1737 shouldDisableDexpreopt bool
Colin Cross50ddcc42019-05-16 12:28:22 -07001738}
1739
Colin Cross4a80a152022-12-21 21:51:52 -08001740func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
Jeongik Cha4b073cd2021-06-08 11:35:00 +09001741 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001742 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
Jiakai Zhangf98da192024-04-15 11:15:41 +00001743 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
1744 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
Colin Cross4a80a152022-12-21 21:51:52 -08001745 // Only add these extra dependencies if the module is an app that depends on framework
1746 // libs. This avoids creating a cyclic dependency:
Paul Duffin250e6192019-06-07 10:44:37 +01001747 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
Colin Cross4a80a152022-12-21 21:51:52 -08001748 if addCompatDeps {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001749 // Dexpreopt needs paths to the dex jars of these libraries in order to construct
1750 // class loader context for dex2oat. Add them as a dependency with a special tag.
1751 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
1752 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
1753 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
Colin Cross3245b2c2019-06-07 13:18:09 -07001754 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001755 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
1756 u.usesLibraryProperties.Missing_optional_uses_libs = diff
Sam Delmerico9f9c0a22022-11-29 11:19:37 -05001757 } else {
1758 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
1759 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
Colin Cross50ddcc42019-05-16 12:28:22 -07001760 }
1761}
1762
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001763// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
Colin Cross50ddcc42019-05-16 12:28:22 -07001764func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001765 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool {
1766 exists := ctx.OtherModuleExists(s)
Jiakai Zhang48203e32023-06-02 23:42:21 +01001767 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
Jiakai Zhang4f65a032023-06-01 15:16:58 +01001768 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
1769 }
1770 return exists
1771 })
Colin Cross50ddcc42019-05-16 12:28:22 -07001772 return optionalUsesLibs
1773}
1774
Ulya Trafimovich24446712021-07-15 14:59:34 +01001775// Returns a map of module names of shared library dependencies to the paths to their dex jars on
1776// host and on device.
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001777func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
1778 clcMap := make(dexpreopt.ClassLoaderContextMap)
Ulya Trafimovich24446712021-07-15 14:59:34 +01001779
1780 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
1781 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
1782 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
1783 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001784 }
1785
Ulya Trafimovich24446712021-07-15 14:59:34 +01001786 ctx.VisitDirectDeps(func(m android.Module) {
1787 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
1788 if !isUsesLibTag {
1789 return
1790 }
1791
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001792 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
Ulya Trafimovich24446712021-07-15 14:59:34 +01001793
Ulya Trafimovich840efb62021-07-15 14:34:40 +01001794 // Skip stub libraries. A dependency on the implementation library has been added earlier,
1795 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
1796 // from implementation libraries by their name, which is different as it has a suffix.
1797 if comp, ok := m.(SdkLibraryComponentDependency); ok {
1798 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
1799 return
1800 }
1801 }
1802
Ulya Trafimovich24446712021-07-15 14:59:34 +01001803 if lib, ok := m.(UsesLibraryDependency); ok {
Jihoon Kang98e9ac62024-09-25 23:42:30 +00001804 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
1805 // Skip java_sdk_library dependencies that provide stubs, but not an implementation.
1806 // This will be restricted to optional_uses_libs
1807 if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
1808 u.shouldDisableDexpreopt = true
1809 return
1810 }
1811 }
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001812 libName := dep
Ulya Trafimovich24446712021-07-15 14:59:34 +01001813 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
Ulya Trafimoviche14f80b2021-07-15 15:05:48 +01001814 libName = *ulib.ProvidesUsesLib()
Ulya Trafimovich24446712021-07-15 14:59:34 +01001815 }
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +01001816 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
Spandan Das59a4a2b2024-01-09 21:35:56 +00001817 lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +01001818 lib.ClassLoaderContexts())
Ulya Trafimovich24446712021-07-15 14:59:34 +01001819 } else if ctx.Config().AllowMissingDependencies() {
1820 ctx.AddMissingDependencies([]string{dep})
1821 } else {
1822 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
1823 }
1824 })
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +00001825 return clcMap
Colin Cross50ddcc42019-05-16 12:28:22 -07001826}
1827
1828// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
1829// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
1830// unconditionally in the future.
1831func (u *usesLibrary) enforceUsesLibraries() bool {
1832 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
1833 len(u.usesLibraryProperties.Optional_uses_libs) > 0
Ulya Trafimovich22890c42021-01-05 12:04:17 +00001834 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
Colin Cross50ddcc42019-05-16 12:28:22 -07001835}
1836
Ulya Trafimovichfc24ad32020-08-19 16:32:54 +01001837// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
1838func (u *usesLibrary) freezeEnforceUsesLibraries() {
1839 enforce := u.enforceUsesLibraries()
1840 u.usesLibraryProperties.Enforce_uses_libs = &enforce
1841}
1842
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001843// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
1844// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
1845// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
1846// extension: APKs are supposed to end with '.apk').
1847func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
Jiakai Zhangf98da192024-04-15 11:15:41 +00001848 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001849
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001850 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
Colin Cross50ddcc42019-05-16 12:28:22 -07001851
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001852 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
1853 // check is not necessary, and although it is good to have, it is difficult to maintain on
1854 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
1855 // various unrelated reasons, such as a failure to get manifest from an APK).
Ulya Trafimovich39dd0a42021-03-29 14:57:34 +01001856 global := dexpreopt.GetGlobalConfig(ctx)
Jiakai Zhang23984422023-11-09 16:47:04 +00001857 if global.DisablePreopt || global.OnlyPreoptArtBootImage {
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001858 return inputFile
Ulya Trafimovich6e55ef12021-03-04 12:37:50 +00001859 }
1860
Colin Crossf1a035e2020-11-16 17:32:30 -08001861 rule := android.NewRuleBuilder(pctx, ctx)
1862 cmd := rule.Command().BuiltTool("manifest_check").
Colin Cross50ddcc42019-05-16 12:28:22 -07001863 Flag("--enforce-uses-libraries").
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001864 Input(inputFile).
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001865 FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
Saeid Farivar Asanjanfd27c7c2022-08-08 20:21:26 +00001866 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001867
1868 if outputFile != nil {
1869 cmd.FlagWithOutput("-o ", outputFile)
1870 }
Colin Cross50ddcc42019-05-16 12:28:22 -07001871
Ulya Trafimovich8c35fcf2021-02-17 16:23:28 +00001872 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
1873 cmd.Flag("--enforce-uses-libraries-relax")
1874 }
1875
Jiakai Zhangf98da192024-04-15 11:15:41 +00001876 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
1877 for _, lib := range requiredUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001878 cmd.FlagWithArg("--uses-library ", lib)
1879 }
Jiakai Zhangf98da192024-04-15 11:15:41 +00001880 for _, lib := range optionalUsesLibs {
Colin Cross50ddcc42019-05-16 12:28:22 -07001881 cmd.FlagWithArg("--optional-uses-library ", lib)
1882 }
1883
Jiakai Zhangf98da192024-04-15 11:15:41 +00001884 // Also add missing optional uses libs, as the manifest check expects them.
1885 // Note that what we add here are the module names of those missing libs, not library names, while
1886 // the manifest check actually expects library names. However, the case where a library is missing
1887 // and the module name != the library name is too rare for us to handle.
1888 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
1889 cmd.FlagWithArg("--missing-optional-uses-library ", lib)
1890 }
1891
Colin Crossf1a035e2020-11-16 17:32:30 -08001892 rule.Build("verify_uses_libraries", "verify <uses-library>")
Ulya Trafimovicha76d6602021-03-16 15:34:50 +00001893 return outputFile
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001894}
Colin Cross50ddcc42019-05-16 12:28:22 -07001895
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001896// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
1897// the build system and returns the path to a copy of the manifest.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001898func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
1899 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001900 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
Jiakai Zhangf98da192024-04-15 11:15:41 +00001901 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
Colin Cross50ddcc42019-05-16 12:28:22 -07001902}
1903
Ulya Trafimovich0aba2522021-03-03 16:38:37 +00001904// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
1905// system and returns the path to a copy of the APK.
Jiakai Zhangf98da192024-04-15 11:15:41 +00001906func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
1907 classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
1908 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
Colin Cross50ddcc42019-05-16 12:28:22 -07001909}