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