android_manifest.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. package java
  15. import (
  16. "fmt"
  17. "strconv"
  18. "strings"
  19. "github.com/google/blueprint"
  20. "android/soong/android"
  21. "android/soong/dexpreopt"
  22. )
  23. var manifestFixerRule = pctx.AndroidStaticRule("manifestFixer",
  24. blueprint.RuleParams{
  25. Command: `${config.ManifestFixerCmd} ` +
  26. `$args $in $out`,
  27. CommandDeps: []string{"${config.ManifestFixerCmd}"},
  28. },
  29. "args")
  30. var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",
  31. blueprint.RuleParams{
  32. Command: `${config.ManifestMergerCmd} $args --main $in $libs --out $out`,
  33. CommandDeps: []string{"${config.ManifestMergerCmd}"},
  34. },
  35. "args", "libs")
  36. // targetSdkVersion for manifest_fixer
  37. // When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK
  38. // 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
  39. func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string {
  40. targetSdkVersionLevel := params.SdkContext.TargetSdkVersion(ctx)
  41. // Check if we want to return 10000
  42. // TODO(b/240294501): Determine the rules for handling test apexes
  43. if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionLevel, params.EnforceDefaultTargetSdkVersion) {
  44. return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
  45. }
  46. targetSdkVersion, err := targetSdkVersionLevel.EffectiveVersionString(ctx)
  47. if err != nil {
  48. ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
  49. }
  50. return targetSdkVersion
  51. }
  52. // Return true for modules targeting "current" if either
  53. // 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
  54. // 2. The module is run as part of MTS, and should be testable on stable branches
  55. // Do not return 10000 if we are enforcing default targetSdkVersion and sdk has been finalised
  56. func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionLevel android.ApiLevel, enforceDefaultTargetSdkVersion bool) bool {
  57. // If this is a REL branch, do not return 10000
  58. if ctx.Config().PlatformSdkFinal() {
  59. return false
  60. }
  61. // If this a module targeting an unreleased SDK (MTS or unbundled builds), return 10000
  62. return targetSdkVersionLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module()))
  63. }
  64. // Helper function that casts android.Module to java.androidTestApp
  65. // If this type conversion is possible, it queries whether the test app is included in an MTS suite
  66. func includedInMts(module android.Module) bool {
  67. if test, ok := module.(androidTestApp); ok {
  68. return test.includedInTestSuite("mts")
  69. }
  70. return false
  71. }
  72. type ManifestFixerParams struct {
  73. SdkContext android.SdkContext
  74. ClassLoaderContexts dexpreopt.ClassLoaderContextMap
  75. IsLibrary bool
  76. DefaultManifestVersion string
  77. UseEmbeddedNativeLibs bool
  78. UsesNonSdkApis bool
  79. UseEmbeddedDex bool
  80. HasNoCode bool
  81. TestOnly bool
  82. LoggingParent string
  83. EnforceDefaultTargetSdkVersion bool
  84. }
  85. // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
  86. func ManifestFixer(ctx android.ModuleContext, manifest android.Path,
  87. params ManifestFixerParams) android.Path {
  88. var args []string
  89. if params.IsLibrary {
  90. args = append(args, "--library")
  91. } else if params.SdkContext != nil {
  92. minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersion(ctx)
  93. if err != nil {
  94. ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
  95. }
  96. if minSdkVersion.FinalOrFutureInt() >= 23 {
  97. args = append(args, fmt.Sprintf("--extract-native-libs=%v", !params.UseEmbeddedNativeLibs))
  98. } else if params.UseEmbeddedNativeLibs {
  99. ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%s doesn't support it",
  100. minSdkVersion.String())
  101. }
  102. }
  103. if params.UsesNonSdkApis {
  104. args = append(args, "--uses-non-sdk-api")
  105. }
  106. if params.UseEmbeddedDex {
  107. args = append(args, "--use-embedded-dex")
  108. }
  109. if params.ClassLoaderContexts != nil {
  110. // Libraries propagated via `uses_libs`/`optional_uses_libs` are also added (they may be
  111. // propagated from dependencies).
  112. requiredUsesLibs, optionalUsesLibs := params.ClassLoaderContexts.UsesLibs()
  113. for _, usesLib := range requiredUsesLibs {
  114. args = append(args, "--uses-library", usesLib)
  115. }
  116. for _, usesLib := range optionalUsesLibs {
  117. args = append(args, "--optional-uses-library", usesLib)
  118. }
  119. }
  120. if params.HasNoCode {
  121. args = append(args, "--has-no-code")
  122. }
  123. if params.TestOnly {
  124. args = append(args, "--test-only")
  125. }
  126. if params.LoggingParent != "" {
  127. args = append(args, "--logging-parent", params.LoggingParent)
  128. }
  129. var deps android.Paths
  130. var argsMapper = make(map[string]string)
  131. if params.SdkContext != nil {
  132. targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
  133. if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
  134. targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
  135. deps = append(deps, ApiFingerprintPath(ctx))
  136. }
  137. args = append(args, "--targetSdkVersion ", targetSdkVersion)
  138. minSdkVersion, err := params.SdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
  139. if err != nil {
  140. ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
  141. }
  142. replaceMaxSdkVersionPlaceholder, err := params.SdkContext.ReplaceMaxSdkVersionPlaceholder(ctx).EffectiveVersion(ctx)
  143. if err != nil {
  144. ctx.ModuleErrorf("invalid ReplaceMaxSdkVersionPlaceholder: %s", err)
  145. }
  146. if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
  147. minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
  148. deps = append(deps, ApiFingerprintPath(ctx))
  149. }
  150. if err != nil {
  151. ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
  152. }
  153. args = append(args, "--minSdkVersion ", minSdkVersion)
  154. args = append(args, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt()))
  155. args = append(args, "--raise-min-sdk-version")
  156. }
  157. if params.DefaultManifestVersion != "" {
  158. args = append(args, "--override-placeholder-version", params.DefaultManifestVersion)
  159. }
  160. fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
  161. argsMapper["args"] = strings.Join(args, " ")
  162. ctx.Build(pctx, android.BuildParams{
  163. Rule: manifestFixerRule,
  164. Description: "fix manifest",
  165. Input: manifest,
  166. Implicits: deps,
  167. Output: fixedManifest,
  168. Args: argsMapper,
  169. })
  170. return fixedManifest.WithoutRel()
  171. }
  172. func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibManifests android.Paths,
  173. isLibrary bool) android.Path {
  174. var args string
  175. if !isLibrary {
  176. // Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests.
  177. args = "--remove-tools-declarations"
  178. }
  179. mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml")
  180. ctx.Build(pctx, android.BuildParams{
  181. Rule: manifestMergerRule,
  182. Description: "merge manifest",
  183. Input: manifest,
  184. Implicits: staticLibManifests,
  185. Output: mergedManifest,
  186. Args: map[string]string{
  187. "libs": android.JoinWithPrefix(staticLibManifests.Strings(), "--libs "),
  188. "args": args,
  189. },
  190. })
  191. return mergedManifest.WithoutRel()
  192. }