blob: 082b00ee589b38ba5a5008b02dad484157be004c [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 Das9f7ae7f2022-07-25 00:34:18 +000074// Helper function that casts android.Module to java.androidTestApp
75// If this type conversion is possible, it queries whether the test app is included in an MTS suite
76func includedInMts(module android.Module) bool {
77 if test, ok := module.(androidTestApp); ok {
78 return test.includedInTestSuite("mts")
79 }
80 return false
81}
82
Gurpreet Singh75d65f32022-01-24 17:44:05 +000083type ManifestFixerParams struct {
Harshit Mahajan5b8b7302022-06-10 11:24:05 +000084 SdkContext android.SdkContext
85 ClassLoaderContexts dexpreopt.ClassLoaderContextMap
86 IsLibrary bool
87 DefaultManifestVersion string
88 UseEmbeddedNativeLibs bool
89 UsesNonSdkApis bool
90 UseEmbeddedDex bool
91 HasNoCode bool
92 TestOnly bool
93 LoggingParent string
94 EnforceDefaultTargetSdkVersion bool
Gurpreet Singh75d65f32022-01-24 17:44:05 +000095}
Colin Cross1b6a3cf2018-07-24 14:51:30 -070096
Gurpreet Singh75d65f32022-01-24 17:44:05 +000097// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
Gurpreet Singh7deabfa2022-02-10 13:28:35 +000098func ManifestFixer(ctx android.ModuleContext, manifest android.Path,
99 params ManifestFixerParams) android.Path {
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700100 var args []string
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000101
102 if params.IsLibrary {
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700103 args = append(args, "--library")
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000104 } else if params.SdkContext != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000105 minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -0800106 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000107 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Colin Crosse4246ab2019-02-05 21:55:21 -0800108 }
Jiyong Park54105c42021-03-31 18:17:53 +0900109 if minSdkVersion.FinalOrFutureInt() >= 23 {
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000110 args = append(args, fmt.Sprintf("--extract-native-libs=%v", !params.UseEmbeddedNativeLibs))
111 } else if params.UseEmbeddedNativeLibs {
Pedro Loureiroea2f5ef2022-04-22 13:53:16 +0000112 ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%s doesn't support it",
113 minSdkVersion.String())
Colin Crosse4246ab2019-02-05 21:55:21 -0800114 }
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700115 }
Colin Cross31656952018-05-24 16:11:20 -0700116
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000117 if params.UsesNonSdkApis {
David Brazdild25060a2019-02-18 18:24:16 +0000118 args = append(args, "--uses-non-sdk-api")
119 }
120
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000121 if params.UseEmbeddedDex {
Sasha Smundakd2e53612019-05-14 17:03:24 -0700122 args = append(args, "--use-embedded-dex")
Colin Cross46abdad2019-02-07 13:07:08 -0800123 }
124
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000125 if params.ClassLoaderContexts != nil {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100126 // Libraries propagated via `uses_libs`/`optional_uses_libs` are also added (they may be
127 // propagated from dependencies).
128 requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.UsesLibs()
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000129
130 for _, usesLib := range requiredUsesLibs {
131 args = append(args, "--uses-library", usesLib)
132 }
133 for _, usesLib := range optionalUsesLibs {
134 args = append(args, "--optional-uses-library", usesLib)
135 }
Colin Cross5446e882019-05-22 10:46:27 -0700136 }
137
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000138 if params.HasNoCode {
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700139 args = append(args, "--has-no-code")
140 }
141
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000142 if params.TestOnly {
143 args = append(args, "--test-only")
144 }
145
146 if params.LoggingParent != "" {
147 args = append(args, "--logging-parent", params.LoggingParent)
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800148 }
Colin Cross10932872019-04-18 14:27:12 -0700149 var deps android.Paths
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000150 var argsMapper = make(map[string]string)
Spandan Dasc8cb0c32021-12-08 17:00:38 +0000151
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000152 if params.SdkContext != nil {
Harshit Mahajan5b8b7302022-06-10 11:24:05 +0000153 targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000154
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000155 if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
156 targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
157 deps = append(deps, ApiFingerprintPath(ctx))
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000158 }
159
Paul Duffinaa2aad62023-01-31 23:13:45 +0000160 args = append(args, "--targetSdkVersion ", targetSdkVersion)
161
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000162 minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000163 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000164 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000165 }
166
William Loh5a082f92022-05-17 20:21:50 +0000167 replaceMaxSdkVersionPlaceholder, err := params.SdkContext.ReplaceMaxSdkVersionPlaceholder(ctx).EffectiveVersion(ctx)
168 if err != nil {
169 ctx.ModuleErrorf("invalid ReplaceMaxSdkVersionPlaceholder: %s", err)
170 }
171
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000172 if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
173 minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
174 deps = append(deps, ApiFingerprintPath(ctx))
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000175 }
176
177 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000178 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000179 }
180 args = append(args, "--minSdkVersion ", minSdkVersion)
William Loh5a082f92022-05-17 20:21:50 +0000181 args = append(args, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt()))
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000182 args = append(args, "--raise-min-sdk-version")
Jiyong Park6a927c42020-01-21 02:03:43 +0900183 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100184 if params.DefaultManifestVersion != "" {
185 args = append(args, "--override-placeholder-version", params.DefaultManifestVersion)
186 }
Jiyong Park6a927c42020-01-21 02:03:43 +0900187
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000188 fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000189 argsMapper["args"] = strings.Join(args, " ")
Colin Cross10932872019-04-18 14:27:12 -0700190
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000191 ctx.Build(pctx, android.BuildParams{
Colin Cross90c25c62019-04-19 16:22:57 -0700192 Rule: manifestFixerRule,
193 Description: "fix manifest",
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000194 Input: manifest,
Colin Cross90c25c62019-04-19 16:22:57 -0700195 Implicits: deps,
196 Output: fixedManifest,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000197 Args: argsMapper,
Colin Cross31656952018-05-24 16:11:20 -0700198 })
Colin Cross31656952018-05-24 16:11:20 -0700199
Colin Cross8eebb132020-01-29 20:07:03 -0800200 return fixedManifest.WithoutRel()
Colin Cross90c25c62019-04-19 16:22:57 -0700201}
Colin Cross31656952018-05-24 16:11:20 -0700202
Alixf7a10272023-09-27 16:47:56 +0000203type ManifestMergerParams struct {
204 staticLibManifests android.Paths
205 isLibrary bool
Alix96ea88452023-08-31 15:48:23 +0000206 packageName string
Alixf7a10272023-09-27 16:47:56 +0000207}
208
209func manifestMerger(ctx android.ModuleContext, manifest android.Path,
210 params ManifestMergerParams) android.Path {
Colin Crossaa1c6f12019-04-19 16:25:38 -0700211
Alix96ea88452023-08-31 15:48:23 +0000212 var args []string
Alixf7a10272023-09-27 16:47:56 +0000213 if !params.isLibrary {
Colin Crossaa1c6f12019-04-19 16:25:38 -0700214 // Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests.
Alix96ea88452023-08-31 15:48:23 +0000215 args = append(args, "--remove-tools-declarations")
216 }
217
218 packageName := params.packageName
219 if packageName != "" {
220 args = append(args, "--property PACKAGE="+packageName)
Colin Crossaa1c6f12019-04-19 16:25:38 -0700221 }
222
Colin Cross90c25c62019-04-19 16:22:57 -0700223 mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml")
224 ctx.Build(pctx, android.BuildParams{
225 Rule: manifestMergerRule,
226 Description: "merge manifest",
227 Input: manifest,
Alixf7a10272023-09-27 16:47:56 +0000228 Implicits: params.staticLibManifests,
Colin Cross90c25c62019-04-19 16:22:57 -0700229 Output: mergedManifest,
230 Args: map[string]string{
Alixf7a10272023-09-27 16:47:56 +0000231 "libs": android.JoinWithPrefix(params.staticLibManifests.Strings(), "--libs "),
Alix96ea88452023-08-31 15:48:23 +0000232 "args": strings.Join(args, " "),
Colin Cross90c25c62019-04-19 16:22:57 -0700233 },
234 })
235
Colin Cross8eebb132020-01-29 20:07:03 -0800236 return mergedManifest.WithoutRel()
Colin Cross31656952018-05-24 16:11:20 -0700237}