Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 1 | #!/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 | """ |
| 18 | Creates the next compatibility matrix. |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 19 | """ |
| 20 | |
| 21 | import argparse |
| 22 | import os |
| 23 | import pathlib |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 24 | import re |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 25 | import subprocess |
| 26 | import textwrap |
| 27 | |
| 28 | |
| 29 | def check_call(*args, **kwargs): |
| 30 | print(args) |
| 31 | subprocess.check_call(*args, **kwargs) |
| 32 | |
| 33 | |
| 34 | def check_output(*args, **kwargs): |
| 35 | print(args) |
| 36 | return subprocess.check_output(*args, **kwargs) |
| 37 | |
| 38 | |
| 39 | class 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 Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 45 | self.current_level = cmdline_args.current_level |
| 46 | self.current_letter = cmdline_args.current_letter |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 47 | self.current_version = cmdline_args.platform_version |
Devin Moore | d07ca2b | 2025-01-13 18:18:12 +0000 | [diff] [blame] | 48 | self.next_version = cmdline_args.next_platform_version |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 49 | 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 Moore | 4be20f7 | 2024-02-01 21:39:36 +0000 | [diff] [blame] | 51 | self.device_module_name = "framework_compatibility_matrix.device.xml" |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 52 | |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 53 | self.next_level = cmdline_args.next_level |
| 54 | self.next_letter = cmdline_args.next_letter |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 55 | self.next_module_name = f"framework_compatibility_matrix.{self.next_level}.xml" |
| 56 | self.next_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.next_level}.xml" |
| 57 | |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 58 | def run(self): |
| 59 | self.bump_kernel_configs() |
| 60 | self.copy_matrix() |
| 61 | self.edit_android_bp() |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 62 | self.bump_libvintf() |
Devin Moore | a4155ed | 2025-01-17 23:31:46 +0000 | [diff] [blame] | 63 | self.bump_libvts_vintf() |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 64 | |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 65 | def bump_kernel_configs(self): |
| 66 | check_call([ |
| 67 | self.top / "kernel/configs/tools/bump.py", |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 68 | self.current_letter.lower(), |
| 69 | self.next_letter.lower(), |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 70 | ]) |
| 71 | |
| 72 | def copy_matrix(self): |
Devin Moore | 4be20f7 | 2024-02-01 21:39:36 +0000 | [diff] [blame] | 73 | with open(self.current_xml) as f_current, open(self.next_xml, "w") as f_next: |
| 74 | f_next.write(f_current.read().replace(f"level=\"{self.current_level}\"", f"level=\"{self.next_level}\"")) |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 75 | |
| 76 | def edit_android_bp(self): |
| 77 | android_bp = self.interfaces_dir / "compatibility_matrices/Android.bp" |
| 78 | |
| 79 | with open(android_bp, "r+") as f: |
| 80 | if self.next_module_name not in f.read(): |
| 81 | f.seek(0, 2) # end of file |
| 82 | f.write("\n") |
| 83 | f.write( |
| 84 | textwrap.dedent(f"""\ |
| 85 | vintf_compatibility_matrix {{ |
| 86 | name: "{self.next_module_name}", |
| 87 | }} |
| 88 | """)) |
| 89 | |
| 90 | next_kernel_configs = check_output( |
| 91 | """grep -rh name: | sed -E 's/^.*"(.*)".*/\\1/g'""", |
| 92 | cwd=self.top / "kernel/configs" / |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 93 | self.next_letter.lower(), |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 94 | text=True, |
| 95 | shell=True, |
| 96 | ).splitlines() |
| 97 | print(next_kernel_configs) |
| 98 | |
| 99 | check_call([ |
| 100 | "bpmodify", "-w", "-m", self.next_module_name, "-property", "stem", |
| 101 | "-str", self.next_xml.name, android_bp |
| 102 | ]) |
| 103 | |
| 104 | check_call([ |
| 105 | "bpmodify", "-w", "-m", self.next_module_name, "-property", "srcs", |
| 106 | "-a", |
| 107 | self.next_xml.relative_to(android_bp.parent), android_bp |
| 108 | ]) |
| 109 | |
| 110 | check_call([ |
| 111 | "bpmodify", "-w", "-m", self.next_module_name, "-property", |
| 112 | "kernel_configs", "-a", " ".join(next_kernel_configs), android_bp |
| 113 | ]) |
| 114 | |
Devin Moore | faa5b0e | 2025-01-08 18:36:14 +0000 | [diff] [blame] | 115 | # Replace the phony module's product_variables entry to add the new FCM |
| 116 | # to the development targets (trunk* configs). |
Devin Moore | f28b695 | 2024-09-12 18:09:21 +0000 | [diff] [blame] | 117 | lines = [] |
| 118 | with open(android_bp) as f: |
| 119 | for line in f: |
Devin Moore | f28b695 | 2024-09-12 18:09:21 +0000 | [diff] [blame] | 120 | if f" \"{self.current_module_name}\",\n" in line: |
| 121 | lines.append(f" \"{self.next_module_name}\",\n") |
| 122 | else: |
| 123 | lines.append(line) |
| 124 | |
| 125 | with open(android_bp, "w") as f: |
| 126 | f.write("".join(lines)) |
| 127 | |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 128 | def bump_libvintf(self): |
| 129 | if not self.current_version: |
| 130 | print("Skip libvintf update...") |
| 131 | return |
| 132 | try: |
| 133 | check_call(["grep", "-h", |
Devin Moore | d07ca2b | 2025-01-13 18:18:12 +0000 | [diff] [blame] | 134 | f"{self.next_letter.upper()} = {self.next_level}", |
Devin Moore | 6d9b76b | 2025-01-13 18:09:14 +0000 | [diff] [blame] | 135 | f"{self.top}/system/libvintf/include/vintf/Level.h"]) |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 136 | except subprocess.CalledProcessError: |
| 137 | print("Adding new API level to libvintf") |
Devin Moore | 6d9b76b | 2025-01-13 18:09:14 +0000 | [diff] [blame] | 138 | add_lines_above(f"{self.top}/system/libvintf/analyze_matrix/analyze_matrix.cpp", |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 139 | " case Level::UNSPECIFIED:", |
| 140 | textwrap.indent(textwrap.dedent(f"""\ |
Devin Moore | d07ca2b | 2025-01-13 18:18:12 +0000 | [diff] [blame] | 141 | case Level::{self.next_letter.upper()}: |
| 142 | return "Android {self.next_version} ({self.next_letter.upper()})";"""), |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 143 | " "*2)) |
Devin Moore | 6d9b76b | 2025-01-13 18:09:14 +0000 | [diff] [blame] | 144 | add_lines_above(f"{self.top}/system/libvintf/include/vintf/Level.h", |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 145 | " // To add new values:", |
Devin Moore | d07ca2b | 2025-01-13 18:18:12 +0000 | [diff] [blame] | 146 | f" {self.next_letter.upper()} = {self.next_level},") |
Devin Moore | 6d9b76b | 2025-01-13 18:09:14 +0000 | [diff] [blame] | 147 | add_lines_above(f"{self.top}/system/libvintf/include/vintf/Level.h", |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 148 | " Level::UNSPECIFIED,", |
Devin Moore | d07ca2b | 2025-01-13 18:18:12 +0000 | [diff] [blame] | 149 | f" Level::{self.next_letter.upper()},") |
Devin Moore | 6d9b76b | 2025-01-13 18:09:14 +0000 | [diff] [blame] | 150 | add_lines_above(f"{self.top}/system/libvintf/RuntimeInfo.cpp", |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 151 | " // Add more levels above this line.", |
| 152 | textwrap.indent(textwrap.dedent(f"""\ |
Devin Moore | d07ca2b | 2025-01-13 18:18:12 +0000 | [diff] [blame] | 153 | case {self.next_version}: {{ |
| 154 | ret = Level::{self.next_letter.upper()}; |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 155 | }} break;"""), |
| 156 | " "*3)) |
| 157 | |
Devin Moore | a4155ed | 2025-01-17 23:31:46 +0000 | [diff] [blame] | 158 | def bump_libvts_vintf(self): |
| 159 | if not self.current_version: |
| 160 | print("Skip libvts_vintf update...") |
| 161 | return |
| 162 | try: |
| 163 | check_call(["grep", "-h", |
| 164 | f"{self.next_level}, Level::{self.next_letter.upper()}", |
| 165 | f"{self.top}/test/vts-testcase/hal/treble/vintf/libvts_vintf_test_common/common.cpp"]) |
| 166 | print("libvts_vintf is already up-to-date") |
| 167 | except subprocess.CalledProcessError: |
| 168 | print("Adding new API level to libvts_vintf") |
| 169 | add_lines_below(f"{self.top}/test/vts-testcase/hal/treble/vintf/libvts_vintf_test_common/common.cpp", |
| 170 | f" {{{self.current_level}, Level::{self.current_letter.upper()}}},", |
| 171 | f" {{{self.next_level}, Level::{self.next_letter.upper()}}},\n") |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 172 | |
| 173 | def add_lines_above(file, pattern, lines): |
| 174 | with open(file, 'r+') as f: |
| 175 | text = f.read() |
| 176 | split_text = re.split(rf"\n{pattern}\n", text) |
| 177 | if len(split_text) != 2: |
| 178 | # Only one pattern must be found, otherwise the source must be |
| 179 | # changed unexpectedly. |
| 180 | raise Exception( |
| 181 | f'Pattern "{pattern}" not found or multiple patterns found in {file}') |
| 182 | f.seek(0) |
| 183 | f.write(f"\n{lines}\n{pattern}\n".join(split_text)) |
| 184 | f.truncate() |
| 185 | |
Devin Moore | a4155ed | 2025-01-17 23:31:46 +0000 | [diff] [blame] | 186 | def add_lines_below(file, pattern, lines): |
| 187 | final_lines = [] |
| 188 | with open(file, 'r+') as f: |
| 189 | for line in f: |
| 190 | final_lines.append(line) |
| 191 | if pattern in line: |
| 192 | final_lines.append(lines) |
| 193 | f.seek(0) |
| 194 | f.write("".join(final_lines)) |
| 195 | f.truncate() |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 196 | |
| 197 | def main(): |
| 198 | parser = argparse.ArgumentParser(description=__doc__) |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 199 | parser.add_argument("current_level", |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 200 | type=str, |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 201 | help="VINTF level of the current version (e.g. 202404)") |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 202 | parser.add_argument("next_level", |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 203 | type=str, |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 204 | help="VINTF level of the next version (e.g. 202504)") |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 205 | parser.add_argument("current_letter", |
| 206 | type=str, |
Devin Moore | 9434f19 | 2024-12-17 17:52:31 +0000 | [diff] [blame] | 207 | help="Letter of the API level of the current version (e.g. b)") |
Devin Moore | 0425916 | 2024-02-06 22:52:32 +0000 | [diff] [blame] | 208 | parser.add_argument("next_letter", |
| 209 | type=str, |
Devin Moore | 9434f19 | 2024-12-17 17:52:31 +0000 | [diff] [blame] | 210 | help="Letter of the API level of the next version (e.g. c)") |
Justin Yun | cb8fb43 | 2024-07-19 09:29:45 +0900 | [diff] [blame] | 211 | parser.add_argument("platform_version", |
| 212 | type=str, |
| 213 | nargs="?", |
Devin Moore | d07ca2b | 2025-01-13 18:18:12 +0000 | [diff] [blame] | 214 | help="Current Android release version number (e.g. 16)") |
| 215 | parser.add_argument("next_platform_version", |
| 216 | type=str, |
| 217 | nargs="?", |
| 218 | help="Next Android release version number number (e.g. 17)") |
Yifan Hong | ace13de | 2023-04-28 15:54:04 -0700 | [diff] [blame] | 219 | cmdline_args = parser.parse_args() |
| 220 | |
| 221 | Bump(cmdline_args).run() |
| 222 | |
| 223 | |
| 224 | if __name__ == "__main__": |
| 225 | main() |