Skip to content

Instantly share code, notes, and snippets.

@SebaUbuntu
Last active November 14, 2024 09:09
Show Gist options
  • Save SebaUbuntu/ec053a00a9988eaea091fb1cc1f19324 to your computer and use it in GitHub Desktop.
Save SebaUbuntu/ec053a00a9988eaea091fb1cc1f19324 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 SM8150 common tree
[email protected]::IGnss/gnss_vendor
[email protected]::ISap/slot2
[email protected]::IImsCmService/qti.ims.connectionmanagerservice
[email protected]::IUceService/com.qualcomm.qti.uceservice
[email protected]::IDisplayColor/default
[email protected]::IDisplayConfig/default
[email protected]::IDisplayPostproc/default
[email protected]::IGoodixFingerprintDaemon/default
[email protected]::IGoodixFingerprintDaemonExt/default
[email protected]::IDisplayModes/default
[email protected]::IPictureAdjustment/default
vendor.lineage.power.IPower/default
[email protected]::IUsbRestrict/default
[email protected]::IFactory/default
[email protected]::IEsePowerManager/default
[email protected]::ILocHidlGnss/gnss_vendor
[email protected]::ILocHidlGnss/gnss_vendor
[email protected]::ILocHidlGnss/gnss_vendor
[email protected]::ILocHidlGnss/gnss_vendor
[email protected]::IAlarm/default
[email protected]::IAudioHalExt/default
[email protected]::IBluetoothAudioProvidersFactory/default
[email protected]::IBluetoothSar/default
[email protected]::IBTConfigStore/default
[email protected]::ICapabilityConfigStore/default
[email protected]::IDataConnection/slot1
[email protected]::IDataConnection/slot2
[email protected]::IQtiAllocator/default
[email protected]::IQtiAllocator/default
[email protected]::IQtiMapper/default
[email protected]::IQtiMapper/default
[email protected]::IDspService/dspservice
[email protected]::IFmHci/default
[email protected]::IIop/default
[email protected]::IPerf/default
[email protected]::IQccvndhal/qccvndhal
[email protected]::IQSEECom/default
[email protected]::IAppConnector/default
[email protected]::IGPAppConnector/default
[email protected]::IQcRilAudio/slot1
[email protected]::IQcRilAudio/slot2
[email protected]::IImsRadio/imsradio0
[email protected]::IImsRadio/imsradio1
[email protected]::IUimLpa/UimLpa0
[email protected]::IUimLpa/UimLpa1
[email protected]::IQtiOemHook/oemhook0
[email protected]::IQtiOemHook/oemhook1
[email protected]::IQtiRadio/slot1
[email protected]::IQtiRadio/slot2
[email protected]::IQtiRadio/slot1
[email protected]::IQtiRadio/slot2
[email protected]::IUim/Uim0
[email protected]::IUim/Uim1
[email protected]::IUimRemoteServiceClient/uimRemoteClient0
[email protected]::IUimRemoteServiceClient/uimRemoteClient1
[email protected]::IUimRemoteServiceServer/uimRemoteServer0
[email protected]::IUimRemoteServiceServer/uimRemoteServer1
[email protected]::ISensorsCalibrate/default
[email protected]::ISoter/default
[email protected]::ITuiComm/default
[email protected]::IHidlVppService/vppService
[email protected]::IWifiDisplaySessionImageTrack/wifidisplaysessionimagetrack
[email protected]::IRTPService/imsrtpservice
[email protected]::IXiaomiFingerprint/default
[email protected]::IMlipayService/default
# Author: Sebastiano Barezzi <[email protected]>
# Version: 1.3
from re import search
class Version:
def __init__(self, version: str):
self.major, self.minor = version.split(".")
def merge_version(self, version):
if version.minor > self.minor:
self.minor = version.minor
def format(self):
version_str = ' <version>'
if 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"
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)
interface_name, interface_instance = interface_str.split("/")
if 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
versioned_aidl_match = search(" \(@[0-9]+\)$", fqname)
if versioned_aidl_match:
fqname = fqname.removesuffix(versioned_aidl_match.group(0))
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()
@Waxaranai
Copy link

Hey, it doesn't work when there is aidl type entry
example: android.hardware.power.IPower/default (@2)

@RDS-007
Copy link

RDS-007 commented Aug 18, 2022

ye. I too faced it

@karthik1896
Copy link

Hey, it doesn't work when there is aidl type entry example: android.hardware.power.IPower/default (@2)

Remove those values with braces . It should be android.hardware.power.IPower/default

@erikdrozina
Copy link

Hey, it doesn't work when there is aidl type entry example: android.hardware.power.IPower/default (@2)

The ouput is:

<hal format="aidl" optional="true">
    <name>android.hardware.power</name>
    <version>2</version>
    <interface>
        <name>IPower</name>
        <instance>default</instance>
    </interface>
</hal>

@itsxrp
Copy link

itsxrp commented Jan 3, 2023

from: too many arguments
generate_fcm.py: line 6: class: command not found
generate_fcm.py: line 7: syntax error near unexpected token (' generate_fcm.py: line 7: def init(self, version: str):'

any clue why it appearing

@fuyukihidekii
Copy link

from: too many arguments generate_fcm.py: line 6: class: command not found generate_fcm.py: line 7: syntax error near unexpected token (' generate_fcm.py: line 7: def init(self, version: str):'

any clue why it appearing

python3 generate_fcm.py

@s4704
Copy link

s4704 commented Oct 3, 2023

Not work for me: https://gist.github.com/s4704/c8171239a87fefac3f6bb83ab1419f6a
python3 generate_fcm.py Traceback (most recent call last): File "/home/igor/dev/distrib/generate_fcm/generate_fcm.py", line 122, in <module> main() File "/home/igor/dev/distrib/generate_fcm/generate_fcm.py", line 112, in main entries[entry.name].merge_entry(entry) File "/home/igor/dev/distrib/generate_fcm/generate_fcm.py", line 68, in merge_entry raise AssertionError("Different HAL type") AssertionError: Different HAL type

@SharmagRit
Copy link

Traceback (most recent call last):
File "/home/sharmagrit/generate_fcm.py", line 122, in
main()
File "/home/sharmagrit/generate_fcm.py", line 112, in main
entries[entry.name].merge_entry(entry)
File "/home/sharmagrit/generate_fcm.py", line 68, in merge_entry
raise AssertionError("Different HAL type")
AssertionError: Different HAL type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment