From 0a420e771a2201c99f570cf48bd09a6bd837cce2 Mon Sep 17 00:00:00 2001 From: satayev Date: Mon, 29 Nov 2021 17:25:52 +0000 Subject: [PATCH 1/2] Introduce max_sdk_version device property. Artifacts that go into apexes should only be active on certain SDK versions. There is now a need to upper bound the range to support expressiong statements like "this jar should only run on platforms 30-31". Bug: 190818041 Test: presubmit Change-Id: I6985ebb671841cdd9f0f37f916267ac5ed76e4f4 --- java/base.go | 12 ++++++++++++ java/java.go | 1 + 2 files changed, 13 insertions(+) diff --git a/java/base.go b/java/base.go index d9b126059..2f90db2b8 100644 --- a/java/base.go +++ b/java/base.go @@ -197,6 +197,10 @@ type DeviceProperties struct { // Defaults to sdk_version if not set. See sdk_version for possible values. Min_sdk_version *string + // if not blank, set the maximum version of the sdk that the compiled artifacts will run against. + // Defaults to empty string "". See sdk_version for possible values. + Max_sdk_version *string + // if not blank, set the targetSdkVersion in the AndroidManifest.xml. // Defaults to sdk_version if not set. See sdk_version for possible values. Target_sdk_version *string @@ -460,6 +464,7 @@ type Module struct { sdkVersion android.SdkSpec minSdkVersion android.SdkSpec + maxSdkVersion android.SdkSpec } func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error { @@ -617,6 +622,13 @@ func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return j.SdkVersion(ctx) } +func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { + maxSdkVersion := proptools.StringDefault(j.deviceProperties.Max_sdk_version, "") + // SdkSpecFrom returns SdkSpecPrivate for this, which may be confusing. + // TODO(b/208456999): ideally MaxSdkVersion should be an ApiLevel and not SdkSpec. + return android.SdkSpecFrom(ctx, maxSdkVersion) +} + func (j *Module) MinSdkVersionString() string { return j.minSdkVersion.Raw } diff --git a/java/java.go b/java/java.go index 2f9e03a80..e8a8236f7 100644 --- a/java/java.go +++ b/java/java.go @@ -545,6 +545,7 @@ func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) + j.maxSdkVersion = j.MaxSdkVersion(ctx) apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if !apexInfo.IsForPlatform() { From cca4ab762eab320fb9beaad61a51969e16127833 Mon Sep 17 00:00:00 2001 From: satayev Date: Tue, 30 Nov 2021 12:33:55 +0000 Subject: [PATCH 2/2] Propagate min and max sdk versions to classpaths.proto configs. These attributed define a range for dessert releases where the jars should be active, and included in corresponding CLASSPATH varibles by derive_classpath. Bug: 190818041 Test: presubmit Change-Id: Ieb9aef29657ad0694d48a63019f93faca2678252 --- android/config.go | 10 +++++++ java/classpath_fragment.go | 49 +++++++++++++++++++++++++++++----- java/platform_bootclasspath.go | 1 - 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/android/config.go b/android/config.go index ed63ddf20..ddad1f532 100644 --- a/android/config.go +++ b/android/config.go @@ -765,6 +765,16 @@ func (c *config) PreviewApiLevels() []ApiLevel { return levels } +func (c *config) LatestPreviewApiLevel() ApiLevel { + level := NoneApiLevel + for _, l := range c.PreviewApiLevels() { + if l.GreaterThan(level) { + level = l + } + } + return level +} + func (c *config) AllSupportedApiLevels() []ApiLevel { var levels []ApiLevel levels = append(levels, c.FinalApiLevels()...) diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go index f63d81d6e..92e01a2df 100644 --- a/java/classpath_fragment.go +++ b/java/classpath_fragment.go @@ -84,11 +84,10 @@ func initClasspathFragment(c classpathFragment, classpathType classpathType) { // Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto type classpathJar struct { - path string - classpath classpathType - // TODO(satayev): propagate min/max sdk versions for the jars - minSdkVersion int32 - maxSdkVersion int32 + path string + classpath classpathType + minSdkVersion string + maxSdkVersion string } // gatherPossibleApexModuleNamesAndStems returns a set of module and stem names from the @@ -120,10 +119,32 @@ func configuredJarListToClasspathJars(ctx android.ModuleContext, configuredJars jars := make([]classpathJar, 0, len(paths)*len(classpaths)) for i := 0; i < len(paths); i++ { for _, classpathType := range classpaths { - jars = append(jars, classpathJar{ + jar := classpathJar{ classpath: classpathType, path: paths[i], + } + ctx.VisitDirectDepsIf(func(m android.Module) bool { + return m.Name() == configuredJars.Jar(i) + }, func(m android.Module) { + if s, ok := m.(*SdkLibrary); ok { + // TODO(208456999): instead of mapping "current" to latest, min_sdk_version should never be set to "current" + if s.minSdkVersion.Specified() { + if s.minSdkVersion.ApiLevel.IsCurrent() { + jar.minSdkVersion = ctx.Config().LatestPreviewApiLevel().String() + } else { + jar.minSdkVersion = s.minSdkVersion.ApiLevel.String() + } + } + if s.maxSdkVersion.Specified() { + if s.maxSdkVersion.ApiLevel.IsCurrent() { + jar.maxSdkVersion = ctx.Config().LatestPreviewApiLevel().String() + } else { + jar.maxSdkVersion = s.maxSdkVersion.ApiLevel.String() + } + } + } }) + jars = append(jars, jar) } } return jars @@ -161,6 +182,7 @@ func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.M func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) { var content strings.Builder + fmt.Fprintf(&content, "{\n") fmt.Fprintf(&content, "\"jars\": [\n") for idx, jar := range jars { @@ -169,6 +191,20 @@ func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, fmt.Fprintf(&content, "\"path\": \"%s\",\n", jar.path) fmt.Fprintf(&content, "\"classpath\": \"%s\"\n", jar.classpath) + if jar.minSdkVersion != "" { + fmt.Fprintf(&content, ",\n") + fmt.Fprintf(&content, "\"minSdkVersion\": \"%s\"\n", jar.minSdkVersion) + } else { + fmt.Fprintf(&content, "\n") + } + + if jar.maxSdkVersion != "" { + fmt.Fprintf(&content, ",\n") + fmt.Fprintf(&content, "\"maxSdkVersion\": \"%s\"\n", jar.maxSdkVersion) + } else { + fmt.Fprintf(&content, "\n") + } + if idx < len(jars)-1 { fmt.Fprintf(&content, "},\n") } else { @@ -177,6 +213,7 @@ func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, } fmt.Fprintf(&content, "]\n") fmt.Fprintf(&content, "}\n") + android.WriteFileRule(ctx, output, content.String()) } diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 9fec08a69..1e2723845 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -68,7 +68,6 @@ type platformBootclasspathProperties struct { func platformBootclasspathFactory() android.SingletonModule { m := &platformBootclasspathModule{} m.AddProperties(&m.properties) - // TODO(satayev): split apex jars into separate configs. initClasspathFragment(m, BOOTCLASSPATH) android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) return m