- 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
 
- 
      
 - 
        
Save SebaUbuntu/ec053a00a9988eaea091fb1cc1f19324 to your computer and use it in GitHub Desktop.  
| # 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() | 
This is my fqnames, i think it's formated properly https://nekobin.com/nevutivuvu
This is my fqnames, i think it's formated properly https://nekobin.com/nevutivuvu
Should be fixed now
Hey, it doesn't work when there is aidl type entry
example: android.hardware.power.IPower/default (@2)
ye. I too faced it
Hey, it doesn't work when there is
aidltype entry example:android.hardware.power.IPower/default (@2)
Remove those values with braces . It should be android.hardware.power.IPower/default
Hey, it doesn't work when there is
aidltype 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>
    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
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
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 
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
Hey, it doesn't work when there is
aidltype entry example:android.hardware.power.IPower/default (@2)
I try to adapt the code to support versioning aidl here
Feel free to test and suggest better code
Traceback (most recent call last):
File "/home/davi/generate_fcm.py", line 116, in
main()
File "/home/davi/generate_fcm.py", line 104, in main
entry = Entry(fqname)
File "/home/davi/generate_fcm.py", line 47, in init
interface_name, interface_instance = fqname.split("::")[1].split("/", 1)
IndexError: list index out of range