1# Copyright (C) 2023 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# An API level, can be a finalized (numbered) API, a preview (codenamed) API, or 16# the future API level (10000). Can be parsed from a string with 17# parse_api_level_with_version. 18 19load("@bazel_skylib//lib:dicts.bzl", "dicts") 20load("@soong_injection//api_levels:api_levels.bzl", "api_levels_released_versions") 21load("@soong_injection//api_levels:platform_versions.bzl", "platform_versions") 22 23_NONE_API_LEVEL_INT = -1 24_PREVIEW_API_LEVEL_BASE = 9000 # Base constant for preview API levels. 25_FUTURE_API_LEVEL_INT = 10000 # API Level associated with an arbitrary future release 26 27# TODO(b/271280342): access these variables in a transition friendly way. 28_PLATFORM_SDK_FINAL = platform_versions.platform_sdk_final 29_PLATFORM_SDK_VERSION = platform_versions.platform_sdk_version 30_PLATFORM_SDK_CODENAME = platform_versions.platform_sdk_codename 31_PLATFORM_VERSION_ACTIVE_CODENAMES = platform_versions.platform_version_active_codenames 32 33# Dict of unfinalized codenames to a placeholder preview API int. 34_preview_codenames_to_ints = { 35 codename: _PREVIEW_API_LEVEL_BASE + i 36 for i, codename in enumerate(_PLATFORM_VERSION_ACTIVE_CODENAMES) 37} 38 39# Returns true if a string or int version is in preview (not finalized). 40def _is_preview(version): 41 if type(version) == "string" and version.isdigit(): 42 # normalize int types internally 43 version = int(version) 44 45 # Future / current is considered as a preview. 46 if version == "current" or version == _FUTURE_API_LEVEL_INT: 47 return True 48 49 # api can be either the codename or the int level (9000+) 50 return version in _preview_codenames_to_ints or version in _preview_codenames_to_ints.values() 51 52# Return 10000 for unfinalized versions, otherwise return unchanged. 53def _final_or_future(version): 54 if _is_preview(version): 55 return _FUTURE_API_LEVEL_INT 56 else: 57 return version 58 59_final_codename = { 60 "current": _final_or_future(_PLATFORM_SDK_VERSION), 61} if _PLATFORM_SDK_FINAL and _PLATFORM_SDK_VERSION else {} 62 63_api_levels_with_previews = dicts.add(api_levels_released_versions, _preview_codenames_to_ints) 64_api_levels_with_final_codenames = dicts.add(api_levels_released_versions, _final_codename) # @unused 65 66# parse_api_level_from_version is a Starlark implementation of ApiLevelFromUser 67# at https://cs.android.com/android/platform/superproject/+/master:build/soong/android/api_levels.go;l=221-250;drc=5095a6c4b484f34d5c4f55a855d6174e00fb7f5e 68def _parse_api_level_from_version(version): 69 """converts the given string `version` to an api level 70 71 Args: 72 version: must be non-empty. Inputs that are not "current", known 73 previews, finalized codenames, or convertible to an integer will return 74 an error. 75 76 Returns: The api level as an int. 77 """ 78 if version == "": 79 fail("API level string must be non-empty") 80 81 if version == "current": 82 return _FUTURE_API_LEVEL_INT 83 84 if _is_preview(version): 85 return _preview_codenames_to_ints.get(version) or int(version) 86 87 # Not preview nor current. 88 # 89 # If the level is the codename of an API level that has been finalized, this 90 # function returns the API level number associated with that API level. If 91 # the input is *not* a finalized codename, the input is returned unmodified. 92 canonical_level = api_levels_released_versions.get(version) 93 if not canonical_level: 94 if not version.isdigit(): 95 fail("version %s could not be parsed as integer and is not a recognized codename" % version) 96 return int(version) 97 return canonical_level 98 99# Starlark implementation of DefaultAppTargetSDK from build/soong/android/config.go 100# https://cs.android.com/android/platform/superproject/+/master:build/soong/android/config.go;l=875-889;drc=b0dc477ef740ec959548fe5517bd92ac4ea0325c 101# check what you want returned for codename == "" case before using 102def _default_app_target_sdk(): 103 """default_app_target_sdk returns the API level that platform apps are targeting. 104 This converts a codename to the exact ApiLevel it represents. 105 """ 106 if _PLATFORM_SDK_FINAL: 107 return _PLATFORM_SDK_VERSION 108 109 codename = _PLATFORM_SDK_CODENAME 110 if not codename: 111 # soong returns NoneApiLevel here value: "(no version)", number: -1, isPreview: true 112 # 113 # fail fast instead of returning an arbitrary value. 114 fail("Platform_sdk_codename must be set.") 115 116 if codename == "REL": 117 fail("Platform_sdk_codename should not be REL when Platform_sdk_final is false") 118 119 return _parse_api_level_from_version(codename) 120 121api = struct( 122 NONE_API_LEVEL = _NONE_API_LEVEL_INT, 123 FUTURE_API_LEVEL = _FUTURE_API_LEVEL_INT, 124 is_preview = _is_preview, 125 final_or_future = _final_or_future, 126 default_app_target_sdk = _default_app_target_sdk, 127 parse_api_level_from_version = _parse_api_level_from_version, 128 api_levels = _api_levels_with_previews, 129) 130