blob: 53afef30af23cdc2140a0a56f829d8582259236e [file] [log] [blame]
shrikar0ca801e2023-11-02 22:25:54 +00001#!/usr/bin/python3
2
3# Copyright (C) 2023 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""A script to generate ENUM_NAME.java file and test files using ENUM_NAME.aidl file.
18
19 Need ANDROID_BUILD_TOP environmental variable to be set. This script will update ENUM_NAME.java
20 under packages/services/Car/car-lib/src/android/car/hardware/property, as well as the
21 ENUM_NAMETest.java files in cts/tests/tests/car/src/android/car/cts and
22 packages/services/Car/tests/android_car_api_test/src/android/car/apitest
23
shrikar4d9c95f2024-10-24 18:06:53 +000024 Also needs a flag name e.g. FLAG_ANDROID_VIC_VEHICLE_PROPERTIES
25
shrikar0ca801e2023-11-02 22:25:54 +000026 Usage:
shrikar4d9c95f2024-10-24 18:06:53 +000027 $ python translate_aidl_enums.py ENUM_NAME.aidl FLAG_NAME
shrikar0ca801e2023-11-02 22:25:54 +000028"""
29import os
30import sys
31
32LICENSE = """/*
shrikar4d9c95f2024-10-24 18:06:53 +000033 * Copyright (C) 2024 The Android Open Source Project
shrikar0ca801e2023-11-02 22:25:54 +000034 *
35 * Licensed under the Apache License, Version 2.0 (the "License");
36 * you may not use this file except in compliance with the License.
37 * You may obtain a copy of the License at
38 *
39 * http://www.apache.org/licenses/LICENSE-2.0
40 *
41 * Unless required by applicable law or agreed to in writing, software
42 * distributed under the License is distributed on an "AS IS" BASIS,
43 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44 * See the License for the specific language governing permissions and
45 * limitations under the License.
46 */
47"""
48
49class EnumParser:
shrikar4d9c95f2024-10-24 18:06:53 +000050 def __init__(self, file_path, file_name, flag_name):
shrikar0ca801e2023-11-02 22:25:54 +000051 self.filePath = file_path
52 self.fileName = file_name
shrikar4d9c95f2024-10-24 18:06:53 +000053 self.flagName = flag_name
shrikar0ca801e2023-11-02 22:25:54 +000054 self.lowerFileName = self.fileName[0].lower() + self.fileName[1:]
shrikar4d9c95f2024-10-24 18:06:53 +000055 self.enumNames = []
shrikar0ca801e2023-11-02 22:25:54 +000056 self.enums = []
57 self.outputMsg = []
58 self.outputMsg.append(LICENSE)
59 self.outputMsg.append("\npackage android.car.hardware.property;\n")
60 self.outputMsg.append("""
shrikar4d9c95f2024-10-24 18:06:53 +000061import static android.car.feature.Flags.{};
62
63import android.annotation.FlaggedApi;
shrikar0ca801e2023-11-02 22:25:54 +000064import android.annotation.IntDef;
65import android.annotation.NonNull;
66
67import com.android.car.internal.util.ConstantDebugUtils;
68
69import java.lang.annotation.Retention;
70import java.lang.annotation.RetentionPolicy;
shrikar4d9c95f2024-10-24 18:06:53 +000071""".format(self.flagName))
72
73 comment_block = []
74 in_comment = False
shrikar0ca801e2023-11-02 22:25:54 +000075
76 with open(self.filePath, 'r') as f:
shrikar4d9c95f2024-10-24 18:06:53 +000077 lines = f.readlines()
78 for line in lines:
79 line = line.rstrip('\n')
80 if line.strip() in ["package android.hardware.automotive.vehicle;",
81 "@VintfStability",
82 '@Backing(type="int")']:
shrikar0ca801e2023-11-02 22:25:54 +000083 continue
84
shrikar4d9c95f2024-10-24 18:06:53 +000085 if line.strip().startswith('/**') or line.strip().startswith('/*'):
86 in_comment = True
87 comment_block.append(line + '\n')
88 continue
89 elif in_comment:
90 comment_block.append(line + '\n')
91 if line.strip().endswith('*/'):
92 in_comment = False
93 continue
94 elif line.strip().startswith('*'):
95 comment_block.append(line + '\n')
96 continue
97
98 msg = line + '\n'
shrikar0ca801e2023-11-02 22:25:54 +000099 msgSplit = msg.strip().split()
100 if len(msgSplit) > 0 and msgSplit[0] == "enum":
shrikar4d9c95f2024-10-24 18:06:53 +0000101 if comment_block:
102 self.outputMsg.extend(comment_block)
103 comment_block = []
104 self.outputMsg.append("@FlaggedApi({})\n".format(self.flagName))
shrikar0ca801e2023-11-02 22:25:54 +0000105 msgSplit[0] = "public final class"
106 msg = " ".join(msgSplit) + "\n"
shrikar4d9c95f2024-10-24 18:06:53 +0000107 self.outputMsg.append(msg)
shrikar0ca801e2023-11-02 22:25:54 +0000108 elif len(msgSplit) > 1 and msgSplit[1] == '=':
shrikar4d9c95f2024-10-24 18:06:53 +0000109 if comment_block:
110 indented_comment_block = [line for line in comment_block]
111 self.outputMsg.extend(indented_comment_block)
112 comment_block = []
shrikar0ca801e2023-11-02 22:25:54 +0000113 msgSplit.insert(0, " public static final int")
shrikar4d9c95f2024-10-24 18:06:53 +0000114 enum_name = msgSplit[1].strip()
115 self.enumNames.append(enum_name)
116 enum = msgSplit[3].strip(",")
117 self.enums.append(enum)
118 if msgSplit[-1].endswith(','):
119 msgSplit[-1] = msgSplit[-1][:-1] + ";"
120 msg = " ".join(msgSplit) + "\n"
121 self.outputMsg.append(msg)
122 elif line.strip() == '}':
123 if comment_block:
124 self.outputMsg.extend(comment_block)
125 comment_block = []
shrikar0ca801e2023-11-02 22:25:54 +0000126 self.outputMsg.append("""
127 private {2}() {{}}
128
129 /**
130 * Returns a user-friendly representation of {{@code {2}}}.
131 */
132 @NonNull
133 public static String toString(@{2}Int int {0}) {{
134 String {0}String = ConstantDebugUtils.toName(
135 {2}.class, {0});
136 return ({0}String != null)
137 ? {0}String
138 : "0x" + Integer.toHexString({0});
139 }}
140
141 /** @hide */
142 @IntDef({1})
143 @Retention(RetentionPolicy.SOURCE)
144 public @interface {2}Int {{}}\n""".format(self.lowerFileName, "{" + ", ".join(self.enums) + "}",
145 self.fileName))
shrikar4d9c95f2024-10-24 18:06:53 +0000146 self.outputMsg.append("}")
shrikar0ca801e2023-11-02 22:25:54 +0000147
148 self.outputMsgApiTest = []
149 self.outputMsgApiTest.append(LICENSE)
150 self.outputMsgApiTest.append("""package android.car.apitest;
151
shrikar4d9c95f2024-10-24 18:06:53 +0000152import static android.car.feature.Flags.{1};
153
shrikar0ca801e2023-11-02 22:25:54 +0000154import static com.google.common.truth.Truth.assertWithMessage;
155
shrikar4d9c95f2024-10-24 18:06:53 +0000156import android.platform.test.annotations.RequiresFlagsEnabled;
157import android.platform.test.flag.junit.CheckFlagsRule;
158import android.platform.test.flag.junit.DeviceFlagsValueProvider;
159
Fangqiu Su82f23a82024-05-10 19:06:09 +0000160import androidx.test.filters.SmallTest;
shrikar0ca801e2023-11-02 22:25:54 +0000161
shrikar4d9c95f2024-10-24 18:06:53 +0000162import org.junit.Rule;
shrikar0ca801e2023-11-02 22:25:54 +0000163import org.junit.Test;
164import org.junit.runner.RunWith;
165import org.junit.runners.Parameterized;
166
167import java.util.Arrays;
168import java.util.Collection;
169
170@SmallTest
171@RunWith(Parameterized.class)
172public class {0}Test {{
shrikar4d9c95f2024-10-24 18:06:53 +0000173 @Rule
174 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
shrikar0ca801e2023-11-02 22:25:54 +0000175 private final int mJavaConstantValue;
176 private final int mHalConstantValue;
177
178 public {0}Test(int javaConstantValue, int halConstantValue) {{
179 mJavaConstantValue = javaConstantValue;
180 mHalConstantValue = halConstantValue;
181 }}
182
183 @Parameterized.Parameters
184 public static Collection constantValues() {{
185 return Arrays.asList(
shrikar4d9c95f2024-10-24 18:06:53 +0000186 new Object[][] {{""".format(self.fileName, self.flagName))
187 for enum in self.enumNames:
shrikar0ca801e2023-11-02 22:25:54 +0000188 self.outputMsgApiTest.append("""
189 {{
190 android.car.hardware.property.{0}.{1},
191 android.hardware.automotive.vehicle.{0}.{1}
192 }},""".format(self.fileName, enum))
193 self.outputMsgApiTest.append("""
shrikar4d9c95f2024-10-24 18:06:53 +0000194 }});
195 }}
shrikar0ca801e2023-11-02 22:25:54 +0000196
197 @Test
shrikar4d9c95f2024-10-24 18:06:53 +0000198 @RequiresFlagsEnabled({})
199 public void testMatchWithVehicleHal() {{
shrikar0ca801e2023-11-02 22:25:54 +0000200 assertWithMessage("Java constant")
201 .that(mJavaConstantValue)
202 .isEqualTo(mHalConstantValue);
shrikar4d9c95f2024-10-24 18:06:53 +0000203 }}
204}}
205""".format(self.flagName))
shrikar0ca801e2023-11-02 22:25:54 +0000206
207 self.outputMsgCtsTest = []
208 self.outputMsgCtsTest.append(LICENSE)
209 self.outputMsgCtsTest.append("""
210package android.car.cts;
211
shrikar4d9c95f2024-10-24 18:06:53 +0000212import static android.car.feature.Flags.{1};
213
shrikar0ca801e2023-11-02 22:25:54 +0000214import static com.google.common.truth.Truth.assertThat;
215import static com.google.common.truth.Truth.assertWithMessage;
216
217import android.car.cts.utils.VehiclePropertyUtils;
218import android.car.hardware.property.{0};
shrikar4d9c95f2024-10-24 18:06:53 +0000219import android.platform.test.annotations.RequiresFlagsEnabled;
220import android.platform.test.flag.junit.CheckFlagsRule;
221import android.platform.test.flag.junit.DeviceFlagsValueProvider;
shrikar0ca801e2023-11-02 22:25:54 +0000222
shrikar4d9c95f2024-10-24 18:06:53 +0000223import org.junit.Rule;
shrikar0ca801e2023-11-02 22:25:54 +0000224import org.junit.Test;
225
226import java.util.List;
227
228public class {0}Test {{
shrikar4d9c95f2024-10-24 18:06:53 +0000229 @Rule
230 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
shrikar0ca801e2023-11-02 22:25:54 +0000231
232 @Test
shrikar4d9c95f2024-10-24 18:06:53 +0000233 @RequiresFlagsEnabled({1})
234 public void testToString() {{""".format(self.fileName, self.flagName))
235 for enum in self.enumNames:
shrikar0ca801e2023-11-02 22:25:54 +0000236 self.outputMsgCtsTest.append("""
237 assertThat({0}.toString(
238 {0}.{1}))
239 .isEqualTo("{1}");""".format(self.fileName, enum))
shrikar4d9c95f2024-10-24 18:06:53 +0000240 max_enum_value = len(self.enums)
shrikar0ca801e2023-11-02 22:25:54 +0000241 self.outputMsgCtsTest.append("""
242 assertThat({0}.toString({1})).isEqualTo("{2}");
243 assertThat({0}.toString(12)).isEqualTo("0xc");
244 }}
245
246 @Test
shrikar4d9c95f2024-10-24 18:06:53 +0000247 @RequiresFlagsEnabled({4})
shrikar0ca801e2023-11-02 22:25:54 +0000248 public void testAll{0}sAreMappedInToString() {{
249 List<Integer> {3}s =
250 VehiclePropertyUtils.getIntegersFromDataEnums({0}.class);
251 for (Integer {3} : {3}s) {{
252 String {3}String = {0}.toString(
253 {3});
254 assertWithMessage("%s starts with 0x", {3}String).that(
255 {3}String.startsWith("0x")).isFalse();
256 }}
257 }}
258}}
shrikar4d9c95f2024-10-24 18:06:53 +0000259""".format(self.fileName, len(self.enums), hex(len(self.enums)), self.lowerFileName, self.flagName))
shrikar0ca801e2023-11-02 22:25:54 +0000260
261def main():
shrikar4d9c95f2024-10-24 18:06:53 +0000262 if len(sys.argv) != 3:
263 print("Usage: {} enum_aidl_file ALL_CAPS_FLAG_NAME".format(sys.argv[0]))
shrikar0ca801e2023-11-02 22:25:54 +0000264 sys.exit(1)
265 print("WARNING: This file only generates the base enum values in the framework layer. The "
266 + "generated files must be reviewed by you and edited if any additional changes are "
267 + "required. The java enum file should be updated with app-developer facing "
268 + "documentation, the @FlaggedApi tag for the new API, and with the @SystemApi tag if "
269 + "the new property is system API")
270 file_path = sys.argv[1]
271 file_name = file_path.split('/')[-1][:-5]
shrikar4d9c95f2024-10-24 18:06:53 +0000272 flag_name = sys.argv[2]
273 parser = EnumParser(file_path, file_name, flag_name)
shrikar0ca801e2023-11-02 22:25:54 +0000274
275 android_top = os.environ['ANDROID_BUILD_TOP']
276 if not android_top:
277 print('ANDROID_BUILD_TOP is not in environmental variable, please run source and lunch '
278 + 'at the android root')
shrikar4d9c95f2024-10-24 18:06:53 +0000279 sys.exit(1)
shrikar0ca801e2023-11-02 22:25:54 +0000280
281 with open(android_top + "/packages/services/Car/car-lib/src/android/car/hardware/property/"
282 + file_name + ".java", 'w') as f:
283 f.write("".join(parser.outputMsg))
284
285 with open(android_top
286 + "/packages/services/Car/tests/android_car_api_test/src/android/car/apitest/"
287 + file_name + "Test.java", 'w') as f:
288 f.write("".join(parser.outputMsgApiTest))
289
290 with open(android_top + "/cts/tests/tests/car/src/android/car/cts/" + file_name + "Test.java",
291 'w') as f:
292 f.write("".join(parser.outputMsgCtsTest))
293
294if __name__ == "__main__":
Fangqiu Su82f23a82024-05-10 19:06:09 +0000295 main()