1// 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 ( 18 "fmt" 19 "strings" 20 21 "github.com/google/blueprint" 22 23 "android/soong/android" 24 "android/soong/dexpreopt" 25) 26 27var manifestFixerRule = pctx.AndroidStaticRule("manifestFixer", 28 blueprint.RuleParams{ 29 Command: `${config.ManifestFixerCmd} ` + 30 `--minSdkVersion ${minSdkVersion} ` + 31 `--targetSdkVersion ${targetSdkVersion} ` + 32 `--raise-min-sdk-version ` + 33 `$args $in $out`, 34 CommandDeps: []string{"${config.ManifestFixerCmd}"}, 35 }, 36 "minSdkVersion", "targetSdkVersion", "args") 37 38var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger", 39 blueprint.RuleParams{ 40 Command: `${config.ManifestMergerCmd} $args --main $in $libs --out $out`, 41 CommandDeps: []string{"${config.ManifestMergerCmd}"}, 42 }, 43 "args", "libs") 44 45// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml 46func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext android.SdkContext, 47 classLoaderContexts dexpreopt.ClassLoaderContextMap, isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, 48 useEmbeddedDex, hasNoCode bool, loggingParent string) android.Path { 49 50 var args []string 51 if isLibrary { 52 args = append(args, "--library") 53 } else { 54 minSdkVersion, err := sdkContext.MinSdkVersion(ctx).EffectiveVersion(ctx) 55 if err != nil { 56 ctx.ModuleErrorf("invalid minSdkVersion: %s", err) 57 } 58 if minSdkVersion.FinalOrFutureInt() >= 23 { 59 args = append(args, fmt.Sprintf("--extract-native-libs=%v", !useEmbeddedNativeLibs)) 60 } else if useEmbeddedNativeLibs { 61 ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%d doesn't support it", 62 minSdkVersion) 63 } 64 } 65 66 if usesNonSdkApis { 67 args = append(args, "--uses-non-sdk-api") 68 } 69 70 if useEmbeddedDex { 71 args = append(args, "--use-embedded-dex") 72 } 73 74 for _, usesLib := range classLoaderContexts.UsesLibs() { 75 if inList(usesLib, dexpreopt.OptionalCompatUsesLibs) { 76 args = append(args, "--optional-uses-library", usesLib) 77 } else { 78 args = append(args, "--uses-library", usesLib) 79 } 80 } 81 82 if hasNoCode { 83 args = append(args, "--has-no-code") 84 } 85 86 if loggingParent != "" { 87 args = append(args, "--logging-parent", loggingParent) 88 } 89 var deps android.Paths 90 targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx) 91 if err != nil { 92 ctx.ModuleErrorf("invalid targetSdkVersion: %s", err) 93 } 94 if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" { 95 targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String()) 96 deps = append(deps, ApiFingerprintPath(ctx)) 97 } 98 99 minSdkVersion, err := sdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx) 100 if err != nil { 101 ctx.ModuleErrorf("invalid minSdkVersion: %s", err) 102 } 103 if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" { 104 minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String()) 105 deps = append(deps, ApiFingerprintPath(ctx)) 106 } 107 108 fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml") 109 if err != nil { 110 ctx.ModuleErrorf("invalid minSdkVersion: %s", err) 111 } 112 ctx.Build(pctx, android.BuildParams{ 113 Rule: manifestFixerRule, 114 Description: "fix manifest", 115 Input: manifest, 116 Implicits: deps, 117 Output: fixedManifest, 118 Args: map[string]string{ 119 "minSdkVersion": minSdkVersion, 120 "targetSdkVersion": targetSdkVersion, 121 "args": strings.Join(args, " "), 122 }, 123 }) 124 125 return fixedManifest.WithoutRel() 126} 127 128func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibManifests android.Paths, 129 isLibrary bool) android.Path { 130 131 var args string 132 if !isLibrary { 133 // Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests. 134 args = "--remove-tools-declarations" 135 } 136 137 mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml") 138 ctx.Build(pctx, android.BuildParams{ 139 Rule: manifestMergerRule, 140 Description: "merge manifest", 141 Input: manifest, 142 Implicits: staticLibManifests, 143 Output: mergedManifest, 144 Args: map[string]string{ 145 "libs": android.JoinWithPrefix(staticLibManifests.Strings(), "--libs "), 146 "args": args, 147 }, 148 }) 149 150 return mergedManifest.WithoutRel() 151} 152