diff --git a/cmds/Android.bp b/cmds/Android.bp new file mode 100644 index 0000000..7daf55e --- /dev/null +++ b/cmds/Android.bp @@ -0,0 +1,12 @@ +cc_binary { + name: "aguiledbeltctl", + system_ext_specific: true, + srcs: [ + "aguiledbeltctl.cpp", + ], + shared_libs: [ + "vendor.mediatek.hardware.aguiledbelt@1.0", + "libutils", + "libhidlbase", + ], +} diff --git a/cmds/aguiledbeltctl.cpp b/cmds/aguiledbeltctl.cpp new file mode 100644 index 0000000..9d8b031 --- /dev/null +++ b/cmds/aguiledbeltctl.cpp @@ -0,0 +1,62 @@ +// vim: expandtab tabstop=4 shiftwidth=4 +#include +#include + +#include +#include + +using namespace ::vendor::mediatek::hardware::aguiledbelt::V1_0; + +void print_usage() { + std::cerr << "Usage: aguiledbeltctl " << std::endl; + std::cerr << " aguiledbeltctl clear" << std::endl; + std::cerr << std::endl; + std::cerr << " should be a binary string where each bit (0 or 1) corresponds to the ON state of each physical light belt" << std::endl; +} + +int main(int argc, char **argv) { + auto service = IAguiLedBeltLight::getService(); + + if (argc <= 1) { + print_usage(); + return -1; + } + + std::string arg1(argv[1]); + + if (arg1 == "clear") { + service->setLedBeltAlwaysOnState(0, 0, 0, false); + return 0; + } + + uint32_t light_id = std::stoi(std::string(argv[1]), nullptr, 2); + + if (light_id > 31) { + std::cerr << "First argument should be a bit field with each bit corresponding to one physical light belt" << std::endl; + return 0; + } + + if (argc < 6) { + print_usage(); + return -1; + } + + uint32_t r = std::stoi(std::string(argv[2])); + uint32_t g = std::stoi(std::string(argv[3])); + uint32_t b = std::stoi(std::string(argv[4])); + + if (r > 255 || g > 255 || b > 255) { + std::cerr << "Color channels must be bewteen 0 and 255" << std::endl; + return -1; + } + + uint32_t brightness = std::stoi(std::string(argv[5])); + + if (brightness > 100) { + std::cerr << "Brightness must be between 0 and 100" << std::endl; + return -1; + } + + service->setLedBeltAlwaysOnState(light_id, (r << 16) + (g << 8) + b, brightness, false); + return 0; +} diff --git a/device.mk b/device.mk index 2d5a5d1..80350e2 100644 --- a/device.mk +++ b/device.mk @@ -48,6 +48,10 @@ PRODUCT_COPY_FILES += \ PRODUCT_PACKAGES += \ OpenEUICC +# Telecom API (Phone Accounts, etc.) +PRODUCT_COPY_FILES += \ + frameworks/native/data/etc/android.software.telecom.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/permissions/android.software.telecom.xml + # vendor/foss include vendor/foss/foss.mk @@ -67,10 +71,18 @@ PRODUCT_PACKAGES += \ PRODUCT_COPY_FILES += \ device/peter/gsi/bluetooth/audio/config/sysbta_audio_policy_configuration.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/sysbta_audio_policy_configuration.xml \ - device/peter/gsi/bluetooth/audio/config/sysbta_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUTY_SYSTEM)/etc/sysbta_audio_policy_configuration_7_0.xml + device/peter/gsi/bluetooth/audio/config/sysbta_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/sysbta_audio_policy_configuration_7_0.xml + +# QcRilAm service for QCOM in-call audio (packages/apps/QcRilAm) +PRODUCT_PACKAGES += \ + QcRilAm # Enable ro.adb.secure on userdebug and user ifeq (,$(filter eng,$(TARGET_BUILD_VARIANT))) PRODUCT_SYSTEM_EXT_PROPERTIES += \ ro.adb.secure=1 endif + +# Custom commands +PRODUCT_PACKAGES += \ + aguiledbeltctl diff --git a/init/Android.bp b/init/Android.bp index 3bfacd2..efdda28 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -4,14 +4,17 @@ cc_binary { srcs: [ "init_gsi.cpp", "quirks.cpp", + + // Per-device / SoC preset properties + "quirks/preset_props.cpp", // SoC-specific quirks "quirks/soc/mtk_ril.cpp", + "quirks/soc/mtk_trustkernel.cpp", "quirks/soc/caf_audio.cpp", // Device-specific quirks "quirks/device/unihertz_keylayout.cpp", - "quirks/device/ulefone_power_armor_13.cpp", ], shared_libs: ["libbase", "libdl", "liblog", "libutils"], static_libs: ["libresetprop", "libc++fs"], diff --git a/init/init_gsi.cpp b/init/init_gsi.cpp index d1fd08a..5e2f3cd 100644 --- a/init/init_gsi.cpp +++ b/init/init_gsi.cpp @@ -9,9 +9,6 @@ using namespace android; using namespace std; -// From libresetprop -extern int setprop(const char *name, const char *value, bool trigger); - void override_ro_prop(string prefix, string source, string postfix, string value) { if (value.length() == 0) return; diff --git a/init/quirks.cpp b/init/quirks.cpp index d3eab5b..7cb6aa6 100644 --- a/init/quirks.cpp +++ b/init/quirks.cpp @@ -3,6 +3,7 @@ #include "quirks.h" +#include #include #include #include @@ -11,6 +12,19 @@ #include #include +// Utility function used with preset properties +void __set_props(int _ignore, ...) { + va_list args; + va_start(args, _ignore); + + while (auto key = va_arg(args, const char*)) { + auto val = va_arg(args, const char*); + setprop(key, val, true); + } + + va_end(args); +} + // Default constructor to add self to the loaded list of quirks DeviceQuirk::DeviceQuirk() { Quirks::Add(this); diff --git a/init/quirks.h b/init/quirks.h index 812346f..c0c1b66 100644 --- a/init/quirks.h +++ b/init/quirks.h @@ -8,6 +8,9 @@ #include #include +// From libresetprop +extern int setprop(const char *name, const char *value, bool trigger); + #define PROP_STARTS_WITH(prop, prefix) \ (android::base::GetProperty(prop, "").rfind(prefix, 0) == 0) #define FP_STARTS_WITH(prefix) \ @@ -37,6 +40,20 @@ public: #define LOAD_QUIRK(NAME) \ static NAME _ignored; +void __set_props(int _ignore, ...); + +#define CONCAT_(x,y) x##y +#define CONCAT(x,y) CONCAT_(x,y) +#define UNIQUE_NAME CONCAT(_unique_name_, __LINE__) + +#define PRESET_PROPS(cond, ...) \ + class UNIQUE_NAME: DeviceQuirk { \ + public: \ + bool ShouldRun() { return cond; } \ + void Run() { __set_props(0, __VA_ARGS__, NULL); } \ + }; \ + static UNIQUE_NAME CONCAT(_ignored, UNIQUE_NAME); + namespace Quirks { void Add(DeviceQuirk* quirk); void Run(); diff --git a/init/quirks/device/ulefone_power_armor_13.cpp b/init/quirks/device/ulefone_power_armor_13.cpp deleted file mode 100644 index 28a689c..0000000 --- a/init/quirks/device/ulefone_power_armor_13.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../../quirks.h" - -#include - -#include - -using namespace std; - -class UlefonePowerArmor13Quirks : DeviceQuirk { -public: - bool ShouldRun() { - return FP_STARTS_WITH("Ulefone/Power_Armor_13/"); - } - - void Run() { - // Set the A2DP offload properties to disabled so legacy policy is loaded - android::base::SetProperty("persist.bluetooth.a2dp_offload.disabled", "true"); - android::base::SetProperty("persist.bluetooth.bluetooth_audio_hal.disabled", "true"); - } -}; - -LOAD_QUIRK(UlefonePowerArmor13Quirks); diff --git a/init/quirks/device/unihertz_keylayout.cpp b/init/quirks/device/unihertz_keylayout.cpp index 6fc4ed9..f3b44bf 100644 --- a/init/quirks/device/unihertz_keylayout.cpp +++ b/init/quirks/device/unihertz_keylayout.cpp @@ -16,7 +16,8 @@ public: Quirks::OverrideFolderWith("/system/usr/keylayout", [](auto p) { Quirks::CopyFileKeepPerms("/system/system_ext/quirks/keylayout/unihertz-fingerprint_key.kl", p / "fingerprint_key.kl"); Quirks::CopyFileKeepPerms("/system/system_ext/quirks/keylayout/unihertz-mtk-tpd.kl", p / "mtk-tpd.kl"); - Quirks::CopyFileKeepPerms("/system/system_ext/quirks/keylayout/unihertz-mtk-tpd-kpd.kl", p / "mtk-tpd-kpd.kl"); + Quirks::CopyFileKeepPerms("/system/system_ext/quirks/keylayout/unihertz-mtk-tpd.kl", p / "mtk-tpd-kpd.kl"); + Quirks::CopyFileKeepPerms("/system/system_ext/quirks/keylayout/unihertz-mtk-tpd.kl", p / "cap_touch.kl"); Quirks::CopyFileKeepPerms("/system/system_ext/quirks/keylayout/unihertz-mtk-kpd.kl", p / "mtk-kpd.kl"); }); } diff --git a/init/quirks/preset_props.cpp b/init/quirks/preset_props.cpp new file mode 100644 index 0000000..f97473e --- /dev/null +++ b/init/quirks/preset_props.cpp @@ -0,0 +1,15 @@ +#include "../quirks.h" + +#include + +// Disable navbar by default on devices known to have physical keys +PRESET_PROPS( + FP_STARTS_WITH("Unihertz/Jelly") || FP_STARTS_WITH("Unihertz/Atom"), + "persist.sys.gsi.hw.mainkeys", "1" +); + +// Some xiaomi devices: Override default network mode to enable 5G +PRESET_PROPS( + FP_STARTS_WITH("Redmi/gauguin"), + "ro.telephony.default_network", "33,22" +); diff --git a/init/quirks/soc/mtk_trustkernel.cpp b/init/quirks/soc/mtk_trustkernel.cpp new file mode 100644 index 0000000..e80bd55 --- /dev/null +++ b/init/quirks/soc/mtk_trustkernel.cpp @@ -0,0 +1,75 @@ +#include "../../quirks.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace std; + +#define AVB_PROP_OS_VERSION "com.android.build.boot.os_version" +#define AVB_PROP_SPL "com.android.build.boot.security_patch" + +optional> try_get_spl() { + string boot_part = "/dev/block/by-name/boot" + android::base::GetProperty("ro.boot.slot_suffix", ""); + + // Read from AVB footer, https://github.com/TrebleDroid/device_phh_treble/blob/android-13.0/fixSPL/getSPL.c + // First read into memory + int fd = open(boot_part.c_str(), O_RDONLY); + off_t size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + char *buf = (char *) malloc(size); + read(fd, buf, size); + + // Search for AVB footer property directly in the binary + char* p = (char *) memmem(buf, size, AVB_PROP_OS_VERSION, sizeof(AVB_PROP_OS_VERSION)); + if (p == nullptr) + return nullopt; + + p += sizeof(AVB_PROP_OS_VERSION); + string os_version(p); + + p = (char *) memmem(buf, size, AVB_PROP_SPL, sizeof(AVB_PROP_SPL)); + if (p == nullptr) + return nullopt; + + p += sizeof(AVB_PROP_SPL); + string spl(p); + + return make_pair(os_version, spl); +} + +class MtkTkQuirk : DeviceQuirk { +public: + bool ShouldRun() { + return filesystem::exists("/proc/tkcore/tkcore_log") + // No longer an issue after MediaTek upgraded to KeyMint AIDL services + && !filesystem::exists("/vendor/bin/hw/android.hardware.security.keymint-service.trustkernel"); + } + + void Run() { + android::base::SetProperty("debug.phh.props.ice.trustkernel", "keymaster"); + android::base::SetProperty("debug.phh.props.teed", "keymaster"); + android::base::SetProperty("ro.keymaster.brn", "Android"); + android::base::SetProperty("ro.keymaster.mod", "AOSP on ARM64"); + + auto res = try_get_spl(); + + if (res) { + android::base::SetProperty("ro.keymaster.xxx.release", res->first); + android::base::SetProperty("ro.keymaster.xxx.security_patch", res->second); + } + + android::base::SetProperty("ctl.restart", "teed"); + } +}; + +LOAD_QUIRK(MtkTkQuirk) diff --git a/interfaces/Android.bp b/interfaces/Android.bp new file mode 100644 index 0000000..007ea3b --- /dev/null +++ b/interfaces/Android.bp @@ -0,0 +1,5 @@ +hidl_package_root { + name: "vendor", + path: "device/peter/gsi/interfaces/vendor", +} + diff --git a/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/Android.bp b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/Android.bp new file mode 100644 index 0000000..2c1a28e --- /dev/null +++ b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/Android.bp @@ -0,0 +1,16 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "vendor.mediatek.hardware.aguiledbelt@1.0", + root: "vendor", + system_ext_specific: true, + srcs: [ + "types.hal", + "IAguiLedBeltLight.hal", + "ILedBeltLightCallback.hal", + ], + interfaces: [ + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/IAguiLedBeltLight.hal b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/IAguiLedBeltLight.hal new file mode 100644 index 0000000..61967c5 --- /dev/null +++ b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/IAguiLedBeltLight.hal @@ -0,0 +1,15 @@ +package vendor.mediatek.hardware.aguiledbelt@1.0; + +import vendor.mediatek.hardware.aguiledbelt@1.0::ILedBeltLightCallback; +import vendor.mediatek.hardware.aguiledbelt@1.0::LedBeltType; + +interface IAguiLedBeltLight { + setLedBeltLightMusicState(uint32_t lightId, uint32_t color, uint32_t brightness, bool isRandom); + setLedBeltLightAtomphereState(uint32_t lightId, uint32_t color, uint32_t brightness); + setLedBeltLightState(LedBeltType type, uint32_t color, uint32_t brightness); + setLedBeltBrightnessState(uint32_t lightId, uint32_t color, uint32_t brightness, bool isRandom); + setLedBeltPatternSettingsState(uint32_t lightId, uint32_t color, uint32_t brightness, bool isRandom); + setLedBeltAlwaysOnState(uint32_t lightId, uint32_t color, uint32_t brightness, bool isRandom); + setCallback(ILedBeltLightCallback callback); + setLedBeltChargingState(uint32_t lightId, uint32_t color); +}; diff --git a/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/ILedBeltLightCallback.hal b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/ILedBeltLightCallback.hal new file mode 100644 index 0000000..2e64b30 --- /dev/null +++ b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/ILedBeltLightCallback.hal @@ -0,0 +1,5 @@ +package vendor.mediatek.hardware.aguiledbelt@1.0; + +interface ILedBeltLightCallback { + onStateChanged(uint32_t id, uint32_t state); +}; diff --git a/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/types.hal b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/types.hal new file mode 100644 index 0000000..2880a49 --- /dev/null +++ b/interfaces/vendor/mediatek/hardware/aguiledbelt/1.0/types.hal @@ -0,0 +1,15 @@ +package vendor.mediatek.hardware.aguiledbelt@1.0; + +enum LedBeltType: uint8_t { + BATTERY = 0x64, + WLR_BATTERY = 0x65, + NOTIFICATIONS = 0x66, + CALL = 0x67, + LIGHT_ID_VOICE_ASSISTANT = 0x68, + MUSIC = 0x6b, + LIGHT_ID_FLIP = 0x6c, + BRIGHTNESS = 0x6e, + ATMOSPHERE = 0x6f, + PATTERN_SETTINGS = 0x70, + ALWAYS_ON = 0x71, +}; diff --git a/overlay/GsiFrameworkResTarget/res/values/config.xml b/overlay/GsiFrameworkResTarget/res/values/config.xml index 423abd0..a89e86d 100644 --- a/overlay/GsiFrameworkResTarget/res/values/config.xml +++ b/overlay/GsiFrameworkResTarget/res/values/config.xml @@ -64,4 +64,8 @@ com.android.statementservice + + + android.sensor.light diff --git a/quirks/keylayout/unihertz-mtk-tpd-kpd.kl b/quirks/keylayout/unihertz-mtk-tpd-kpd.kl deleted file mode 100644 index 9024e2f..0000000 --- a/quirks/keylayout/unihertz-mtk-tpd-kpd.kl +++ /dev/null @@ -1,6 +0,0 @@ -# Keylayout for Unihertz devices with capacitive keys -# Capacitive navigation -key 172 HOME VIRTUAL -key 580 APP_SWITCH VIRTUAL -key 158 BACK VIRTUAL - diff --git a/quirks/quirks.mk b/quirks/quirks.mk index b82f7c9..b68de18 100644 --- a/quirks/quirks.mk +++ b/quirks/quirks.mk @@ -4,5 +4,4 @@ LOCAL_PATH := device/peter/gsi/quirks PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/keylayout/unihertz-fingerprint_key.kl:$(TARGET_COPY_OUT_SYSTEM_EXT)/quirks/keylayout/unihertz-fingerprint_key.kl \ $(LOCAL_PATH)/keylayout/unihertz-mtk-kpd.kl:$(TARGET_COPY_OUT_SYSTEM_EXT)/quirks/keylayout/unihertz-mtk-kpd.kl \ - $(LOCAL_PATH)/keylayout/unihertz-mtk-tpd-kpd.kl:$(TARGET_COPY_OUT_SYSTEM_EXT)/quirks/keylayout/unihertz-mtk-tpd-kpd.kl \ $(LOCAL_PATH)/keylayout/unihertz-mtk-tpd.kl:$(TARGET_COPY_OUT_SYSTEM_EXT)/quirks/keylayout/unihertz-mtk-tpd.kl \ diff --git a/sepolicy/private/hal_aguiledbelt_hwservice.te b/sepolicy/private/hal_aguiledbelt_hwservice.te new file mode 100644 index 0000000..7058096 --- /dev/null +++ b/sepolicy/private/hal_aguiledbelt_hwservice.te @@ -0,0 +1,4 @@ +type hal_aguiledbelt_hwservice, hwservice_manager_type; +allow system_app hal_aguiledbelt_hwservice:hwservice_manager { find }; +type hal_aguiledbelt, domain; +allow system_app hal_aguiledbelt:binder { call }; diff --git a/sepolicy/private/hal_telephony.te b/sepolicy/private/hal_telephony.te new file mode 100644 index 0000000..398de41 --- /dev/null +++ b/sepolicy/private/hal_telephony.te @@ -0,0 +1,4 @@ +type rild, domain; + +allow system_app hal_telephony_hwservice:hwservice_manager find; +allow { rild system_app } { rild system_app }:binder { call transfer }; diff --git a/sepolicy/private/hwservice_contexts b/sepolicy/private/hwservice_contexts new file mode 100644 index 0000000..91e2392 --- /dev/null +++ b/sepolicy/private/hwservice_contexts @@ -0,0 +1,3 @@ +# HIDL interface for QcRilAm +vendor.qti.hardware.radio.am::IQcRilAudio u:object_r:hal_telephony_hwservice:s0 +vendor.qti.qcril.am::IQcRilAudio u:object_r:hal_telephony_hwservice:s0 diff --git a/sepolicy/private/keymaster.te b/sepolicy/private/keymaster.te new file mode 100644 index 0000000..60105fb --- /dev/null +++ b/sepolicy/private/keymaster.te @@ -0,0 +1,7 @@ +# Access to fake keymaster SPL/Android version props -- from TrebleDroid +get_prop(hal_keymaster, default_prop); +get_prop(tee, default_prop); + +get_prop(hal_keymaster, system_prop); + +get_prop(hal_gatekeeper, system_prop); diff --git a/sepolicy/private/qcrilam_app.te b/sepolicy/private/qcrilam_app.te new file mode 100644 index 0000000..8b3dc0e --- /dev/null +++ b/sepolicy/private/qcrilam_app.te @@ -0,0 +1,22 @@ +type qcrilam_app, domain; + +app_domain(qcrilam_app) + +# Needed to get access to /data/data/com.sony.qcrilam +# Only getattr and search are requested since qcrilam does not write to its own directory +# /data/data/com.sony.qcrilam only has two empty subdirs +dontaudit qcrilam_app app_data_file:dir { getattr search }; + +# Access services that should be available to all apps +allow qcrilam_app app_api_service:service_manager find; + +# Find media.audio_flinger +allow qcrilam_app audioserver_service:service_manager find; +# Find isub +allow qcrilam_app radio_service:service_manager find; + +# Find the vendor.qti.hardware.radio.am::IQcRilAudio HIDL service +# And grant binder access to the host (`rild`) +hal_client_domain(qcrilam_app, hal_telephony) + +allow qcrilam_app cgroup:file w_file_perms; diff --git a/sepolicy/private/seapp_contexts b/sepolicy/private/seapp_contexts new file mode 100644 index 0000000..2153f7d --- /dev/null +++ b/sepolicy/private/seapp_contexts @@ -0,0 +1 @@ +user=_app seinfo=platform name=com.sony.qcrilam domain=qcrilam_app type=app_data_file