• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tools.metalava
17 
18 import com.android.tools.metalava.apilevels.ApiVersion
19 
20 /**
21  * ID and aliases for a given SDK extension.
22  *
23  * An SDK extension has an [id] corresponding to an Android dessert release that it extends, e.g.
24  * the T extension has an [id] of 33.
25  *
26  * @param id: numerical ID of the extension SDK, primarily used in generated artifacts and consumed
27  *   by tools
28  * @param shortname: short name for the SDK, primarily used in configuration files
29  * @param name: human-readable name for the SDK; used in the official documentation
30  * @param reference: Java symbol in the Android SDK with the same numerical value as the id, using a
31  *   JVM signature like syntax: "some/clazz$INNER$FIELD"
32  */
33 sealed class SdkExtension
34 private constructor(
35     val id: Int,
36     val shortname: String,
37     val name: String,
38     val reference: String,
39 ) {
40     /**
41      * Check to see whether this SDK extension supersedes the Android SDK version
42      * [androidSdkVersion].
43      *
44      * A dessert based extension supersedes an Android SDK version if it is based on that version or
45      * earlier.
46      *
47      * A dessert independent extension will always supersede an Android SDK version.
48      *
49      * @param androidSdkVersion the version of the Android SDK in which an API element was added.
50      */
supersedesAndroidSdkVersionnull51     abstract fun supersedesAndroidSdkVersion(androidSdkVersion: ApiVersion): Boolean
52 
53     init {
54         require(id >= 1) { "SDK extensions cannot have an id less than 1 but it is $id" }
55     }
56 
57     companion object {
58         /**
59          * Create an [SdkExtension] from the attributes that appear in sdk-extension-info.xml and
60          * api-versions.xml files.
61          *
62          * If [id] is greater than or equal to [DESSERT_RELEASE_INDEPENDENT_SDK_BASE] then the
63          * [SdkExtension] is independent of the Android SDK version, otherwise [id] is the base SDK
64          * version of the extension.
65          */
fromXmlAttributesnull66         fun fromXmlAttributes(id: Int, shortname: String, name: String, reference: String) =
67             if (id >= DESSERT_RELEASE_INDEPENDENT_SDK_BASE)
68                 DessertReleaseIndependentSdkExtension(id, shortname, name, reference)
69             else DessertReleaseBasedSdkExtension(id, shortname, name, reference)
70 
71         /**
72          * The base of dessert release independent SDKs.
73          *
74          * A dessert release independent SDK is one which is not coupled to the Android dessert
75          * release numbering. Any SDK greater than or equal to this is not comparable to either each
76          * other, or to the Android dessert release. e.g. `1000000` is not the same as, later than,
77          * or earlier than SDK 31. Similarly, `1000001` is not the same as, later than, or earlier
78          * then `1000000`.
79          */
80         private const val DESSERT_RELEASE_INDEPENDENT_SDK_BASE = 1000000
81     }
82 
83     /**
84      * An [SdkExtension] that is based on a specific version of the Android Sdk.
85      *
86      * The [id] is the major version of the Android SDK on which this is based.
87      */
88     private class DessertReleaseBasedSdkExtension(
89         id: Int,
90         shortname: String,
91         name: String,
92         reference: String,
93     ) : SdkExtension(id, shortname, name, reference) {
94 
95         /**
96          * The base [ApiVersion] of this extension. This the version of the Android SDK to which
97          * this extension applies.
98          */
99         private val baseSdkVersion = ApiVersion.fromLevel(id)
100 
101         override fun supersedesAndroidSdkVersion(androidSdkVersion: ApiVersion) =
102             baseSdkVersion <= androidSdkVersion
103     }
104 
105     /** An [SdkExtension] that is independent of an Android SDK version. */
106     private class DessertReleaseIndependentSdkExtension(
107         id: Int,
108         shortname: String,
109         name: String,
110         reference: String,
111     ) : SdkExtension(id, shortname, name, reference) {
supersedesAndroidSdkVersionnull112         override fun supersedesAndroidSdkVersion(androidSdkVersion: ApiVersion) = true
113     }
114 }
115