1*333d2b36SAndroid Build Coastguard Worker// Copyright 2021 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 android 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "fmt" 19*333d2b36SAndroid Build Coastguard Worker "reflect" 20*333d2b36SAndroid Build Coastguard Worker "strconv" 21*333d2b36SAndroid Build Coastguard Worker "strings" 22*333d2b36SAndroid Build Coastguard Worker) 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Workertype SdkContext interface { 25*333d2b36SAndroid Build Coastguard Worker // SdkVersion returns SdkSpec that corresponds to the sdk_version property of the current module 26*333d2b36SAndroid Build Coastguard Worker SdkVersion(ctx EarlyModuleContext) SdkSpec 27*333d2b36SAndroid Build Coastguard Worker // SystemModules returns the system_modules property of the current module, or an empty string if it is not set. 28*333d2b36SAndroid Build Coastguard Worker SystemModules() string 29*333d2b36SAndroid Build Coastguard Worker // MinSdkVersion returns ApiLevel that corresponds to the min_sdk_version property of the current module, 30*333d2b36SAndroid Build Coastguard Worker // or from sdk_version if it is not set. 31*333d2b36SAndroid Build Coastguard Worker MinSdkVersion(ctx EarlyModuleContext) ApiLevel 32*333d2b36SAndroid Build Coastguard Worker // ReplaceMaxSdkVersionPlaceholder returns Apilevel to replace the maxSdkVersion property of permission and 33*333d2b36SAndroid Build Coastguard Worker // uses-permission tags if it is set. 34*333d2b36SAndroid Build Coastguard Worker ReplaceMaxSdkVersionPlaceholder(ctx EarlyModuleContext) ApiLevel 35*333d2b36SAndroid Build Coastguard Worker // TargetSdkVersion returns the ApiLevel that corresponds to the target_sdk_version property of the current module, 36*333d2b36SAndroid Build Coastguard Worker // or from sdk_version if it is not set. 37*333d2b36SAndroid Build Coastguard Worker TargetSdkVersion(ctx EarlyModuleContext) ApiLevel 38*333d2b36SAndroid Build Coastguard Worker} 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker// SdkKind represents a particular category of an SDK spec like public, system, test, etc. 41*333d2b36SAndroid Build Coastguard Workertype SdkKind int 42*333d2b36SAndroid Build Coastguard Worker 43*333d2b36SAndroid Build Coastguard Worker// These are generally ordered from the narrower sdk version to the wider sdk version, 44*333d2b36SAndroid Build Coastguard Worker// but not all entries have a strict subset/superset relationship. 45*333d2b36SAndroid Build Coastguard Worker// For example, SdkTest and SdkModule do not have a strict subset/superset relationship but both 46*333d2b36SAndroid Build Coastguard Worker// are supersets of SdkSystem. 47*333d2b36SAndroid Build Coastguard Worker// The general trend should be kept when an additional sdk kind is added. 48*333d2b36SAndroid Build Coastguard Workerconst ( 49*333d2b36SAndroid Build Coastguard Worker SdkInvalid SdkKind = iota 50*333d2b36SAndroid Build Coastguard Worker SdkNone 51*333d2b36SAndroid Build Coastguard Worker SdkToolchain // API surface provided by ART to compile other API domains 52*333d2b36SAndroid Build Coastguard Worker SdkCore 53*333d2b36SAndroid Build Coastguard Worker SdkCorePlatform 54*333d2b36SAndroid Build Coastguard Worker SdkIntraCore // API surface provided by one core module to another 55*333d2b36SAndroid Build Coastguard Worker SdkPublic 56*333d2b36SAndroid Build Coastguard Worker SdkSystem 57*333d2b36SAndroid Build Coastguard Worker SdkTest 58*333d2b36SAndroid Build Coastguard Worker SdkTestFrameworksCore 59*333d2b36SAndroid Build Coastguard Worker SdkModule 60*333d2b36SAndroid Build Coastguard Worker SdkSystemServer 61*333d2b36SAndroid Build Coastguard Worker SdkPrivate 62*333d2b36SAndroid Build Coastguard Worker) 63*333d2b36SAndroid Build Coastguard Worker 64*333d2b36SAndroid Build Coastguard Worker// String returns the string representation of this SdkKind 65*333d2b36SAndroid Build Coastguard Workerfunc (k SdkKind) String() string { 66*333d2b36SAndroid Build Coastguard Worker switch k { 67*333d2b36SAndroid Build Coastguard Worker case SdkPrivate: 68*333d2b36SAndroid Build Coastguard Worker return "private" 69*333d2b36SAndroid Build Coastguard Worker case SdkNone: 70*333d2b36SAndroid Build Coastguard Worker return "none" 71*333d2b36SAndroid Build Coastguard Worker case SdkPublic: 72*333d2b36SAndroid Build Coastguard Worker return "public" 73*333d2b36SAndroid Build Coastguard Worker case SdkSystem: 74*333d2b36SAndroid Build Coastguard Worker return "system" 75*333d2b36SAndroid Build Coastguard Worker case SdkTest: 76*333d2b36SAndroid Build Coastguard Worker return "test" 77*333d2b36SAndroid Build Coastguard Worker case SdkTestFrameworksCore: 78*333d2b36SAndroid Build Coastguard Worker return "test_frameworks_core" 79*333d2b36SAndroid Build Coastguard Worker case SdkCore: 80*333d2b36SAndroid Build Coastguard Worker return "core" 81*333d2b36SAndroid Build Coastguard Worker case SdkCorePlatform: 82*333d2b36SAndroid Build Coastguard Worker return "core_platform" 83*333d2b36SAndroid Build Coastguard Worker case SdkIntraCore: 84*333d2b36SAndroid Build Coastguard Worker return "intracore" 85*333d2b36SAndroid Build Coastguard Worker case SdkModule: 86*333d2b36SAndroid Build Coastguard Worker return "module-lib" 87*333d2b36SAndroid Build Coastguard Worker case SdkSystemServer: 88*333d2b36SAndroid Build Coastguard Worker return "system-server" 89*333d2b36SAndroid Build Coastguard Worker case SdkToolchain: 90*333d2b36SAndroid Build Coastguard Worker return "toolchain" 91*333d2b36SAndroid Build Coastguard Worker default: 92*333d2b36SAndroid Build Coastguard Worker return "invalid" 93*333d2b36SAndroid Build Coastguard Worker } 94*333d2b36SAndroid Build Coastguard Worker} 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Workerfunc ToSdkKind(s string) SdkKind { 97*333d2b36SAndroid Build Coastguard Worker for kind := SdkNone; kind <= SdkPrivate; kind++ { 98*333d2b36SAndroid Build Coastguard Worker if s == kind.String() { 99*333d2b36SAndroid Build Coastguard Worker return kind 100*333d2b36SAndroid Build Coastguard Worker } 101*333d2b36SAndroid Build Coastguard Worker } 102*333d2b36SAndroid Build Coastguard Worker return SdkInvalid 103*333d2b36SAndroid Build Coastguard Worker} 104*333d2b36SAndroid Build Coastguard Worker 105*333d2b36SAndroid Build Coastguard Workerfunc (k SdkKind) DefaultJavaLibraryName() string { 106*333d2b36SAndroid Build Coastguard Worker switch k { 107*333d2b36SAndroid Build Coastguard Worker case SdkPublic: 108*333d2b36SAndroid Build Coastguard Worker return "android_stubs_current" 109*333d2b36SAndroid Build Coastguard Worker case SdkSystem: 110*333d2b36SAndroid Build Coastguard Worker return "android_system_stubs_current" 111*333d2b36SAndroid Build Coastguard Worker case SdkTest: 112*333d2b36SAndroid Build Coastguard Worker return "android_test_stubs_current" 113*333d2b36SAndroid Build Coastguard Worker case SdkTestFrameworksCore: 114*333d2b36SAndroid Build Coastguard Worker return "android_test_frameworks_core_stubs_current" 115*333d2b36SAndroid Build Coastguard Worker case SdkCore: 116*333d2b36SAndroid Build Coastguard Worker return "core.current.stubs" 117*333d2b36SAndroid Build Coastguard Worker case SdkModule: 118*333d2b36SAndroid Build Coastguard Worker return "android_module_lib_stubs_current" 119*333d2b36SAndroid Build Coastguard Worker case SdkSystemServer: 120*333d2b36SAndroid Build Coastguard Worker return "android_system_server_stubs_current" 121*333d2b36SAndroid Build Coastguard Worker default: 122*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("APIs of API surface %v cannot be provided by a single Soong module\n", k)) 123*333d2b36SAndroid Build Coastguard Worker } 124*333d2b36SAndroid Build Coastguard Worker} 125*333d2b36SAndroid Build Coastguard Worker 126*333d2b36SAndroid Build Coastguard Workerfunc (k SdkKind) DefaultExportableJavaLibraryName() string { 127*333d2b36SAndroid Build Coastguard Worker switch k { 128*333d2b36SAndroid Build Coastguard Worker case SdkPublic, SdkSystem, SdkTest, SdkModule, SdkSystemServer: 129*333d2b36SAndroid Build Coastguard Worker return k.DefaultJavaLibraryName() + "_exportable" 130*333d2b36SAndroid Build Coastguard Worker case SdkCore: 131*333d2b36SAndroid Build Coastguard Worker return k.DefaultJavaLibraryName() + ".exportable" 132*333d2b36SAndroid Build Coastguard Worker default: 133*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("API surface %v does not provide exportable stubs", k)) 134*333d2b36SAndroid Build Coastguard Worker } 135*333d2b36SAndroid Build Coastguard Worker} 136*333d2b36SAndroid Build Coastguard Worker 137*333d2b36SAndroid Build Coastguard Worker// SdkSpec represents the kind and the version of an SDK for a module to build against 138*333d2b36SAndroid Build Coastguard Workertype SdkSpec struct { 139*333d2b36SAndroid Build Coastguard Worker Kind SdkKind 140*333d2b36SAndroid Build Coastguard Worker ApiLevel ApiLevel 141*333d2b36SAndroid Build Coastguard Worker Raw string 142*333d2b36SAndroid Build Coastguard Worker} 143*333d2b36SAndroid Build Coastguard Worker 144*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) String() string { 145*333d2b36SAndroid Build Coastguard Worker return fmt.Sprintf("%s_%s", s.Kind, s.ApiLevel) 146*333d2b36SAndroid Build Coastguard Worker} 147*333d2b36SAndroid Build Coastguard Worker 148*333d2b36SAndroid Build Coastguard Worker// Valid checks if this SdkSpec is well-formed. Note however that true doesn't mean that the 149*333d2b36SAndroid Build Coastguard Worker// specified SDK actually exists. 150*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) Valid() bool { 151*333d2b36SAndroid Build Coastguard Worker return s.Kind != SdkInvalid 152*333d2b36SAndroid Build Coastguard Worker} 153*333d2b36SAndroid Build Coastguard Worker 154*333d2b36SAndroid Build Coastguard Worker// Specified checks if this SdkSpec is well-formed and is not "". 155*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) Specified() bool { 156*333d2b36SAndroid Build Coastguard Worker return s.Valid() && s.Kind != SdkPrivate 157*333d2b36SAndroid Build Coastguard Worker} 158*333d2b36SAndroid Build Coastguard Worker 159*333d2b36SAndroid Build Coastguard Worker// whether the API surface is managed and versioned, i.e. has .txt file that 160*333d2b36SAndroid Build Coastguard Worker// get frozen on SDK freeze and changes get reviewed by API council. 161*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) Stable() bool { 162*333d2b36SAndroid Build Coastguard Worker if !s.Specified() { 163*333d2b36SAndroid Build Coastguard Worker return false 164*333d2b36SAndroid Build Coastguard Worker } 165*333d2b36SAndroid Build Coastguard Worker switch s.Kind { 166*333d2b36SAndroid Build Coastguard Worker case SdkNone: 167*333d2b36SAndroid Build Coastguard Worker // there is nothing to manage and version in this case; de facto stable API. 168*333d2b36SAndroid Build Coastguard Worker return true 169*333d2b36SAndroid Build Coastguard Worker case SdkCore, SdkPublic, SdkSystem, SdkModule, SdkSystemServer: 170*333d2b36SAndroid Build Coastguard Worker return true 171*333d2b36SAndroid Build Coastguard Worker case SdkCorePlatform, SdkTest, SdkTestFrameworksCore, SdkPrivate: 172*333d2b36SAndroid Build Coastguard Worker return false 173*333d2b36SAndroid Build Coastguard Worker default: 174*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("unknown SdkKind=%v", s.Kind)) 175*333d2b36SAndroid Build Coastguard Worker } 176*333d2b36SAndroid Build Coastguard Worker return false 177*333d2b36SAndroid Build Coastguard Worker} 178*333d2b36SAndroid Build Coastguard Worker 179*333d2b36SAndroid Build Coastguard Worker// PrebuiltSdkAvailableForUnbundledBuild tells whether this SdkSpec can have a prebuilt SDK 180*333d2b36SAndroid Build Coastguard Worker// that can be used for unbundled builds. 181*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) PrebuiltSdkAvailableForUnbundledBuild() bool { 182*333d2b36SAndroid Build Coastguard Worker // "", "none", and "core_platform" are not available for unbundled build 183*333d2b36SAndroid Build Coastguard Worker // as we don't/can't have prebuilt stub for the versions 184*333d2b36SAndroid Build Coastguard Worker return s.Kind != SdkPrivate && s.Kind != SdkNone && s.Kind != SdkCorePlatform 185*333d2b36SAndroid Build Coastguard Worker} 186*333d2b36SAndroid Build Coastguard Worker 187*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) ForVendorPartition(ctx EarlyModuleContext) SdkSpec { 188*333d2b36SAndroid Build Coastguard Worker // If BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES has a numeric value, 189*333d2b36SAndroid Build Coastguard Worker // use it instead of "current" for the vendor partition. 190*333d2b36SAndroid Build Coastguard Worker currentSdkVersion := ctx.DeviceConfig().CurrentApiLevelForVendorModules() 191*333d2b36SAndroid Build Coastguard Worker // b/314011075: special case for Java modules in vendor partition. They can no longer use 192*333d2b36SAndroid Build Coastguard Worker // SDK 35 or later. Their maximum API level is limited to 34 (Android U). This is to 193*333d2b36SAndroid Build Coastguard Worker // discourage the use of Java APIs in the vendor partition which hasn't been officially 194*333d2b36SAndroid Build Coastguard Worker // supported since the Project Treble back in Android 10. We would like to eventually 195*333d2b36SAndroid Build Coastguard Worker // evacuate all Java modules from the partition, but that shall be done progressively. 196*333d2b36SAndroid Build Coastguard Worker // Note that the check for the availability of SDK 34 is to not break existing tests where 197*333d2b36SAndroid Build Coastguard Worker // any of the frozen SDK version is unavailable. 198*333d2b36SAndroid Build Coastguard Worker if isJava(ctx.Module()) && isSdkVersion34AvailableIn(ctx.Config()) { 199*333d2b36SAndroid Build Coastguard Worker currentSdkVersion = "34" 200*333d2b36SAndroid Build Coastguard Worker } 201*333d2b36SAndroid Build Coastguard Worker 202*333d2b36SAndroid Build Coastguard Worker if currentSdkVersion == "current" { 203*333d2b36SAndroid Build Coastguard Worker return s 204*333d2b36SAndroid Build Coastguard Worker } 205*333d2b36SAndroid Build Coastguard Worker 206*333d2b36SAndroid Build Coastguard Worker if s.Kind == SdkPublic || s.Kind == SdkSystem { 207*333d2b36SAndroid Build Coastguard Worker if s.ApiLevel.IsCurrent() { 208*333d2b36SAndroid Build Coastguard Worker if i, err := strconv.Atoi(currentSdkVersion); err == nil { 209*333d2b36SAndroid Build Coastguard Worker apiLevel := uncheckedFinalApiLevel(i) 210*333d2b36SAndroid Build Coastguard Worker return SdkSpec{s.Kind, apiLevel, s.Raw} 211*333d2b36SAndroid Build Coastguard Worker } 212*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES must be either \"current\" or a number, but was %q", currentSdkVersion)) 213*333d2b36SAndroid Build Coastguard Worker } 214*333d2b36SAndroid Build Coastguard Worker } 215*333d2b36SAndroid Build Coastguard Worker return s 216*333d2b36SAndroid Build Coastguard Worker} 217*333d2b36SAndroid Build Coastguard Worker 218*333d2b36SAndroid Build Coastguard Worker// UsePrebuilt determines whether prebuilt SDK should be used for this SdkSpec with the given context. 219*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) UsePrebuilt(ctx EarlyModuleContext) bool { 220*333d2b36SAndroid Build Coastguard Worker switch s { 221*333d2b36SAndroid Build Coastguard Worker case SdkSpecNone, SdkSpecCorePlatform, SdkSpecPrivate: 222*333d2b36SAndroid Build Coastguard Worker return false 223*333d2b36SAndroid Build Coastguard Worker } 224*333d2b36SAndroid Build Coastguard Worker 225*333d2b36SAndroid Build Coastguard Worker if s.ApiLevel.IsCurrent() { 226*333d2b36SAndroid Build Coastguard Worker // "current" can be built from source and be from prebuilt SDK 227*333d2b36SAndroid Build Coastguard Worker return ctx.Config().AlwaysUsePrebuiltSdks() 228*333d2b36SAndroid Build Coastguard Worker } else if !s.ApiLevel.IsPreview() { 229*333d2b36SAndroid Build Coastguard Worker // validation check 230*333d2b36SAndroid Build Coastguard Worker if s.Kind != SdkPublic && s.Kind != SdkSystem && s.Kind != SdkTest && 231*333d2b36SAndroid Build Coastguard Worker s.Kind != SdkTestFrameworksCore && s.Kind != SdkModule && s.Kind != SdkSystemServer { 232*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("prebuilt SDK is not not available for SdkKind=%q", s.Kind)) 233*333d2b36SAndroid Build Coastguard Worker return false 234*333d2b36SAndroid Build Coastguard Worker } 235*333d2b36SAndroid Build Coastguard Worker // numbered SDKs are always from prebuilt 236*333d2b36SAndroid Build Coastguard Worker return true 237*333d2b36SAndroid Build Coastguard Worker } 238*333d2b36SAndroid Build Coastguard Worker return false 239*333d2b36SAndroid Build Coastguard Worker} 240*333d2b36SAndroid Build Coastguard Worker 241*333d2b36SAndroid Build Coastguard Worker// EffectiveVersion converts an SdkSpec into the concrete ApiLevel that the module should use. For 242*333d2b36SAndroid Build Coastguard Worker// modules targeting an unreleased SDK (meaning it does not yet have a number) it returns 243*333d2b36SAndroid Build Coastguard Worker// FutureApiLevel(10000). 244*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) EffectiveVersion(ctx EarlyModuleContext) (ApiLevel, error) { 245*333d2b36SAndroid Build Coastguard Worker if !s.Valid() { 246*333d2b36SAndroid Build Coastguard Worker return s.ApiLevel, fmt.Errorf("invalid sdk version %q", s.Raw) 247*333d2b36SAndroid Build Coastguard Worker } 248*333d2b36SAndroid Build Coastguard Worker 249*333d2b36SAndroid Build Coastguard Worker if ctx.DeviceSpecific() || ctx.SocSpecific() { 250*333d2b36SAndroid Build Coastguard Worker s = s.ForVendorPartition(ctx) 251*333d2b36SAndroid Build Coastguard Worker } 252*333d2b36SAndroid Build Coastguard Worker return s.ApiLevel.EffectiveVersion(ctx) 253*333d2b36SAndroid Build Coastguard Worker} 254*333d2b36SAndroid Build Coastguard Worker 255*333d2b36SAndroid Build Coastguard Worker// EffectiveVersionString converts an SdkSpec into the concrete version string that the module 256*333d2b36SAndroid Build Coastguard Worker// should use. For modules targeting an unreleased SDK (meaning it does not yet have a number) 257*333d2b36SAndroid Build Coastguard Worker// it returns the codename (P, Q, R, etc.) 258*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) EffectiveVersionString(ctx EarlyModuleContext) (string, error) { 259*333d2b36SAndroid Build Coastguard Worker if !s.Valid() { 260*333d2b36SAndroid Build Coastguard Worker return s.ApiLevel.String(), fmt.Errorf("invalid sdk version %q", s.Raw) 261*333d2b36SAndroid Build Coastguard Worker } 262*333d2b36SAndroid Build Coastguard Worker 263*333d2b36SAndroid Build Coastguard Worker if ctx.DeviceSpecific() || ctx.SocSpecific() { 264*333d2b36SAndroid Build Coastguard Worker s = s.ForVendorPartition(ctx) 265*333d2b36SAndroid Build Coastguard Worker } 266*333d2b36SAndroid Build Coastguard Worker return s.ApiLevel.EffectiveVersionString(ctx) 267*333d2b36SAndroid Build Coastguard Worker} 268*333d2b36SAndroid Build Coastguard Worker 269*333d2b36SAndroid Build Coastguard Workervar ( 270*333d2b36SAndroid Build Coastguard Worker SdkSpecNone = SdkSpec{SdkNone, NoneApiLevel, "(no version)"} 271*333d2b36SAndroid Build Coastguard Worker SdkSpecPrivate = SdkSpec{SdkPrivate, PrivateApiLevel, ""} 272*333d2b36SAndroid Build Coastguard Worker SdkSpecCorePlatform = SdkSpec{SdkCorePlatform, FutureApiLevel, "core_platform"} 273*333d2b36SAndroid Build Coastguard Worker) 274*333d2b36SAndroid Build Coastguard Worker 275*333d2b36SAndroid Build Coastguard Workerfunc SdkSpecFrom(ctx EarlyModuleContext, str string) SdkSpec { 276*333d2b36SAndroid Build Coastguard Worker return SdkSpecFromWithConfig(ctx.Config(), str) 277*333d2b36SAndroid Build Coastguard Worker} 278*333d2b36SAndroid Build Coastguard Worker 279*333d2b36SAndroid Build Coastguard Workerfunc SdkSpecFromWithConfig(config Config, str string) SdkSpec { 280*333d2b36SAndroid Build Coastguard Worker switch str { 281*333d2b36SAndroid Build Coastguard Worker // special cases first 282*333d2b36SAndroid Build Coastguard Worker case "": 283*333d2b36SAndroid Build Coastguard Worker return SdkSpecPrivate 284*333d2b36SAndroid Build Coastguard Worker case "none": 285*333d2b36SAndroid Build Coastguard Worker return SdkSpecNone 286*333d2b36SAndroid Build Coastguard Worker case "core_platform": 287*333d2b36SAndroid Build Coastguard Worker return SdkSpecCorePlatform 288*333d2b36SAndroid Build Coastguard Worker default: 289*333d2b36SAndroid Build Coastguard Worker // the syntax is [kind_]version 290*333d2b36SAndroid Build Coastguard Worker sep := strings.LastIndex(str, "_") 291*333d2b36SAndroid Build Coastguard Worker 292*333d2b36SAndroid Build Coastguard Worker var kindString string 293*333d2b36SAndroid Build Coastguard Worker if sep == 0 { 294*333d2b36SAndroid Build Coastguard Worker return SdkSpec{SdkInvalid, NewInvalidApiLevel(str), str} 295*333d2b36SAndroid Build Coastguard Worker } else if sep == -1 { 296*333d2b36SAndroid Build Coastguard Worker kindString = "" 297*333d2b36SAndroid Build Coastguard Worker } else { 298*333d2b36SAndroid Build Coastguard Worker kindString = str[0:sep] 299*333d2b36SAndroid Build Coastguard Worker } 300*333d2b36SAndroid Build Coastguard Worker versionString := str[sep+1 : len(str)] 301*333d2b36SAndroid Build Coastguard Worker 302*333d2b36SAndroid Build Coastguard Worker var kind SdkKind 303*333d2b36SAndroid Build Coastguard Worker switch kindString { 304*333d2b36SAndroid Build Coastguard Worker case "": 305*333d2b36SAndroid Build Coastguard Worker kind = SdkPublic 306*333d2b36SAndroid Build Coastguard Worker case "core": 307*333d2b36SAndroid Build Coastguard Worker kind = SdkCore 308*333d2b36SAndroid Build Coastguard Worker case "system": 309*333d2b36SAndroid Build Coastguard Worker kind = SdkSystem 310*333d2b36SAndroid Build Coastguard Worker case "test": 311*333d2b36SAndroid Build Coastguard Worker kind = SdkTest 312*333d2b36SAndroid Build Coastguard Worker case "test_frameworks_core": 313*333d2b36SAndroid Build Coastguard Worker kind = SdkTestFrameworksCore 314*333d2b36SAndroid Build Coastguard Worker case "module": 315*333d2b36SAndroid Build Coastguard Worker kind = SdkModule 316*333d2b36SAndroid Build Coastguard Worker case "system_server": 317*333d2b36SAndroid Build Coastguard Worker kind = SdkSystemServer 318*333d2b36SAndroid Build Coastguard Worker default: 319*333d2b36SAndroid Build Coastguard Worker return SdkSpec{SdkInvalid, NoneApiLevel, str} 320*333d2b36SAndroid Build Coastguard Worker } 321*333d2b36SAndroid Build Coastguard Worker 322*333d2b36SAndroid Build Coastguard Worker apiLevel, err := ApiLevelFromUserWithConfig(config, versionString) 323*333d2b36SAndroid Build Coastguard Worker if err != nil { 324*333d2b36SAndroid Build Coastguard Worker return SdkSpec{SdkInvalid, NewInvalidApiLevel(versionString), str} 325*333d2b36SAndroid Build Coastguard Worker } 326*333d2b36SAndroid Build Coastguard Worker return SdkSpec{kind, apiLevel, str} 327*333d2b36SAndroid Build Coastguard Worker } 328*333d2b36SAndroid Build Coastguard Worker} 329*333d2b36SAndroid Build Coastguard Worker 330*333d2b36SAndroid Build Coastguard Worker// Checks if the use of this SDK `s` is valid for the given module context `ctx`. 331*333d2b36SAndroid Build Coastguard Workerfunc (s SdkSpec) ValidateSystemSdk(ctx EarlyModuleContext) bool { 332*333d2b36SAndroid Build Coastguard Worker // Do some early checks. This check is currently only for Java modules. And our only concern 333*333d2b36SAndroid Build Coastguard Worker // is the use of "system" SDKs. 334*333d2b36SAndroid Build Coastguard Worker if !isJava(ctx.Module()) || s.Kind != SdkSystem || ctx.DeviceConfig().BuildBrokenDontCheckSystemSdk() { 335*333d2b36SAndroid Build Coastguard Worker return true 336*333d2b36SAndroid Build Coastguard Worker } 337*333d2b36SAndroid Build Coastguard Worker 338*333d2b36SAndroid Build Coastguard Worker inVendor := ctx.DeviceSpecific() || ctx.SocSpecific() 339*333d2b36SAndroid Build Coastguard Worker inProduct := ctx.ProductSpecific() 340*333d2b36SAndroid Build Coastguard Worker isProductUnbundled := ctx.Config().EnforceProductPartitionInterface() 341*333d2b36SAndroid Build Coastguard Worker inApex := false 342*333d2b36SAndroid Build Coastguard Worker if am, ok := ctx.Module().(ApexModule); ok { 343*333d2b36SAndroid Build Coastguard Worker inApex = am.InAnyApex() 344*333d2b36SAndroid Build Coastguard Worker } 345*333d2b36SAndroid Build Coastguard Worker isUnbundled := inVendor || (inProduct && isProductUnbundled) || inApex 346*333d2b36SAndroid Build Coastguard Worker 347*333d2b36SAndroid Build Coastguard Worker // Bundled modules can use any SDK 348*333d2b36SAndroid Build Coastguard Worker if !isUnbundled { 349*333d2b36SAndroid Build Coastguard Worker return true 350*333d2b36SAndroid Build Coastguard Worker } 351*333d2b36SAndroid Build Coastguard Worker 352*333d2b36SAndroid Build Coastguard Worker // Unbundled modules are allowed to use BOARD_SYSTEMSDK_VERSIONS 353*333d2b36SAndroid Build Coastguard Worker supportedVersions := ctx.DeviceConfig().SystemSdkVersions() 354*333d2b36SAndroid Build Coastguard Worker 355*333d2b36SAndroid Build Coastguard Worker // b/314011075: special case for vendor modules. Java modules in the vendor partition can 356*333d2b36SAndroid Build Coastguard Worker // not use SDK 35 or later. This is to discourage the use of Java APIs in the vendor 357*333d2b36SAndroid Build Coastguard Worker // partition which hasn't been officially supported since the Project Treble back in Android 358*333d2b36SAndroid Build Coastguard Worker // 10. We would like to eventually evacuate all Java modules from the partition, but that 359*333d2b36SAndroid Build Coastguard Worker // shall be done progressively. 360*333d2b36SAndroid Build Coastguard Worker if inVendor { 361*333d2b36SAndroid Build Coastguard Worker // 28 was the API when BOARD_SYSTEMSDK_VERSIONS was introduced, so that's the oldest 362*333d2b36SAndroid Build Coastguard Worker // we should allow. 363*333d2b36SAndroid Build Coastguard Worker supportedVersions = []string{} 364*333d2b36SAndroid Build Coastguard Worker for v := 28; v <= 34; v++ { 365*333d2b36SAndroid Build Coastguard Worker supportedVersions = append(supportedVersions, strconv.Itoa(v)) 366*333d2b36SAndroid Build Coastguard Worker } 367*333d2b36SAndroid Build Coastguard Worker } 368*333d2b36SAndroid Build Coastguard Worker 369*333d2b36SAndroid Build Coastguard Worker // APEXes in the system partition are still considered as part of the platform, thus can use 370*333d2b36SAndroid Build Coastguard Worker // more SDKs from PLATFORM_SYSTEMSDK_VERSIONS 371*333d2b36SAndroid Build Coastguard Worker if inApex && !inVendor { 372*333d2b36SAndroid Build Coastguard Worker supportedVersions = ctx.DeviceConfig().PlatformSystemSdkVersions() 373*333d2b36SAndroid Build Coastguard Worker } 374*333d2b36SAndroid Build Coastguard Worker 375*333d2b36SAndroid Build Coastguard Worker thisVer, err := s.EffectiveVersion(ctx) 376*333d2b36SAndroid Build Coastguard Worker if err != nil { 377*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("sdk_version", "invalid sdk version %q", s.Raw) 378*333d2b36SAndroid Build Coastguard Worker return false 379*333d2b36SAndroid Build Coastguard Worker } 380*333d2b36SAndroid Build Coastguard Worker 381*333d2b36SAndroid Build Coastguard Worker thisVerString := strconv.Itoa(thisVer.FinalOrPreviewInt()) 382*333d2b36SAndroid Build Coastguard Worker if thisVer.IsPreview() { 383*333d2b36SAndroid Build Coastguard Worker thisVerString = *ctx.Config().productVariables.Platform_sdk_version_or_codename 384*333d2b36SAndroid Build Coastguard Worker } 385*333d2b36SAndroid Build Coastguard Worker 386*333d2b36SAndroid Build Coastguard Worker if !InList(thisVerString, supportedVersions) { 387*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q", 388*333d2b36SAndroid Build Coastguard Worker s.Raw, supportedVersions) 389*333d2b36SAndroid Build Coastguard Worker return false 390*333d2b36SAndroid Build Coastguard Worker } 391*333d2b36SAndroid Build Coastguard Worker return true 392*333d2b36SAndroid Build Coastguard Worker} 393*333d2b36SAndroid Build Coastguard Worker 394*333d2b36SAndroid Build Coastguard Workerfunc isJava(m Module) bool { 395*333d2b36SAndroid Build Coastguard Worker moduleType := reflect.TypeOf(m).String() 396*333d2b36SAndroid Build Coastguard Worker return strings.HasPrefix(moduleType, "*java.") 397*333d2b36SAndroid Build Coastguard Worker} 398*333d2b36SAndroid Build Coastguard Worker 399*333d2b36SAndroid Build Coastguard Workerfunc isSdkVersion34AvailableIn(c Config) bool { 400*333d2b36SAndroid Build Coastguard Worker return c.PlatformSdkVersion().FinalInt() >= 34 401*333d2b36SAndroid Build Coastguard Worker} 402*333d2b36SAndroid Build Coastguard Worker 403*333d2b36SAndroid Build Coastguard Workerfunc init() { 404*333d2b36SAndroid Build Coastguard Worker RegisterMakeVarsProvider(pctx, javaSdkMakeVars) 405*333d2b36SAndroid Build Coastguard Worker} 406*333d2b36SAndroid Build Coastguard Worker 407*333d2b36SAndroid Build Coastguard Worker// Export the name of the soong modules representing the various Java API surfaces. 408*333d2b36SAndroid Build Coastguard Workerfunc javaSdkMakeVars(ctx MakeVarsContext) { 409*333d2b36SAndroid Build Coastguard Worker ctx.Strict("ANDROID_PUBLIC_STUBS", SdkPublic.DefaultJavaLibraryName()) 410*333d2b36SAndroid Build Coastguard Worker ctx.Strict("ANDROID_PUBLIC_EXPORTABLE_STUBS", SdkPublic.DefaultExportableJavaLibraryName()) 411*333d2b36SAndroid Build Coastguard Worker ctx.Strict("ANDROID_SYSTEM_STUBS", SdkSystem.DefaultJavaLibraryName()) 412*333d2b36SAndroid Build Coastguard Worker ctx.Strict("ANDROID_TEST_STUBS", SdkTest.DefaultJavaLibraryName()) 413*333d2b36SAndroid Build Coastguard Worker ctx.Strict("ANDROID_MODULE_LIB_STUBS", SdkModule.DefaultJavaLibraryName()) 414*333d2b36SAndroid Build Coastguard Worker ctx.Strict("ANDROID_SYSTEM_SERVER_STUBS", SdkSystemServer.DefaultJavaLibraryName()) 415*333d2b36SAndroid Build Coastguard Worker ctx.Strict("ANDROID_CORE_STUBS", SdkCore.DefaultJavaLibraryName()) 416*333d2b36SAndroid Build Coastguard Worker} 417