diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ecbb16ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +.ruff_cache/ diff --git a/extract_utils_qti/__init__.py b/extract_utils_qti/__init__.py new file mode 100644 index 00000000..3f9643bc --- /dev/null +++ b/extract_utils_qti/__init__.py @@ -0,0 +1,4 @@ +# +# SPDX-FileCopyrightText: 2024 Paranoid Android +# SPDX-License-Identifier: Apache-2.0 +# diff --git a/extract_utils_qti/fixups_blob.py b/extract_utils_qti/fixups_blob.py new file mode 100644 index 00000000..1f85cfaf --- /dev/null +++ b/extract_utils_qti/fixups_blob.py @@ -0,0 +1,35 @@ +# +# SPDX-FileCopyrightText: 2024 Paranoid Android +# SPDX-License-Identifier: Apache-2.0 +# + +from os import remove +from shutil import move +from typing import Self + +from extract_utils.file import File +from extract_utils.fixups_blob import BlobFixupCtx, blob_fixup +from extract_utils.utils import run_cmd + + +class blob_fixup_qti(blob_fixup): + def __init__(self): + super().__init__() + + def zipalign_impl( + self, + ctx: BlobFixupCtx, + file: File, + file_path: str, + *args, + **kwargs, + ): + tmp_path = file_path + '.tmp' + move(file_path, tmp_path) + try: + run_cmd(['zipalign', '-p', '-f', '4', tmp_path, file_path]) + finally: + remove(tmp_path) + + def zipalign(self) -> Self: + return self.call(self.zipalign_impl) diff --git a/extract_utils_qti/fixups_lib.py b/extract_utils_qti/fixups_lib.py new file mode 100644 index 00000000..54d30c00 --- /dev/null +++ b/extract_utils_qti/fixups_lib.py @@ -0,0 +1,8 @@ +# +# SPDX-FileCopyrightText: 2024 Paranoid Android +# SPDX-License-Identifier: Apache-2.0 +# + + +def lib_fixup_vendor_suffix(lib: str, partition: str, *args, **kwargs): + return f'{lib}_{partition}' if partition == 'vendor' else None diff --git a/extract_utils_qti/module.py b/extract_utils_qti/module.py new file mode 100644 index 00000000..ab6a62d8 --- /dev/null +++ b/extract_utils_qti/module.py @@ -0,0 +1,110 @@ +# +# SPDX-FileCopyrightText: 2024 Paranoid Android +# SPDX-License-Identifier: Apache-2.0 +# + +from __future__ import annotations + +from enum import Enum +from os import path +from typing import List, Optional + +from extract_utils.extract import extract_fns_user_type +from extract_utils.fixups_blob import blob_fixups_user_type +from extract_utils.fixups_lib import lib_fixups_user_type +from extract_utils.makefiles import ( + MakefilesCtx, + write_mk_guard_begin, + write_mk_guard_end, + write_mk_header, + write_mk_local_path, +) +from extract_utils.module import ExtractUtilsModule +from extract_utils.tools import android_root + + +class QTIComponentType(str, Enum): + SYSTEM = 'system' + VENDOR = 'vendor' + + +class ExtractUtilsQTIModule(ExtractUtilsModule): + """ + Extension of ExtractUtilsModule for handling Qualcomm components. + Supports both system and vendor components with their specific directory structures. + """ + + def __init__( + self, + component: str, + component_type: QTIComponentType, + vendor: str = 'qcom', + device_rel_path: Optional[str] = None, + blob_fixups: Optional[blob_fixups_user_type] = None, + lib_fixups: Optional[lib_fixups_user_type] = None, + namespace_imports: Optional[List[str]] = None, + extract_fns: Optional[extract_fns_user_type] = None, + check_elf: bool = True, + add_firmware_proprietary_file: bool = False, + add_factory_proprietary_file: bool = False, + add_generated_carriersettings: bool = False, + ): + self.component_type = component_type + self.component = component + self.base_component = component.split('/')[0] + + # Set up paths according to QTI structure + if device_rel_path is None: + device_rel_path = path.join( + 'device', vendor, 'common', component_type, component + ) + + # Initialize base class + super().__init__( + device=self.base_component, + vendor=vendor, + device_rel_path=device_rel_path, + blob_fixups=blob_fixups, + lib_fixups=lib_fixups, + namespace_imports=namespace_imports, + extract_fns=extract_fns, + check_elf=check_elf, + add_firmware_proprietary_file=add_firmware_proprietary_file, + add_factory_proprietary_file=add_factory_proprietary_file, + add_generated_carriersettings=add_generated_carriersettings, + skip_main_proprietary_file=True, + ) + + # Override vendor paths for QTI components + self.vendor_rel_path = path.join( + 'vendor', vendor, 'common', component_type, component + ) + self.vendor_path = path.join(android_root, self.vendor_rel_path) + + # Add proprietary files for this component + self.add_proprietary_file('proprietary-files.txt') + + def write_makefiles(self, legacy: bool, extract_factory: bool): + """Write Android.bp, Android.mk and other makefiles with QTI-specific guards.""" + with MakefilesCtx.from_paths( + legacy, + path.join(self.vendor_path, 'Android.bp'), + path.join(self.vendor_path, 'Android.mk'), + path.join(self.vendor_path, f'{self.device}-vendor.mk'), + path.join(self.vendor_path, 'BoardConfigVendor.mk'), + ) as ctx: + # Write the headers and LOCAL_PATH + write_mk_header(ctx.mk_out) + write_mk_local_path(ctx.mk_out) + + # Add QTI component guard + write_mk_guard_begin( + 'TARGET_COMMON_QTI_COMPONENTS', + self.component, + ctx.mk_out, + invert=True, + ) + + super().write_makefiles(legacy, extract_factory) + + write_mk_guard_end(ctx.mk_out) diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 00000000..0ddc0152 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,7 @@ +line-length = 80 + +[lint] +extend-select = ['A', 'FA100', 'FA102', 'I'] + +[format] +quote-style = 'single'