blob: 71c8c46feb8bb4b0e174c6e3dcf1b7e7c525ac2c [file] [log] [blame]
Yifan Hongace13de2023-04-28 15:54:04 -07001#!/usr/bin/env 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"""
18Creates the next compatibility matrix.
Yifan Hongace13de2023-04-28 15:54:04 -070019"""
20
21import argparse
22import os
23import pathlib
Justin Yuncb8fb432024-07-19 09:29:45 +090024import re
Yifan Hongace13de2023-04-28 15:54:04 -070025import subprocess
26import textwrap
27
28
29def check_call(*args, **kwargs):
30 print(args)
31 subprocess.check_call(*args, **kwargs)
32
33
34def check_output(*args, **kwargs):
35 print(args)
36 return subprocess.check_output(*args, **kwargs)
37
38
39class Bump(object):
40
41 def __init__(self, cmdline_args):
42 self.top = pathlib.Path(os.environ["ANDROID_BUILD_TOP"])
43 self.interfaces_dir = self.top / "hardware/interfaces"
44
Devin Moore04259162024-02-06 22:52:32 +000045 self.current_level = cmdline_args.current_level
46 self.current_letter = cmdline_args.current_letter
Justin Yuncb8fb432024-07-19 09:29:45 +090047 self.current_version = cmdline_args.platform_version
Devin Moored07ca2b2025-01-13 18:18:12 +000048 self.next_version = cmdline_args.next_platform_version
Yifan Hongace13de2023-04-28 15:54:04 -070049 self.current_module_name = f"framework_compatibility_matrix.{self.current_level}.xml"
50 self.current_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.current_level}.xml"
Devin Moore4be20f72024-02-01 21:39:36 +000051 self.device_module_name = "framework_compatibility_matrix.device.xml"
Yifan Hongace13de2023-04-28 15:54:04 -070052
Devin Moore04259162024-02-06 22:52:32 +000053 self.next_level = cmdline_args.next_level
54 self.next_letter = cmdline_args.next_letter
Devin Moore7ddc2a52025-01-21 20:18:57 +000055 self.current_sdk = cmdline_args.current_sdk
56 self.next_sdk = cmdline_args.next_sdk
Yifan Hongace13de2023-04-28 15:54:04 -070057 self.next_module_name = f"framework_compatibility_matrix.{self.next_level}.xml"
58 self.next_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.next_level}.xml"
59
Yifan Hongace13de2023-04-28 15:54:04 -070060 def run(self):
61 self.bump_kernel_configs()
62 self.copy_matrix()
63 self.edit_android_bp()
Justin Yuncb8fb432024-07-19 09:29:45 +090064 self.bump_libvintf()
Devin Moorea4155ed2025-01-17 23:31:46 +000065 self.bump_libvts_vintf()
Devin Moore7ddc2a52025-01-21 20:18:57 +000066 self.bump_cuttlefish()
Yifan Hongace13de2023-04-28 15:54:04 -070067
Yifan Hongace13de2023-04-28 15:54:04 -070068 def bump_kernel_configs(self):
69 check_call([
70 self.top / "kernel/configs/tools/bump.py",
Justin Yuncb8fb432024-07-19 09:29:45 +090071 self.current_letter.lower(),
72 self.next_letter.lower(),
Yifan Hongace13de2023-04-28 15:54:04 -070073 ])
74
75 def copy_matrix(self):
Devin Moore4be20f72024-02-01 21:39:36 +000076 with open(self.current_xml) as f_current, open(self.next_xml, "w") as f_next:
77 f_next.write(f_current.read().replace(f"level=\"{self.current_level}\"", f"level=\"{self.next_level}\""))
Yifan Hongace13de2023-04-28 15:54:04 -070078
79 def edit_android_bp(self):
80 android_bp = self.interfaces_dir / "compatibility_matrices/Android.bp"
81
82 with open(android_bp, "r+") as f:
83 if self.next_module_name not in f.read():
84 f.seek(0, 2) # end of file
85 f.write("\n")
86 f.write(
87 textwrap.dedent(f"""\
88 vintf_compatibility_matrix {{
89 name: "{self.next_module_name}",
90 }}
91 """))
92
93 next_kernel_configs = check_output(
94 """grep -rh name: | sed -E 's/^.*"(.*)".*/\\1/g'""",
95 cwd=self.top / "kernel/configs" /
Justin Yuncb8fb432024-07-19 09:29:45 +090096 self.next_letter.lower(),
Yifan Hongace13de2023-04-28 15:54:04 -070097 text=True,
98 shell=True,
99 ).splitlines()
100 print(next_kernel_configs)
101
102 check_call([
103 "bpmodify", "-w", "-m", self.next_module_name, "-property", "stem",
104 "-str", self.next_xml.name, android_bp
105 ])
106
107 check_call([
108 "bpmodify", "-w", "-m", self.next_module_name, "-property", "srcs",
109 "-a",
110 self.next_xml.relative_to(android_bp.parent), android_bp
111 ])
112
113 check_call([
114 "bpmodify", "-w", "-m", self.next_module_name, "-property",
115 "kernel_configs", "-a", " ".join(next_kernel_configs), android_bp
116 ])
117
Devin Moorefaa5b0e2025-01-08 18:36:14 +0000118 # Replace the phony module's product_variables entry to add the new FCM
119 # to the development targets (trunk* configs).
Devin Mooref28b6952024-09-12 18:09:21 +0000120 lines = []
121 with open(android_bp) as f:
122 for line in f:
Devin Mooref28b6952024-09-12 18:09:21 +0000123 if f" \"{self.current_module_name}\",\n" in line:
124 lines.append(f" \"{self.next_module_name}\",\n")
125 else:
126 lines.append(line)
127
128 with open(android_bp, "w") as f:
129 f.write("".join(lines))
130
Justin Yuncb8fb432024-07-19 09:29:45 +0900131 def bump_libvintf(self):
132 if not self.current_version:
133 print("Skip libvintf update...")
134 return
135 try:
136 check_call(["grep", "-h",
Devin Moored07ca2b2025-01-13 18:18:12 +0000137 f"{self.next_letter.upper()} = {self.next_level}",
Devin Moore6d9b76b2025-01-13 18:09:14 +0000138 f"{self.top}/system/libvintf/include/vintf/Level.h"])
Justin Yuncb8fb432024-07-19 09:29:45 +0900139 except subprocess.CalledProcessError:
140 print("Adding new API level to libvintf")
Devin Moore6d9b76b2025-01-13 18:09:14 +0000141 add_lines_above(f"{self.top}/system/libvintf/analyze_matrix/analyze_matrix.cpp",
Justin Yuncb8fb432024-07-19 09:29:45 +0900142 " case Level::UNSPECIFIED:",
143 textwrap.indent(textwrap.dedent(f"""\
Devin Moored07ca2b2025-01-13 18:18:12 +0000144 case Level::{self.next_letter.upper()}:
145 return "Android {self.next_version} ({self.next_letter.upper()})";"""),
Justin Yuncb8fb432024-07-19 09:29:45 +0900146 " "*2))
Devin Moore6d9b76b2025-01-13 18:09:14 +0000147 add_lines_above(f"{self.top}/system/libvintf/include/vintf/Level.h",
Justin Yuncb8fb432024-07-19 09:29:45 +0900148 " // To add new values:",
Devin Moored07ca2b2025-01-13 18:18:12 +0000149 f" {self.next_letter.upper()} = {self.next_level},")
Devin Moore6d9b76b2025-01-13 18:09:14 +0000150 add_lines_above(f"{self.top}/system/libvintf/include/vintf/Level.h",
Justin Yuncb8fb432024-07-19 09:29:45 +0900151 " Level::UNSPECIFIED,",
Devin Moored07ca2b2025-01-13 18:18:12 +0000152 f" Level::{self.next_letter.upper()},")
Devin Moore6d9b76b2025-01-13 18:09:14 +0000153 add_lines_above(f"{self.top}/system/libvintf/RuntimeInfo.cpp",
Justin Yuncb8fb432024-07-19 09:29:45 +0900154 " // Add more levels above this line.",
155 textwrap.indent(textwrap.dedent(f"""\
Devin Moored07ca2b2025-01-13 18:18:12 +0000156 case {self.next_version}: {{
157 ret = Level::{self.next_letter.upper()};
Justin Yuncb8fb432024-07-19 09:29:45 +0900158 }} break;"""),
159 " "*3))
160
Devin Moorea4155ed2025-01-17 23:31:46 +0000161 def bump_libvts_vintf(self):
162 if not self.current_version:
163 print("Skip libvts_vintf update...")
164 return
165 try:
166 check_call(["grep", "-h",
167 f"{self.next_level}, Level::{self.next_letter.upper()}",
168 f"{self.top}/test/vts-testcase/hal/treble/vintf/libvts_vintf_test_common/common.cpp"])
169 print("libvts_vintf is already up-to-date")
170 except subprocess.CalledProcessError:
171 print("Adding new API level to libvts_vintf")
172 add_lines_below(f"{self.top}/test/vts-testcase/hal/treble/vintf/libvts_vintf_test_common/common.cpp",
173 f" {{{self.current_level}, Level::{self.current_letter.upper()}}},",
174 f" {{{self.next_level}, Level::{self.next_letter.upper()}}},\n")
Justin Yuncb8fb432024-07-19 09:29:45 +0900175
Devin Moore7ddc2a52025-01-21 20:18:57 +0000176 def bump_cuttlefish(self):
177 if not self.next_sdk:
178 print("Skip Cuttlefish update...")
179 return
180 cf_mk_file = f"{self.top}/device/google/cuttlefish/shared/device.mk"
181 try:
182 check_call(["grep", "-h",
183 f"PRODUCT_SHIPPING_API_LEVEL := {self.next_sdk}",
184 cf_mk_file])
185 print("Cuttlefish is already up-to-date")
186 except subprocess.CalledProcessError:
187 print("Bumping Cuttlefish to the next SHIPPING_API_LEVEL")
188 final_lines = []
189 with open(cf_mk_file, 'r+') as f:
190 for line in f:
191 if f"PRODUCT_SHIPPING_API_LEVEL := {self.current_sdk}" in line:
192 final_lines.append(f"PRODUCT_SHIPPING_API_LEVEL := {self.next_sdk}\n")
193 elif line.startswith("PRODUCT_SHIPPING_API_LEVEL :="):
194 # this is the previous SDK level.
195 final_lines.append(f"PRODUCT_SHIPPING_API_LEVEL := {self.current_sdk}\n")
196 else:
197 final_lines.append(line)
198 f.seek(0)
199 f.write("".join(final_lines))
200 f.truncate()
201 final_lines = []
202 with open(f"{self.top}/device/google/cuttlefish/shared/config/previous_manifest.xml", 'r+') as f:
203 for line in f:
204 if "target-level=" in line:
205 final_lines.append(f"<manifest version=\"1.0\" type=\"device\" target-level=\"{self.current_level}\">\n")
206 else:
207 final_lines.append(line)
208 f.seek(0)
209 f.write("".join(final_lines))
210 f.truncate()
211
212 final_lines = []
213 with open(f"{self.top}/device/google/cuttlefish/shared/config/manifest.xml", 'r+') as f:
214 for line in f:
215 if "target-level=" in line:
216 final_lines.append(f"<manifest version=\"1.0\" type=\"device\" target-level=\"{self.next_level}\">\n")
217 else:
218 final_lines.append(line)
219 f.seek(0)
220 f.write("".join(final_lines))
221 f.truncate()
222
Justin Yuncb8fb432024-07-19 09:29:45 +0900223def add_lines_above(file, pattern, lines):
224 with open(file, 'r+') as f:
225 text = f.read()
226 split_text = re.split(rf"\n{pattern}\n", text)
227 if len(split_text) != 2:
228 # Only one pattern must be found, otherwise the source must be
229 # changed unexpectedly.
230 raise Exception(
231 f'Pattern "{pattern}" not found or multiple patterns found in {file}')
232 f.seek(0)
233 f.write(f"\n{lines}\n{pattern}\n".join(split_text))
234 f.truncate()
235
Devin Moorea4155ed2025-01-17 23:31:46 +0000236def add_lines_below(file, pattern, lines):
237 final_lines = []
238 with open(file, 'r+') as f:
239 for line in f:
240 final_lines.append(line)
241 if pattern in line:
242 final_lines.append(lines)
243 f.seek(0)
244 f.write("".join(final_lines))
245 f.truncate()
Yifan Hongace13de2023-04-28 15:54:04 -0700246
247def main():
248 parser = argparse.ArgumentParser(description=__doc__)
Devin Moore04259162024-02-06 22:52:32 +0000249 parser.add_argument("current_level",
Yifan Hongace13de2023-04-28 15:54:04 -0700250 type=str,
Justin Yuncb8fb432024-07-19 09:29:45 +0900251 help="VINTF level of the current version (e.g. 202404)")
Devin Moore04259162024-02-06 22:52:32 +0000252 parser.add_argument("next_level",
Yifan Hongace13de2023-04-28 15:54:04 -0700253 type=str,
Justin Yuncb8fb432024-07-19 09:29:45 +0900254 help="VINTF level of the next version (e.g. 202504)")
Devin Moore04259162024-02-06 22:52:32 +0000255 parser.add_argument("current_letter",
256 type=str,
Devin Moore9434f192024-12-17 17:52:31 +0000257 help="Letter of the API level of the current version (e.g. b)")
Devin Moore04259162024-02-06 22:52:32 +0000258 parser.add_argument("next_letter",
259 type=str,
Devin Moore9434f192024-12-17 17:52:31 +0000260 help="Letter of the API level of the next version (e.g. c)")
Justin Yuncb8fb432024-07-19 09:29:45 +0900261 parser.add_argument("platform_version",
262 type=str,
263 nargs="?",
Devin Moored07ca2b2025-01-13 18:18:12 +0000264 help="Current Android release version number (e.g. 16)")
265 parser.add_argument("next_platform_version",
266 type=str,
267 nargs="?",
268 help="Next Android release version number number (e.g. 17)")
Devin Moore7ddc2a52025-01-21 20:18:57 +0000269 parser.add_argument("current_sdk",
270 type=str,
271 nargs="?",
272 help="Version of the current SDK API level (e.g. 36)")
273 parser.add_argument("next_sdk",
274 type=str,
275 nargs="?",
276 help="Version of the next SDK API level(e.g. 37)")
277
Yifan Hongace13de2023-04-28 15:54:04 -0700278 cmdline_args = parser.parse_args()
279
280 Bump(cmdline_args).run()
281
282
283if __name__ == "__main__":
284 main()