blob: 0c77968e69c30c7d04cb76259b28c1e981095dd6 [file] [log] [blame]
Colin Cross31656952018-05-24 16:11:20 -07001// Copyright 2018 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
17import (
Colin Crosse4246ab2019-02-05 21:55:21 -080018 "fmt"
Spandan Dasc8cb0c32021-12-08 17:00:38 +000019 "strconv"
Colin Cross1b6a3cf2018-07-24 14:51:30 -070020 "strings"
Colin Cross31656952018-05-24 16:11:20 -070021
22 "github.com/google/blueprint"
23
24 "android/soong/android"
Ulya Trafimovich31e444e2020-08-14 17:32:16 +010025 "android/soong/dexpreopt"
Colin Cross31656952018-05-24 16:11:20 -070026)
27
28var manifestFixerRule = pctx.AndroidStaticRule("manifestFixer",
29 blueprint.RuleParams{
Colin Cross7b59e7b2018-09-10 13:35:13 -070030 Command: `${config.ManifestFixerCmd} ` +
Colin Cross7b59e7b2018-09-10 13:35:13 -070031 `$args $in $out`,
Colin Cross31656952018-05-24 16:11:20 -070032 CommandDeps: []string{"${config.ManifestFixerCmd}"},
33 },
Gurpreet Singh75d65f32022-01-24 17:44:05 +000034 "args")
Colin Cross31656952018-05-24 16:11:20 -070035
36var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",
37 blueprint.RuleParams{
Colin Crossaa1c6f12019-04-19 16:25:38 -070038 Command: `${config.ManifestMergerCmd} $args --main $in $libs --out $out`,
Colin Cross87ecbfe2019-02-26 22:14:04 -080039 CommandDeps: []string{"${config.ManifestMergerCmd}"},
Colin Cross31656952018-05-24 16:11:20 -070040 },
Colin Crossaa1c6f12019-04-19 16:25:38 -070041 "args", "libs")
Colin Cross31656952018-05-24 16:11:20 -070042
Spandan Dasc8cb0c32021-12-08 17:00:38 +000043// targetSdkVersion for manifest_fixer
44// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK
45// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK
Harshit Mahajan5b8b7302022-06-10 11:24:05 +000046func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string {
Spandan Dasca70fc42023-03-01 23:38:49 +000047 targetSdkVersionLevel := params.SdkContext.TargetSdkVersion(ctx)
Harshit Mahajan5b8b7302022-06-10 11:24:05 +000048
49 // Check if we want to return 10000
Spandan Das9f7ae7f2022-07-25 00:34:18 +000050 // TODO(b/240294501): Determine the rules for handling test apexes
Spandan Dasca70fc42023-03-01 23:38:49 +000051 if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionLevel, params.EnforceDefaultTargetSdkVersion) {
Spandan Dasc8cb0c32021-12-08 17:00:38 +000052 return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
53 }
Spandan Dasca70fc42023-03-01 23:38:49 +000054 targetSdkVersion, err := targetSdkVersionLevel.EffectiveVersionString(ctx)
Spandan Dasc8cb0c32021-12-08 17:00:38 +000055 if err != nil {
56 ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
57 }
58 return targetSdkVersion
59}
60
Harshit Mahajan5b8b7302022-06-10 11:24:05 +000061// Return true for modules targeting "current" if either
62// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
63// 2. The module is run as part of MTS, and should be testable on stable branches
64// Do not return 10000 if we are enforcing default targetSdkVersion and sdk has been finalised
Spandan Dasca70fc42023-03-01 23:38:49 +000065func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionLevel android.ApiLevel, enforceDefaultTargetSdkVersion bool) bool {
Spandan Dasfb6a1ee2023-04-27 16:08:26 +000066 // If this is a REL branch, do not return 10000
67 if ctx.Config().PlatformSdkFinal() {
Harshit Mahajan5b8b7302022-06-10 11:24:05 +000068 return false
69 }
Spandan Dasfb6a1ee2023-04-27 16:08:26 +000070 // If this a module targeting an unreleased SDK (MTS or unbundled builds), return 10000
Spandan Dasca70fc42023-03-01 23:38:49 +000071 return targetSdkVersionLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module()))
Harshit Mahajan5b8b7302022-06-10 11:24:05 +000072}
73
Spandan Dasb0410872024-06-25 03:30:03 +000074// Helper function that returns true if android_test, android_test_helper_app, java_test are in an MTS suite.
Spandan Das9f7ae7f2022-07-25 00:34:18 +000075func includedInMts(module android.Module) bool {
76 if test, ok := module.(androidTestApp); ok {
77 return test.includedInTestSuite("mts")
78 }
Spandan Dasb0410872024-06-25 03:30:03 +000079 // java_test
80 if test, ok := module.(*Test); ok {
81 return android.PrefixInList(test.testProperties.Test_suites, "mts")
82 }
Spandan Das9f7ae7f2022-07-25 00:34:18 +000083 return false
84}
85
Gurpreet Singh75d65f32022-01-24 17:44:05 +000086type ManifestFixerParams struct {
Harshit Mahajan5b8b7302022-06-10 11:24:05 +000087 SdkContext android.SdkContext
88 ClassLoaderContexts dexpreopt.ClassLoaderContextMap
89 IsLibrary bool
90 DefaultManifestVersion string
91 UseEmbeddedNativeLibs bool
92 UsesNonSdkApis bool
93 UseEmbeddedDex bool
94 HasNoCode bool
95 TestOnly bool
96 LoggingParent string
97 EnforceDefaultTargetSdkVersion bool
Gurpreet Singh75d65f32022-01-24 17:44:05 +000098}
Colin Cross1b6a3cf2018-07-24 14:51:30 -070099
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000100// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000101func ManifestFixer(ctx android.ModuleContext, manifest android.Path,
102 params ManifestFixerParams) android.Path {
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700103 var args []string
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000104
105 if params.IsLibrary {
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700106 args = append(args, "--library")
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000107 } else if params.SdkContext != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000108 minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800109 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000110 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800111 }
Jiyong Park54105c42021-03-31 18:17:53 +0900112 if minSdkVersion.FinalOrFutureInt() >= 23 {
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000113 args = append(args, fmt.Sprintf("--extract-native-libs=%v", !params.UseEmbeddedNativeLibs))
114 } else if params.UseEmbeddedNativeLibs {
Pedro Loureiroea2f5ef2022-04-22 13:53:16 +0000115 ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%s doesn't support it",
116 minSdkVersion.String())
Colin Crosse4246ab2019-02-05 21:55:21 -0800117 }
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700118 }
Colin Cross31656952018-05-24 16:11:20 -0700119
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000120 if params.UsesNonSdkApis {
David Brazdild25060a2019-02-18 18:24:16 +0000121 args = append(args, "--uses-non-sdk-api")
122 }
123
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000124 if params.UseEmbeddedDex {
Sasha Smundakd2e53612019-05-14 17:03:24 -0700125 args = append(args, "--use-embedded-dex")
Colin Cross46abdad2019-02-07 13:07:08 -0800126 }
127
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000128 if params.ClassLoaderContexts != nil {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100129 // Libraries propagated via `uses_libs`/`optional_uses_libs` are also added (they may be
130 // propagated from dependencies).
131 requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.UsesLibs()
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000132
133 for _, usesLib := range requiredUsesLibs {
134 args = append(args, "--uses-library", usesLib)
135 }
136 for _, usesLib := range optionalUsesLibs {
137 args = append(args, "--optional-uses-library", usesLib)
138 }
Colin Cross5446e882019-05-22 10:46:27 -0700139 }
140
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000141 if params.HasNoCode {
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700142 args = append(args, "--has-no-code")
143 }
144
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000145 if params.TestOnly {
146 args = append(args, "--test-only")
147 }
148
149 if params.LoggingParent != "" {
150 args = append(args, "--logging-parent", params.LoggingParent)
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800151 }
Colin Cross10932872019-04-18 14:27:12 -0700152 var deps android.Paths
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000153 var argsMapper = make(map[string]string)
Spandan Dasc8cb0c32021-12-08 17:00:38 +0000154
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000155 if params.SdkContext != nil {
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000156 targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000157
Jihoon Kang842b9992024-02-08 01:41:51 +0000158 if useApiFingerprint, fingerprintTargetSdkVersion, fingerprintDeps :=
159 UseApiFingerprint(ctx); useApiFingerprint && ctx.ModuleName() != "framework-res" {
160 targetSdkVersion = fingerprintTargetSdkVersion
161 deps = append(deps, fingerprintDeps)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000162 }
163
Paul Duffinaa2aad62023-01-31 23:13:45 +0000164 args = append(args, "--targetSdkVersion ", targetSdkVersion)
165
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000166 minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000167 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000168 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000169 }
170
William Loh5a082f92022-05-17 20:21:50 +0000171 replaceMaxSdkVersionPlaceholder, err := params.SdkContext.ReplaceMaxSdkVersionPlaceholder(ctx).EffectiveVersion(ctx)
172 if err != nil {
173 ctx.ModuleErrorf("invalid ReplaceMaxSdkVersionPlaceholder: %s", err)
174 }
175
Jihoon Kang842b9992024-02-08 01:41:51 +0000176 if useApiFingerprint, fingerprintMinSdkVersion, fingerprintDeps :=
177 UseApiFingerprint(ctx); useApiFingerprint && ctx.ModuleName() != "framework-res" {
178 minSdkVersion = fingerprintMinSdkVersion
179 deps = append(deps, fingerprintDeps)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000180 }
181
182 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000183 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000184 }
185 args = append(args, "--minSdkVersion ", minSdkVersion)
William Loh5a082f92022-05-17 20:21:50 +0000186 args = append(args, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt()))
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000187 args = append(args, "--raise-min-sdk-version")
Jiyong Park6a927c42020-01-21 02:03:43 +0900188 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100189 if params.DefaultManifestVersion != "" {
190 args = append(args, "--override-placeholder-version", params.DefaultManifestVersion)
191 }
Jiyong Park6a927c42020-01-21 02:03:43 +0900192
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000193 fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000194 argsMapper["args"] = strings.Join(args, " ")
Colin Cross10932872019-04-18 14:27:12 -0700195
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000196 ctx.Build(pctx, android.BuildParams{
Colin Cross90c25c62019-04-19 16:22:57 -0700197 Rule: manifestFixerRule,
198 Description: "fix manifest",
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000199 Input: manifest,
Colin Cross90c25c62019-04-19 16:22:57 -0700200 Implicits: deps,
201 Output: fixedManifest,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000202 Args: argsMapper,
Colin Cross31656952018-05-24 16:11:20 -0700203 })
Colin Cross31656952018-05-24 16:11:20 -0700204
Colin Cross8eebb132020-01-29 20:07:03 -0800205 return fixedManifest.WithoutRel()
Colin Cross90c25c62019-04-19 16:22:57 -0700206}
Colin Cross31656952018-05-24 16:11:20 -0700207
Alixf7a10272023-09-27 16:47:56 +0000208type ManifestMergerParams struct {
209 staticLibManifests android.Paths
210 isLibrary bool
Alix96ea88452023-08-31 15:48:23 +0000211 packageName string
Alixf7a10272023-09-27 16:47:56 +0000212}
213
214func manifestMerger(ctx android.ModuleContext, manifest android.Path,
215 params ManifestMergerParams) android.Path {
Colin Crossaa1c6f12019-04-19 16:25:38 -0700216
Alix96ea88452023-08-31 15:48:23 +0000217 var args []string
Alixf7a10272023-09-27 16:47:56 +0000218 if !params.isLibrary {
Colin Crossaa1c6f12019-04-19 16:25:38 -0700219 // Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests.
Alix96ea88452023-08-31 15:48:23 +0000220 args = append(args, "--remove-tools-declarations")
221 }
222
223 packageName := params.packageName
224 if packageName != "" {
225 args = append(args, "--property PACKAGE="+packageName)
Colin Crossaa1c6f12019-04-19 16:25:38 -0700226 }
227
Colin Cross90c25c62019-04-19 16:22:57 -0700228 mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml")
229 ctx.Build(pctx, android.BuildParams{
230 Rule: manifestMergerRule,
231 Description: "merge manifest",
232 Input: manifest,
Alixf7a10272023-09-27 16:47:56 +0000233 Implicits: params.staticLibManifests,
Colin Cross90c25c62019-04-19 16:22:57 -0700234 Output: mergedManifest,
235 Args: map[string]string{
Alixf7a10272023-09-27 16:47:56 +0000236 "libs": android.JoinWithPrefix(params.staticLibManifests.Strings(), "--libs "),
Alix96ea88452023-08-31 15:48:23 +0000237 "args": strings.Join(args, " "),
Colin Cross90c25c62019-04-19 16:22:57 -0700238 },
239 })
240
Colin Cross8eebb132020-01-29 20:07:03 -0800241 return mergedManifest.WithoutRel()
Colin Cross31656952018-05-24 16:11:20 -0700242}