blob: 522b6647a53eb2077a097debba350477aa6a6ae5 [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
46func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext android.SdkContext) string {
47 targetSdkVersionSpec := sdkContext.TargetSdkVersion(ctx)
Spandan Das9f7ae7f2022-07-25 00:34:18 +000048 // Return 10000 for modules targeting "current" if either
49 // 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
50 // 2. The module is run as part of MTS, and should be testable on stable branches
51 // TODO(b/240294501): Determine the rules for handling test apexes
52 if targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module())) {
Spandan Dasc8cb0c32021-12-08 17:00:38 +000053 return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
54 }
55 targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx)
56 if err != nil {
57 ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
58 }
59 return targetSdkVersion
60}
61
Spandan Das9f7ae7f2022-07-25 00:34:18 +000062// Helper function that casts android.Module to java.androidTestApp
63// If this type conversion is possible, it queries whether the test app is included in an MTS suite
64func includedInMts(module android.Module) bool {
65 if test, ok := module.(androidTestApp); ok {
66 return test.includedInTestSuite("mts")
67 }
68 return false
69}
70
Gurpreet Singh75d65f32022-01-24 17:44:05 +000071type ManifestFixerParams struct {
Alexei Nicoara69cf0f32022-07-27 14:59:18 +010072 SdkContext android.SdkContext
73 ClassLoaderContexts dexpreopt.ClassLoaderContextMap
74 IsLibrary bool
75 DefaultManifestVersion string
76 UseEmbeddedNativeLibs bool
77 UsesNonSdkApis bool
78 UseEmbeddedDex bool
79 HasNoCode bool
80 TestOnly bool
81 LoggingParent string
Gurpreet Singh75d65f32022-01-24 17:44:05 +000082}
Colin Cross1b6a3cf2018-07-24 14:51:30 -070083
Gurpreet Singh75d65f32022-01-24 17:44:05 +000084// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
Gurpreet Singh7deabfa2022-02-10 13:28:35 +000085func ManifestFixer(ctx android.ModuleContext, manifest android.Path,
86 params ManifestFixerParams) android.Path {
Colin Cross1b6a3cf2018-07-24 14:51:30 -070087 var args []string
Gurpreet Singh75d65f32022-01-24 17:44:05 +000088
89 if params.IsLibrary {
Colin Cross1b6a3cf2018-07-24 14:51:30 -070090 args = append(args, "--library")
Gurpreet Singh75d65f32022-01-24 17:44:05 +000091 } else if params.SdkContext != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +000092 minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersion(ctx)
Colin Crosse4246ab2019-02-05 21:55:21 -080093 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +000094 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Colin Crosse4246ab2019-02-05 21:55:21 -080095 }
Jiyong Park54105c42021-03-31 18:17:53 +090096 if minSdkVersion.FinalOrFutureInt() >= 23 {
Gurpreet Singh75d65f32022-01-24 17:44:05 +000097 args = append(args, fmt.Sprintf("--extract-native-libs=%v", !params.UseEmbeddedNativeLibs))
98 } else if params.UseEmbeddedNativeLibs {
Pedro Loureiroea2f5ef2022-04-22 13:53:16 +000099 ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%s doesn't support it",
100 minSdkVersion.String())
Colin Crosse4246ab2019-02-05 21:55:21 -0800101 }
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700102 }
Colin Cross31656952018-05-24 16:11:20 -0700103
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000104 if params.UsesNonSdkApis {
David Brazdild25060a2019-02-18 18:24:16 +0000105 args = append(args, "--uses-non-sdk-api")
106 }
107
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000108 if params.UseEmbeddedDex {
Sasha Smundakd2e53612019-05-14 17:03:24 -0700109 args = append(args, "--use-embedded-dex")
Colin Cross46abdad2019-02-07 13:07:08 -0800110 }
111
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000112 if params.ClassLoaderContexts != nil {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100113 // Libraries propagated via `uses_libs`/`optional_uses_libs` are also added (they may be
114 // propagated from dependencies).
115 requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.UsesLibs()
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000116
117 for _, usesLib := range requiredUsesLibs {
118 args = append(args, "--uses-library", usesLib)
119 }
120 for _, usesLib := range optionalUsesLibs {
121 args = append(args, "--optional-uses-library", usesLib)
122 }
Colin Cross5446e882019-05-22 10:46:27 -0700123 }
124
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000125 if params.HasNoCode {
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700126 args = append(args, "--has-no-code")
127 }
128
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000129 if params.TestOnly {
130 args = append(args, "--test-only")
131 }
132
133 if params.LoggingParent != "" {
134 args = append(args, "--logging-parent", params.LoggingParent)
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800135 }
Colin Cross10932872019-04-18 14:27:12 -0700136 var deps android.Paths
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000137 var argsMapper = make(map[string]string)
Spandan Dasc8cb0c32021-12-08 17:00:38 +0000138
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000139 if params.SdkContext != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000140 targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params.SdkContext)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000141 args = append(args, "--targetSdkVersion ", targetSdkVersion)
142
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000143 if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
144 targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
145 deps = append(deps, ApiFingerprintPath(ctx))
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000146 }
147
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000148 minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000149 if err != nil {
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000150 ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000151 }
152
William Loh5a082f92022-05-17 20:21:50 +0000153 replaceMaxSdkVersionPlaceholder, err := params.SdkContext.ReplaceMaxSdkVersionPlaceholder(ctx).EffectiveVersion(ctx)
154 if err != nil {
155 ctx.ModuleErrorf("invalid ReplaceMaxSdkVersionPlaceholder: %s", err)
156 }
157
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000158 if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
159 minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
160 deps = append(deps, ApiFingerprintPath(ctx))
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000161 }
162
163 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 args = append(args, "--minSdkVersion ", minSdkVersion)
William Loh5a082f92022-05-17 20:21:50 +0000167 args = append(args, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt()))
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000168 args = append(args, "--raise-min-sdk-version")
Jiyong Park6a927c42020-01-21 02:03:43 +0900169 }
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100170 if params.DefaultManifestVersion != "" {
171 args = append(args, "--override-placeholder-version", params.DefaultManifestVersion)
172 }
Jiyong Park6a927c42020-01-21 02:03:43 +0900173
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000174 fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000175 argsMapper["args"] = strings.Join(args, " ")
Colin Cross10932872019-04-18 14:27:12 -0700176
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000177 ctx.Build(pctx, android.BuildParams{
Colin Cross90c25c62019-04-19 16:22:57 -0700178 Rule: manifestFixerRule,
179 Description: "fix manifest",
Gurpreet Singh7deabfa2022-02-10 13:28:35 +0000180 Input: manifest,
Colin Cross90c25c62019-04-19 16:22:57 -0700181 Implicits: deps,
182 Output: fixedManifest,
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000183 Args: argsMapper,
Colin Cross31656952018-05-24 16:11:20 -0700184 })
Colin Cross31656952018-05-24 16:11:20 -0700185
Colin Cross8eebb132020-01-29 20:07:03 -0800186 return fixedManifest.WithoutRel()
Colin Cross90c25c62019-04-19 16:22:57 -0700187}
Colin Cross31656952018-05-24 16:11:20 -0700188
Colin Crossaa1c6f12019-04-19 16:25:38 -0700189func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibManifests android.Paths,
190 isLibrary bool) android.Path {
191
192 var args string
193 if !isLibrary {
194 // Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests.
195 args = "--remove-tools-declarations"
196 }
197
Colin Cross90c25c62019-04-19 16:22:57 -0700198 mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml")
199 ctx.Build(pctx, android.BuildParams{
200 Rule: manifestMergerRule,
201 Description: "merge manifest",
202 Input: manifest,
203 Implicits: staticLibManifests,
204 Output: mergedManifest,
205 Args: map[string]string{
206 "libs": android.JoinWithPrefix(staticLibManifests.Strings(), "--libs "),
Colin Crossaa1c6f12019-04-19 16:25:38 -0700207 "args": args,
Colin Cross90c25c62019-04-19 16:22:57 -0700208 },
209 })
210
Colin Cross8eebb132020-01-29 20:07:03 -0800211 return mergedManifest.WithoutRel()
Colin Cross31656952018-05-24 16:11:20 -0700212}