xref: /aosp_15_r20/build/soong/java/android_manifest.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2018 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage java
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"strconv"
20*333d2b36SAndroid Build Coastguard Worker	"strings"
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
25*333d2b36SAndroid Build Coastguard Worker	"android/soong/dexpreopt"
26*333d2b36SAndroid Build Coastguard Worker)
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Workervar manifestFixerRule = pctx.AndroidStaticRule("manifestFixer",
29*333d2b36SAndroid Build Coastguard Worker	blueprint.RuleParams{
30*333d2b36SAndroid Build Coastguard Worker		Command: `${config.ManifestFixerCmd} ` +
31*333d2b36SAndroid Build Coastguard Worker			`$args $in $out`,
32*333d2b36SAndroid Build Coastguard Worker		CommandDeps: []string{"${config.ManifestFixerCmd}"},
33*333d2b36SAndroid Build Coastguard Worker	},
34*333d2b36SAndroid Build Coastguard Worker	"args")
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Workervar manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",
37*333d2b36SAndroid Build Coastguard Worker	blueprint.RuleParams{
38*333d2b36SAndroid Build Coastguard Worker		Command:     `${config.ManifestMergerCmd} $args --main $in $libs --out $out`,
39*333d2b36SAndroid Build Coastguard Worker		CommandDeps: []string{"${config.ManifestMergerCmd}"},
40*333d2b36SAndroid Build Coastguard Worker	},
41*333d2b36SAndroid Build Coastguard Worker	"args", "libs")
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Worker// targetSdkVersion for manifest_fixer
44*333d2b36SAndroid Build Coastguard Worker// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK
45*333d2b36SAndroid Build Coastguard Worker// 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
46*333d2b36SAndroid Build Coastguard Workerfunc targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string {
47*333d2b36SAndroid Build Coastguard Worker	targetSdkVersionLevel := params.SdkContext.TargetSdkVersion(ctx)
48*333d2b36SAndroid Build Coastguard Worker
49*333d2b36SAndroid Build Coastguard Worker	// Check if we want to return 10000
50*333d2b36SAndroid Build Coastguard Worker	// TODO(b/240294501): Determine the rules for handling test apexes
51*333d2b36SAndroid Build Coastguard Worker	if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionLevel, params.EnforceDefaultTargetSdkVersion) {
52*333d2b36SAndroid Build Coastguard Worker		return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
53*333d2b36SAndroid Build Coastguard Worker	}
54*333d2b36SAndroid Build Coastguard Worker	targetSdkVersion, err := targetSdkVersionLevel.EffectiveVersionString(ctx)
55*333d2b36SAndroid Build Coastguard Worker	if err != nil {
56*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
57*333d2b36SAndroid Build Coastguard Worker	}
58*333d2b36SAndroid Build Coastguard Worker	return targetSdkVersion
59*333d2b36SAndroid Build Coastguard Worker}
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Worker// Return true for modules targeting "current" if either
62*333d2b36SAndroid Build Coastguard Worker// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
63*333d2b36SAndroid Build Coastguard Worker// 2. The module is run as part of MTS, and should be testable on stable branches
64*333d2b36SAndroid Build Coastguard Worker// Do not return 10000 if we are enforcing default targetSdkVersion and sdk has been finalised
65*333d2b36SAndroid Build Coastguard Workerfunc shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionLevel android.ApiLevel, enforceDefaultTargetSdkVersion bool) bool {
66*333d2b36SAndroid Build Coastguard Worker	// If this is a REL branch, do not return 10000
67*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().PlatformSdkFinal() {
68*333d2b36SAndroid Build Coastguard Worker		return false
69*333d2b36SAndroid Build Coastguard Worker	}
70*333d2b36SAndroid Build Coastguard Worker	// If this a module targeting an unreleased SDK (MTS or unbundled builds), return 10000
71*333d2b36SAndroid Build Coastguard Worker	return targetSdkVersionLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module()))
72*333d2b36SAndroid Build Coastguard Worker}
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker// Helper function that returns true if android_test, android_test_helper_app, java_test are in an MTS suite.
75*333d2b36SAndroid Build Coastguard Workerfunc includedInMts(module android.Module) bool {
76*333d2b36SAndroid Build Coastguard Worker	if test, ok := module.(androidTestApp); ok {
77*333d2b36SAndroid Build Coastguard Worker		return test.includedInTestSuite("mts")
78*333d2b36SAndroid Build Coastguard Worker	}
79*333d2b36SAndroid Build Coastguard Worker	// java_test
80*333d2b36SAndroid Build Coastguard Worker	if test, ok := module.(*Test); ok {
81*333d2b36SAndroid Build Coastguard Worker		return android.PrefixInList(test.testProperties.Test_suites, "mts")
82*333d2b36SAndroid Build Coastguard Worker	}
83*333d2b36SAndroid Build Coastguard Worker	return false
84*333d2b36SAndroid Build Coastguard Worker}
85*333d2b36SAndroid Build Coastguard Worker
86*333d2b36SAndroid Build Coastguard Workertype ManifestFixerParams struct {
87*333d2b36SAndroid Build Coastguard Worker	SdkContext                     android.SdkContext
88*333d2b36SAndroid Build Coastguard Worker	ClassLoaderContexts            dexpreopt.ClassLoaderContextMap
89*333d2b36SAndroid Build Coastguard Worker	IsLibrary                      bool
90*333d2b36SAndroid Build Coastguard Worker	DefaultManifestVersion         string
91*333d2b36SAndroid Build Coastguard Worker	UseEmbeddedNativeLibs          bool
92*333d2b36SAndroid Build Coastguard Worker	UsesNonSdkApis                 bool
93*333d2b36SAndroid Build Coastguard Worker	UseEmbeddedDex                 bool
94*333d2b36SAndroid Build Coastguard Worker	HasNoCode                      bool
95*333d2b36SAndroid Build Coastguard Worker	TestOnly                       bool
96*333d2b36SAndroid Build Coastguard Worker	LoggingParent                  string
97*333d2b36SAndroid Build Coastguard Worker	EnforceDefaultTargetSdkVersion bool
98*333d2b36SAndroid Build Coastguard Worker}
99*333d2b36SAndroid Build Coastguard Worker
100*333d2b36SAndroid Build Coastguard Worker// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
101*333d2b36SAndroid Build Coastguard Workerfunc ManifestFixer(ctx android.ModuleContext, manifest android.Path,
102*333d2b36SAndroid Build Coastguard Worker	params ManifestFixerParams) android.Path {
103*333d2b36SAndroid Build Coastguard Worker	var args []string
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Worker	if params.IsLibrary {
106*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--library")
107*333d2b36SAndroid Build Coastguard Worker	} else if params.SdkContext != nil {
108*333d2b36SAndroid Build Coastguard Worker		minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersion(ctx)
109*333d2b36SAndroid Build Coastguard Worker		if err != nil {
110*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
111*333d2b36SAndroid Build Coastguard Worker		}
112*333d2b36SAndroid Build Coastguard Worker		if minSdkVersion.FinalOrFutureInt() >= 23 {
113*333d2b36SAndroid Build Coastguard Worker			args = append(args, fmt.Sprintf("--extract-native-libs=%v", !params.UseEmbeddedNativeLibs))
114*333d2b36SAndroid Build Coastguard Worker		} else if params.UseEmbeddedNativeLibs {
115*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%s doesn't support it",
116*333d2b36SAndroid Build Coastguard Worker				minSdkVersion.String())
117*333d2b36SAndroid Build Coastguard Worker		}
118*333d2b36SAndroid Build Coastguard Worker	}
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Worker	if params.UsesNonSdkApis {
121*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--uses-non-sdk-api")
122*333d2b36SAndroid Build Coastguard Worker	}
123*333d2b36SAndroid Build Coastguard Worker
124*333d2b36SAndroid Build Coastguard Worker	if params.UseEmbeddedDex {
125*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--use-embedded-dex")
126*333d2b36SAndroid Build Coastguard Worker	}
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Worker	if params.ClassLoaderContexts != nil {
129*333d2b36SAndroid Build Coastguard Worker		// Libraries propagated via `uses_libs`/`optional_uses_libs` are also added (they may be
130*333d2b36SAndroid Build Coastguard Worker		// propagated from dependencies).
131*333d2b36SAndroid Build Coastguard Worker		requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.UsesLibs()
132*333d2b36SAndroid Build Coastguard Worker
133*333d2b36SAndroid Build Coastguard Worker		for _, usesLib := range requiredUsesLibs {
134*333d2b36SAndroid Build Coastguard Worker			args = append(args, "--uses-library", usesLib)
135*333d2b36SAndroid Build Coastguard Worker		}
136*333d2b36SAndroid Build Coastguard Worker		for _, usesLib := range optionalUsesLibs {
137*333d2b36SAndroid Build Coastguard Worker			args = append(args, "--optional-uses-library", usesLib)
138*333d2b36SAndroid Build Coastguard Worker		}
139*333d2b36SAndroid Build Coastguard Worker	}
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Worker	if params.HasNoCode {
142*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--has-no-code")
143*333d2b36SAndroid Build Coastguard Worker	}
144*333d2b36SAndroid Build Coastguard Worker
145*333d2b36SAndroid Build Coastguard Worker	if params.TestOnly {
146*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--test-only")
147*333d2b36SAndroid Build Coastguard Worker	}
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Worker	if params.LoggingParent != "" {
150*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--logging-parent", params.LoggingParent)
151*333d2b36SAndroid Build Coastguard Worker	}
152*333d2b36SAndroid Build Coastguard Worker	var deps android.Paths
153*333d2b36SAndroid Build Coastguard Worker	var argsMapper = make(map[string]string)
154*333d2b36SAndroid Build Coastguard Worker
155*333d2b36SAndroid Build Coastguard Worker	if params.SdkContext != nil {
156*333d2b36SAndroid Build Coastguard Worker		targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
157*333d2b36SAndroid Build Coastguard Worker
158*333d2b36SAndroid Build Coastguard Worker		if useApiFingerprint, fingerprintTargetSdkVersion, fingerprintDeps :=
159*333d2b36SAndroid Build Coastguard Worker			UseApiFingerprint(ctx); useApiFingerprint && ctx.ModuleName() != "framework-res" {
160*333d2b36SAndroid Build Coastguard Worker			targetSdkVersion = fingerprintTargetSdkVersion
161*333d2b36SAndroid Build Coastguard Worker			deps = append(deps, fingerprintDeps)
162*333d2b36SAndroid Build Coastguard Worker		}
163*333d2b36SAndroid Build Coastguard Worker
164*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--targetSdkVersion ", targetSdkVersion)
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard Worker		minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
167*333d2b36SAndroid Build Coastguard Worker		if err != nil {
168*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
169*333d2b36SAndroid Build Coastguard Worker		}
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard Worker		replaceMaxSdkVersionPlaceholder, err := params.SdkContext.ReplaceMaxSdkVersionPlaceholder(ctx).EffectiveVersion(ctx)
172*333d2b36SAndroid Build Coastguard Worker		if err != nil {
173*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("invalid ReplaceMaxSdkVersionPlaceholder: %s", err)
174*333d2b36SAndroid Build Coastguard Worker		}
175*333d2b36SAndroid Build Coastguard Worker
176*333d2b36SAndroid Build Coastguard Worker		if useApiFingerprint, fingerprintMinSdkVersion, fingerprintDeps :=
177*333d2b36SAndroid Build Coastguard Worker			UseApiFingerprint(ctx); useApiFingerprint && ctx.ModuleName() != "framework-res" {
178*333d2b36SAndroid Build Coastguard Worker			minSdkVersion = fingerprintMinSdkVersion
179*333d2b36SAndroid Build Coastguard Worker			deps = append(deps, fingerprintDeps)
180*333d2b36SAndroid Build Coastguard Worker		}
181*333d2b36SAndroid Build Coastguard Worker
182*333d2b36SAndroid Build Coastguard Worker		if err != nil {
183*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
184*333d2b36SAndroid Build Coastguard Worker		}
185*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--minSdkVersion ", minSdkVersion)
186*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt()))
187*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--raise-min-sdk-version")
188*333d2b36SAndroid Build Coastguard Worker	}
189*333d2b36SAndroid Build Coastguard Worker	if params.DefaultManifestVersion != "" {
190*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--override-placeholder-version", params.DefaultManifestVersion)
191*333d2b36SAndroid Build Coastguard Worker	}
192*333d2b36SAndroid Build Coastguard Worker
193*333d2b36SAndroid Build Coastguard Worker	fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
194*333d2b36SAndroid Build Coastguard Worker	argsMapper["args"] = strings.Join(args, " ")
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
197*333d2b36SAndroid Build Coastguard Worker		Rule:        manifestFixerRule,
198*333d2b36SAndroid Build Coastguard Worker		Description: "fix manifest",
199*333d2b36SAndroid Build Coastguard Worker		Input:       manifest,
200*333d2b36SAndroid Build Coastguard Worker		Implicits:   deps,
201*333d2b36SAndroid Build Coastguard Worker		Output:      fixedManifest,
202*333d2b36SAndroid Build Coastguard Worker		Args:        argsMapper,
203*333d2b36SAndroid Build Coastguard Worker	})
204*333d2b36SAndroid Build Coastguard Worker
205*333d2b36SAndroid Build Coastguard Worker	return fixedManifest.WithoutRel()
206*333d2b36SAndroid Build Coastguard Worker}
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard Workertype ManifestMergerParams struct {
209*333d2b36SAndroid Build Coastguard Worker	staticLibManifests android.Paths
210*333d2b36SAndroid Build Coastguard Worker	isLibrary          bool
211*333d2b36SAndroid Build Coastguard Worker	packageName        string
212*333d2b36SAndroid Build Coastguard Worker}
213*333d2b36SAndroid Build Coastguard Worker
214*333d2b36SAndroid Build Coastguard Workerfunc manifestMerger(ctx android.ModuleContext, manifest android.Path,
215*333d2b36SAndroid Build Coastguard Worker	params ManifestMergerParams) android.Path {
216*333d2b36SAndroid Build Coastguard Worker
217*333d2b36SAndroid Build Coastguard Worker	var args []string
218*333d2b36SAndroid Build Coastguard Worker	if !params.isLibrary {
219*333d2b36SAndroid Build Coastguard Worker		// Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests.
220*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--remove-tools-declarations")
221*333d2b36SAndroid Build Coastguard Worker	}
222*333d2b36SAndroid Build Coastguard Worker
223*333d2b36SAndroid Build Coastguard Worker	packageName := params.packageName
224*333d2b36SAndroid Build Coastguard Worker	if packageName != "" {
225*333d2b36SAndroid Build Coastguard Worker		args = append(args, "--property PACKAGE="+packageName)
226*333d2b36SAndroid Build Coastguard Worker	}
227*333d2b36SAndroid Build Coastguard Worker
228*333d2b36SAndroid Build Coastguard Worker	mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml")
229*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
230*333d2b36SAndroid Build Coastguard Worker		Rule:        manifestMergerRule,
231*333d2b36SAndroid Build Coastguard Worker		Description: "merge manifest",
232*333d2b36SAndroid Build Coastguard Worker		Input:       manifest,
233*333d2b36SAndroid Build Coastguard Worker		Implicits:   params.staticLibManifests,
234*333d2b36SAndroid Build Coastguard Worker		Output:      mergedManifest,
235*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
236*333d2b36SAndroid Build Coastguard Worker			"libs": android.JoinWithPrefix(params.staticLibManifests.Strings(), "--libs "),
237*333d2b36SAndroid Build Coastguard Worker			"args": strings.Join(args, " "),
238*333d2b36SAndroid Build Coastguard Worker		},
239*333d2b36SAndroid Build Coastguard Worker	})
240*333d2b36SAndroid Build Coastguard Worker
241*333d2b36SAndroid Build Coastguard Worker	return mergedManifest.WithoutRel()
242*333d2b36SAndroid Build Coastguard Worker}
243