Skip to content

Instantly share code, notes, and snippets.

@dodyirawan85
Forked from SebaUbuntu/README.md
Last active October 26, 2025 12:52
Show Gist options
  • Select an option

  • Save dodyirawan85/44738635554494f450d19347aee90d4a to your computer and use it in GitHub Desktop.

Select an option

Save dodyirawan85/44738635554494f450d19347aee90d4a to your computer and use it in GitHub Desktop.
Generate framework compatibility matrix from fqnames

Generate framework compatibility matrix from fqnames

  • Download these 2 files
  • Compile AOSP without fcm from stock and wait for check_vintf to error out
  • Delete Python prefix from all lines (e.g. checkvintf E 06-24 00:30:22 49120 49120 check_vintf.cpp:554])
  • Paste the result in fqnames.txt
  • Launch the script
# Add here a list of fqname
# You can get it if you try to build AOSP without a fcm
# check_vintf will print a list of needed entries
# This currently works with AIDL and HIDL
# Here an example from Xiaomi SM8650 common tree
[email protected]::IComponentStore/dolby
com.fingerprints.extension3.IFingerprintNavigation/default (@1)
com.fingerprints.extension3.IFingerprintSensorTest/default (@1)
com.fingerprints.fpc.extension.IFpcExtension/default (@1)
vendor.qti.sla.service.ISlaAIDLService/default (@1)
vendor.xiaomi.hardware.aidlbgservice.IBGService/default (@1)
vendor.xiaomi.hardware.aon.IAlwaysOn/miaonservicehal (@1)
vendor.xiaomi.hardware.fingerprintextension.IXiaomiFingerprint/default (@1)
vendor.xiaomi.hardware.fx.tunnel.IMiFxTunnel/default (@1)
vendor.xiaomi.hardware.micharge.IMiCharge/default (@2)
vendor.xiaomi.hardware.quickcamera.IQuickCameraService/default (@1)
vendor.xiaomi.hw.touchfeature.ITouchFeature/default (@1)
# Author: Sebastiano Barezzi <[email protected]>
# Version: 1.3
from re import match, search
class Version:
def __init__(self, version: str):
self.major = version
self.minor = None
if "." in version:
self.major, self.minor = version.split(".")
def merge_version(self, version):
if version.minor is None or self.minor is None:
return
if version.minor > self.minor:
self.minor = version.minor
def format(self):
version_str = ' <version>'
if self.minor is None:
version_str += f"{self.major}"
elif int(self.minor) > 0:
version_str += f"{self.major}.0-{self.minor}"
else:
version_str += f"{self.major}.{self.minor}"
version_str += '</version>\n'
return version_str
class Interface:
def __init__(self, name: str, instance: str):
self.name = name
self.instances = [instance]
def merge_interface(self, interface):
for instance in interface.instances:
if not instance in self.instances:
self.instances += [instance]
def format(self):
interface_str = ' <interface>\n'
interface_str += f' <name>{self.name}</name>\n'
for instance in self.instances:
interface_str += f' <instance>{instance}</instance>\n'
interface_str += ' </interface>\n'
return interface_str
class Entry:
def __init__(self, fqname: str):
self.type = "HIDL" if "::" in fqname else "AIDL"
version = 0
if self.type == "HIDL":
self.name, version = fqname.split("::")[0].split("@")
interface_name, interface_instance = fqname.split("::")[1].split("/", 1)
else:
self.name, interface_str = fqname.rsplit(".", 1)
if "@" in interface_str:
interface_str, version = match(r"^(.*?)\s+\(@([0-9]+)\)$", interface_str).groups()
interface_name, interface_instance = interface_str.split("/")
if version != '1' or self.type == "HIDL":
version = Version(version)
self.versions = {version.major: version}
else:
self.versions = {}
interface = Interface(interface_name, interface_instance)
self.interfaces = {interface.name: interface}
def merge_entry(self, entry):
if entry.name != self.name:
raise AssertionError("Different entry name")
if entry.type != self.type:
raise AssertionError("Different HAL type")
for version_major, version in entry.versions.items():
if version_major in self.versions:
self.versions[version_major].merge_version(version)
else:
self.versions[version_major] = version
for interface_name, interface in entry.interfaces.items():
if interface_name in self.interfaces:
self.interfaces[interface_name].merge_interface(interface)
else:
self.interfaces[interface_name] = interface
pass
def format(self):
entry_str = f'<hal format="{self.type.lower()}" optional="true">\n'
entry_str += f' <name>{self.name}</name>\n'
for version in self.versions.values():
entry_str += version.format()
for interface in self.interfaces.values():
entry_str += interface.format()
entry_str += '</hal>\n'
return entry_str
def main():
entries = {}
for fqname in open("fqnames.txt").readlines():
fqname = fqname.strip()
if fqname == "" or fqname[0] == '#':
continue
entry = Entry(fqname)
if entry.name in entries:
entries[entry.name].merge_entry(entry)
else:
entries[entry.name] = entry
fcms = [entry.format() for entry in entries.values()]
print("".join(fcms))
return
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment