xref: /aosp_15_r20/build/soong/android/sdk_version.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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