From 83bb3167f6a774139a1b9b230fa4c7621aeb1cbe Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 25 Jun 2018 15:48:06 -0700 Subject: [PATCH 1/2] Add support for min_sdk_version Add min_sdk_version properties and use it for aapt2 --min-sdk-version and --target-sdk-version flags. Add an sdkContext interface that any function that needs an sdk version can take in order to get the values for the current module. Bug: 110848854 Test: m checkbuild Change-Id: Ic69f1f935d8b865ec77689350407df08bfac5925 --- androidmk/cmd/androidmk/android.go | 1 + java/aar.go | 41 +++++----- java/androidmk.go | 6 +- java/app.go | 4 +- java/dex.go | 7 +- java/droiddoc.go | 18 +++-- java/java.go | 118 +++++++++++++++++++---------- 7 files changed, 128 insertions(+), 67 deletions(-) diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go index ded9efa47..e3eb82a94 100644 --- a/androidmk/cmd/androidmk/android.go +++ b/androidmk/cmd/androidmk/android.go @@ -85,6 +85,7 @@ func init() { "LOCAL_MULTILIB": "compile_multilib", "LOCAL_ARM_MODE_HACK": "instruction_set", "LOCAL_SDK_VERSION": "sdk_version", + "LOCAL_MIN_SDK_VERSION": "min_sdk_version", "LOCAL_NDK_STL_VARIANT": "stl", "LOCAL_JAR_MANIFEST": "manifest", "LOCAL_JARJAR_RULES": "jarjar_rules", diff --git a/java/aar.go b/java/aar.go index da353e01f..506f39f8a 100644 --- a/java/aar.go +++ b/java/aar.go @@ -74,7 +74,7 @@ func (a *aapt) ExportPackage() android.Path { return a.exportPackage } -func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkVersion string) (flags []string, deps android.Paths, +func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext) (flags []string, deps android.Paths, resDirs, overlayDirs []globbedResourceDir, overlayFiles, rroDirs android.Paths, manifestPath android.Path) { hasVersionCode := false @@ -125,20 +125,17 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkVersion string) (flags [ linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A ")) linkDeps = append(linkDeps, assetFiles...) - transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkVersion) + transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkContext) overlayFiles = append(overlayFiles, transitiveStaticLibs...) linkDeps = append(linkDeps, libDeps...) linkFlags = append(linkFlags, libFlags...) // SDK version flags - switch sdkVersion { - case "", "current", "system_current", "test_current": - sdkVersion = proptools.NinjaEscape([]string{ctx.Config().DefaultAppTargetSdk()})[0] - } + minSdkVersion := sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()) - linkFlags = append(linkFlags, "--min-sdk-version "+sdkVersion) - linkFlags = append(linkFlags, "--target-sdk-version "+sdkVersion) + linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion) + linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion) // Version code if !hasVersionCode { @@ -162,17 +159,17 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkVersion string) (flags [ return linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath } -func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkVersion string) { +func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkContext sdkContext) { if !ctx.Config().UnbundledBuild() { - sdkDep := decodeSdkDep(ctx, sdkVersion) + sdkDep := decodeSdkDep(ctx, sdkContext) if sdkDep.frameworkResModule != "" { ctx.AddDependency(ctx.Module(), frameworkResTag, sdkDep.frameworkResModule) } } } -func (a *aapt) buildActions(ctx android.ModuleContext, sdkVersion string, extraLinkFlags ...string) { - linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath := a.aapt2Flags(ctx, sdkVersion) +func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, extraLinkFlags ...string) { + linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath := a.aapt2Flags(ctx, sdkContext) linkFlags = append(linkFlags, extraLinkFlags...) @@ -206,12 +203,12 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkVersion string, extraL } // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths -func aaptLibs(ctx android.ModuleContext, sdkVersion string) (transitiveStaticLibs, deps android.Paths, +func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, deps android.Paths, flags []string) { var sharedLibs android.Paths - sdkDep := decodeSdkDep(ctx, sdkVersion) + sdkDep := decodeSdkDep(ctx, sdkContext) if sdkDep.useFiles { sharedLibs = append(sharedLibs, sdkDep.jars...) } @@ -277,12 +274,12 @@ var _ AndroidLibraryDependency = (*AndroidLibrary)(nil) func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { a.Module.deps(ctx) if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) { - a.aapt.deps(ctx, String(a.deviceProperties.Sdk_version)) + a.aapt.deps(ctx, sdkContext(a)) } } func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { - a.aapt.buildActions(ctx, String(a.deviceProperties.Sdk_version), "--static-lib") + a.aapt.buildActions(ctx, sdkContext(a), "--static-lib") ctx.CheckbuildFile(a.proguardOptionsFile) ctx.CheckbuildFile(a.exportPackage) @@ -359,6 +356,14 @@ type AARImport struct { exportedStaticPackages android.Paths } +func (a *AARImport) sdkVersion() string { + return String(a.properties.Sdk_version) +} + +func (a *AARImport) minSdkVersion() string { + return a.sdkVersion() +} + var _ AndroidLibraryDependency = (*AARImport)(nil) func (a *AARImport) ExportPackage() android.Path { @@ -383,7 +388,7 @@ func (a *AARImport) Name() string { func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) { if !ctx.Config().UnbundledBuild() { - sdkDep := decodeSdkDep(ctx, String(a.properties.Sdk_version)) + sdkDep := decodeSdkDep(ctx, sdkContext(a)) if sdkDep.useModule && sdkDep.frameworkResModule != "" { ctx.AddDependency(ctx.Module(), frameworkResTag, sdkDep.frameworkResModule) } @@ -450,7 +455,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { linkFlags = append(linkFlags, "--manifest "+a.manifest.String()) linkDeps = append(linkDeps, a.manifest) - transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, String(a.properties.Sdk_version)) + transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkContext(a)) linkDeps = append(linkDeps, libDeps...) linkFlags = append(linkFlags, libFlags...) diff --git a/java/androidmk.go b/java/androidmk.go index d6095ae0f..79cf31754 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -56,7 +56,7 @@ func (library *Library) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING := $(LOCAL_PATH)/"+*library.deviceProperties.Dex_preopt.Profile) } } - fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", String(library.deviceProperties.Sdk_version)) + fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", library.sdkVersion()) fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.headerJarFile.String()) if library.jacocoReportClassesFile != nil { @@ -121,7 +121,7 @@ func (prebuilt *Import) AndroidMk() android.AndroidMkData { func(w io.Writer, outputFile android.Path) { fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := ", !Bool(prebuilt.properties.Installable)) fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", prebuilt.combinedClasspathFile.String()) - fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", String(prebuilt.properties.Sdk_version)) + fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", prebuilt.sdkVersion()) }, }, } @@ -141,7 +141,7 @@ func (prebuilt *AARImport) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_SOONG_EXPORT_PROGUARD_FLAGS :=", prebuilt.proguardFlags.String()) fmt.Fprintln(w, "LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=", prebuilt.extraAaptPackagesFile.String()) fmt.Fprintln(w, "LOCAL_FULL_MANIFEST_FILE :=", prebuilt.manifest.String()) - fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", String(prebuilt.properties.Sdk_version)) + fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", prebuilt.sdkVersion()) }, }, } diff --git a/java/app.go b/java/app.go index 37109b56a..f4de419be 100644 --- a/java/app.go +++ b/java/app.go @@ -81,7 +81,7 @@ type certificate struct { func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { a.Module.deps(ctx) if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) { - a.aapt.deps(ctx, String(a.deviceProperties.Sdk_version)) + a.aapt.deps(ctx, sdkContext(a)) } } @@ -117,7 +117,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { // TODO: LOCAL_PACKAGE_OVERRIDES // $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \ - a.aapt.buildActions(ctx, String(a.deviceProperties.Sdk_version), linkFlags...) + a.aapt.buildActions(ctx, sdkContext(a), linkFlags...) // apps manifests are handled by aapt, don't let Module see them a.properties.Manifest = nil diff --git a/java/dex.go b/java/dex.go index f729badea..06ee272de 100644 --- a/java/dex.go +++ b/java/dex.go @@ -70,7 +70,12 @@ func (j *Module) dxFlags(ctx android.ModuleContext) []string { "--verbose") } - flags = append(flags, "--min-api "+j.minSdkVersionNumber(ctx)) + minSdkVersion, err := sdkVersionToNumberAsString(ctx, j.minSdkVersion()) + if err != nil { + ctx.PropertyErrorf("min_sdk_version", "%s", err) + } + + flags = append(flags, "--min-api "+minSdkVersion) return flags } diff --git a/java/droiddoc.go b/java/droiddoc.go index 1eb935f19..dbceed86e 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -332,9 +332,17 @@ func DroiddocHostFactory() android.Module { return module } +func (j *Javadoc) sdkVersion() string { + return String(j.properties.Sdk_version) +} + +func (j *Javadoc) minSdkVersion() string { + return j.sdkVersion() +} + func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) { if ctx.Device() { - sdkDep := decodeSdkDep(ctx, String(j.properties.Sdk_version)) + sdkDep := decodeSdkDep(ctx, sdkContext(j)) if sdkDep.useDefaultLibs { ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...) if ctx.Config().TargetOpenJDK9() { @@ -432,7 +440,7 @@ func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths, func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { var deps deps - sdkDep := decodeSdkDep(ctx, String(j.properties.Sdk_version)) + sdkDep := decodeSdkDep(ctx, sdkContext(j)) if sdkDep.invalidVersion { ctx.AddMissingDependencies(sdkDep.modules) } else if sdkDep.useFiles { @@ -455,7 +463,7 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { case Dependency: deps.classpath = append(deps.classpath, dep.ImplementationJars()...) case SdkLibraryDependency: - sdkVersion := String(j.properties.Sdk_version) + sdkVersion := j.sdkVersion() linkType := javaSdk if strings.HasPrefix(sdkVersion, "system_") || strings.HasPrefix(sdkVersion, "test_") { linkType = javaSystem @@ -539,7 +547,7 @@ func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) { var bootClasspathArgs, classpathArgs string - javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), String(j.properties.Sdk_version)) + javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j)) if len(deps.bootClasspath) > 0 { var systemModules classpath if deps.systemModules != nil { @@ -639,7 +647,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) { implicits = append(implicits, deps.classpath...) var bootClasspathArgs string - javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), String(d.Javadoc.properties.Sdk_version)) + javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d)) // Doclava has problem with "-source 1.9", so override javaVersion when Doclava // is running with EXPERIMENTAL_USE_OPENJDK9=true. And eventually Doclava will be // replaced by Metalava. diff --git a/java/java.go b/java/java.go index 00d52634d..5d75b1fc0 100644 --- a/java/java.go +++ b/java/java.go @@ -168,9 +168,14 @@ type CompilerDeviceProperties struct { // list of module-specific flags that will be used for dex compiles Dxflags []string `android:"arch_variant"` - // if not blank, set to the version of the sdk to compile against + // if not blank, set to the version of the sdk to compile against. Defaults to compiling against the current + // sdk if platform_apis is not set. Sdk_version *string + // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. + // Defaults to sdk_version if not set. + Min_sdk_version *string + // if true, compile against the platform APIs instead of an SDK. Platform_apis *bool @@ -355,20 +360,6 @@ type sdkDep struct { aidl android.Path } -func sdkStringToNumber(ctx android.BaseContext, v string) int { - switch v { - case "", "current", "system_current", "test_current", "core_current": - return android.FutureApiLevel - default: - if i, err := strconv.Atoi(android.GetNumericSdkVersion(v)); err != nil { - ctx.PropertyErrorf("sdk_version", "invalid sdk version") - return -1 - } else { - return i - } - } -} - func (j *Module) shouldInstrument(ctx android.BaseContext) bool { return j.properties.Instrument && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") } @@ -379,10 +370,62 @@ func (j *Module) shouldInstrumentStatic(ctx android.BaseContext) bool { ctx.Config().UnbundledBuild()) } -func decodeSdkDep(ctx android.BaseContext, v string) sdkDep { - i := sdkStringToNumber(ctx, v) - if i == -1 { - // Invalid sdk version, error handled by sdkStringToNumber. +func (j *Module) sdkVersion() string { + return String(j.deviceProperties.Sdk_version) +} + +func (j *Module) minSdkVersion() string { + if j.deviceProperties.Min_sdk_version != nil { + return *j.deviceProperties.Min_sdk_version + } + return j.sdkVersion() +} + +type sdkContext interface { + // sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set. + sdkVersion() string + // minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set. + minSdkVersion() string +} + +func sdkVersionOrDefault(ctx android.BaseContext, v string) string { + switch v { + case "", "current", "system_current", "test_current", "core_current": + return ctx.Config().DefaultAppTargetSdk() + default: + return v + } +} + +// Returns a sdk version as a number. For modules targeting an unreleased SDK (meaning it does not yet have a number) +// it returns android.FutureApiLevel (10000). +func sdkVersionToNumber(ctx android.BaseContext, v string) (int, error) { + switch v { + case "", "current", "test_current", "system_current", "core_current": + return ctx.Config().DefaultAppTargetSdkInt(), nil + default: + n := android.GetNumericSdkVersion(v) + if i, err := strconv.Atoi(n); err != nil { + return -1, fmt.Errorf("invalid sdk version %q", n) + } else { + return i, nil + } + } +} + +func sdkVersionToNumberAsString(ctx android.BaseContext, v string) (string, error) { + n, err := sdkVersionToNumber(ctx, v) + if err != nil { + return "", err + } + return strconv.Itoa(n), nil +} + +func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep { + v := sdkContext.sdkVersion() + i, err := sdkVersionToNumber(ctx, v) + if err != nil { + ctx.PropertyErrorf("sdk_version", "%s", err) return sdkDep{} } @@ -485,7 +528,7 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep { func (j *Module) deps(ctx android.BottomUpMutatorContext) { if ctx.Device() { if !Bool(j.properties.No_standard_libs) { - sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version)) + sdkDep := decodeSdkDep(ctx, sdkContext(j)) if sdkDep.useDefaultLibs { ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...) if ctx.Config().TargetOpenJDK9() { @@ -638,7 +681,7 @@ const ( ) func getLinkType(m *Module, name string) linkType { - ver := String(m.deviceProperties.Sdk_version) + ver := m.sdkVersion() noStdLibs := Bool(m.properties.No_standard_libs) switch { case name == "core.current.stubs" || ver == "core_current" || noStdLibs || name == "stub-annotations": @@ -697,7 +740,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { var deps deps if ctx.Device() { - sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version)) + sdkDep := decodeSdkDep(ctx, sdkContext(j)) if sdkDep.invalidVersion { ctx.AddMissingDependencies(sdkDep.modules) } else if sdkDep.useFiles { @@ -808,16 +851,19 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { return deps } -func getJavaVersion(ctx android.ModuleContext, javaVersion, sdkVersion string) string { +func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string { var ret string - sdk := sdkStringToNumber(ctx, sdkVersion) + sdk, err := sdkVersionToNumber(ctx, sdkContext.sdkVersion()) + if err != nil { + ctx.PropertyErrorf("sdk_version", "%s", err) + } if javaVersion != "" { ret = javaVersion } else if ctx.Device() && sdk <= 23 { ret = "1.7" } else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() { ret = "1.8" - } else if ctx.Device() && sdkVersion != "" && sdk == android.FutureApiLevel { + } else if ctx.Device() && sdkContext.sdkVersion() != "" && sdk == android.FutureApiLevel { // TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current" ret = "1.8" } else { @@ -864,8 +910,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB } // javaVersion flag. - flags.javaVersion = getJavaVersion(ctx, - String(j.properties.Java_version), String(j.deviceProperties.Sdk_version)) + flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j)) // classpath flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...) @@ -1205,17 +1250,6 @@ func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, return instrumentedJar } -// Returns a sdk version as a string that is guaranteed to be a parseable as a number. For -// modules targeting an unreleased SDK (meaning it does not yet have a number) it returns "10000". -func (j *Module) minSdkVersionNumber(ctx android.ModuleContext) string { - switch String(j.deviceProperties.Sdk_version) { - case "", "current", "test_current", "system_current", "core_current": - return strconv.Itoa(ctx.Config().DefaultAppTargetSdkInt()) - default: - return android.GetNumericSdkVersion(String(j.deviceProperties.Sdk_version)) - } -} - func (j *Module) installable() bool { return BoolDefault(j.properties.Installable, true) } @@ -1459,6 +1493,14 @@ type Import struct { exportedSdkLibs []string } +func (j *Import) sdkVersion() string { + return String(j.properties.Sdk_version) +} + +func (j *Import) minSdkVersion() string { + return j.sdkVersion() +} + func (j *Import) Prebuilt() *android.Prebuilt { return &j.prebuilt } From cf53e608a7f2cc9cd422f13fb096b9ff1e2c74de Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Jun 2018 15:27:20 -0700 Subject: [PATCH 2/2] pom2bp: extract minSdkVersion from manifest into Android.bp When manifest merging in Soong is turned on the modules created by pom2bp will need to have min_sdk_version specified in order to prevent manifest_fixer from setting it to the current SDK level. Read the minSdkVersion attribute out of the AndroidManifest.xml file inside each .aar file. Bug: 110848854 Test: cd prebuilts/sdk/current/support && pom2bp -regen Android.bp Change-Id: Ieaf37ba6eccaf32dc5d3411566335830b1a327ff --- cmd/pom2bp/pom2bp.go | 70 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go index 078a07dd7..7b06035d6 100644 --- a/cmd/pom2bp/pom2bp.go +++ b/cmd/pom2bp/pom2bp.go @@ -15,6 +15,7 @@ package main import ( + "archive/zip" "bufio" "bytes" "encoding/xml" @@ -138,9 +139,10 @@ func (d Dependency) BpName() string { type Pom struct { XMLName xml.Name `xml:"http://maven.apache.org/POM/4.0.0 project"` - PomFile string `xml:"-"` - ArtifactFile string `xml:"-"` - BpTarget string `xml:"-"` + PomFile string `xml:"-"` + ArtifactFile string `xml:"-"` + BpTarget string `xml:"-"` + MinSdkVersion string `xml:"-"` GroupId string `xml:"groupId"` ArtifactId string `xml:"artifactId"` @@ -215,11 +217,61 @@ func (p *Pom) FixDeps(modules map[string]*Pom) { } } +// ExtractMinSdkVersion extracts the minSdkVersion from the AndroidManifest.xml file inside an aar file, or sets it +// to "current" if it is not present. +func (p *Pom) ExtractMinSdkVersion() error { + aar, err := zip.OpenReader(p.ArtifactFile) + if err != nil { + return err + } + defer aar.Close() + + var manifest *zip.File + for _, f := range aar.File { + if f.Name == "AndroidManifest.xml" { + manifest = f + break + } + } + + if manifest == nil { + return fmt.Errorf("failed to find AndroidManifest.xml in %s", p.ArtifactFile) + } + + r, err := manifest.Open() + if err != nil { + return err + } + defer r.Close() + + decoder := xml.NewDecoder(r) + + manifestData := struct { + XMLName xml.Name `xml:"manifest"` + Uses_sdk struct { + MinSdkVersion string `xml:"http://schemas.android.com/apk/res/android minSdkVersion,attr"` + } `xml:"uses-sdk"` + }{} + + err = decoder.Decode(&manifestData) + if err != nil { + return err + } + + p.MinSdkVersion = manifestData.Uses_sdk.MinSdkVersion + if p.MinSdkVersion == "" { + p.MinSdkVersion = "current" + } + + return nil +} + var bpTemplate = template.Must(template.New("bp").Parse(` {{if .IsAar}}android_library_import{{else}}java_import{{end}} { name: "{{.BpName}}-nodeps", {{if .IsAar}}aars{{else}}jars{{end}}: ["{{.ArtifactFile}}"], sdk_version: "{{.SdkVersion}}",{{if .IsAar}} + min_sdk_version: "{{.MinSdkVersion}}", static_libs: [{{range .BpAarDeps}} "{{.}}",{{end}}{{range .BpExtraDeps}} "{{.}}",{{end}} @@ -229,7 +281,8 @@ var bpTemplate = template.Must(template.New("bp").Parse(` {{if .IsAar}}android_library{{else}}java_library_static{{end}} { name: "{{.BpName}}", sdk_version: "{{.SdkVersion}}",{{if .IsAar}} - manifest: "manifests/{{.BpName}}/AndroidManifest.xml",{{end}} + min_sdk_version: "{{.MinSdkVersion}}",{{end}} + manifest: "manifests/{{.BpName}}/AndroidManifest.xml", static_libs: [ "{{.BpName}}-nodeps",{{range .BpJarDeps}} "{{.}}",{{end}}{{range .BpAarDeps}} @@ -302,7 +355,7 @@ func rerunForRegen(filename string) error { // Append all current command line args except -regen to the ones from the file for i := 1; i < len(os.Args); i++ { - if os.Args[i] == "-regen" { + if os.Args[i] == "-regen" || os.Args[i] == "--regen" { i++ } else { args = append(args, os.Args[i]) @@ -468,6 +521,13 @@ Usage: %s [--rewrite =] [-exclude ] [--extra-deps