diff --git a/device.mk b/device.mk index 5fceb79..1d1705d 100644 --- a/device.mk +++ b/device.mk @@ -32,3 +32,5 @@ include vendor/hardware_overlay/overlay.mk PRODUCT_PACKAGES += \ init_gsi +# Quirks +include device/peter/gsi/quirks/quirks.mk diff --git a/init/Android.bp b/init/Android.bp index ff4b21b..9977a59 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -7,6 +7,9 @@ cc_binary { // SoC-specific quirks "quirks/soc/mtk_ril.cpp", + + // Device-specific quirks + "quirks/device/unihertz_keylayout.cpp", ], shared_libs: ["libbase", "libdl", "liblog", "libutils"], static_libs: ["libresetprop", "libc++fs"], diff --git a/init/quirks.cpp b/init/quirks.cpp index 50a0f95..bb40d26 100644 --- a/init/quirks.cpp +++ b/init/quirks.cpp @@ -43,6 +43,7 @@ void Quirks::Run() { // Utility functions for use with quirks #define QUIRKS_TMP_BASE_PATH "/mnt/quirks" #define QUIRKS_TMP_FILES_PATH QUIRKS_TMP_BASE_PATH "/files" +#define QUIRKS_TMP_DIRS_PATH QUIRKS_TMP_BASE_PATH "/dirs" void EnsureDirectory(filesystem::path p) { if (!filesystem::is_directory(p)) { @@ -61,6 +62,31 @@ void EnsureTmpMount() { } } +void RestoreFilePermissions(filesystem::path orig, filesystem::path new_path) { + // Synchronize ownership and permission + // C++ filesystem does not support uid / gid manipulation + struct stat st; + int err = stat(orig.c_str(), &st); + if (err < 0) { + ALOGE("Failed to stat %s: %d\n", orig.c_str(), errno); + return; + } + + err = chown(new_path.c_str(), st.st_uid, st.st_gid); + if (err < 0) { + ALOGE("Failed to chown %s: %d\n", new_path.c_str(), errno); + } + err = chmod(new_path.c_str(), st.st_mode); + if (err < 0) { + ALOGE("Failed to chmod %s: %d\n", new_path.c_str(), errno); + } +} + +void Quirks::CopyFileKeepPerms(filesystem::path src, filesystem::path dst) { + filesystem::copy_file(src, dst); + RestoreFilePermissions(src, dst); +} + void Quirks::OverrideFileWith(filesystem::path p, function proc) { if (!filesystem::is_regular_file(p)) return; @@ -79,26 +105,10 @@ void Quirks::OverrideFileWith(filesystem::path p, function proc) { + if (!filesystem::is_directory(p)) return; + + EnsureTmpMount(); + EnsureDirectory(QUIRKS_TMP_DIRS_PATH); + + filesystem::path tmp_path = QUIRKS_TMP_DIRS_PATH + p.string(); + EnsureDirectory(tmp_path); + + filesystem::copy(p, tmp_path, filesystem::copy_options::recursive); + + for (auto& entry : filesystem::recursive_directory_iterator(tmp_path)) { + if (!filesystem::is_regular_file(entry.path())) continue; + RestoreFilePermissions(p / filesystem::relative(entry.path(), tmp_path), entry.path()); + } + + // Restore the permission of the outer directory as well + RestoreFilePermissions(p, tmp_path); + + proc(tmp_path); + + int err = mount(tmp_path.c_str(), p.c_str(), nullptr, MS_BIND, nullptr); + + if (err < 0) { + ALOGE("bind mount %s on %s err = %d\n", tmp_path.c_str(), p.c_str(), errno); + return; + } + + fork_execl("/system/bin/restorecon", "restorecon", "-R", p.c_str()); +} diff --git a/init/quirks.h b/init/quirks.h index bbcb34a..ff27f75 100644 --- a/init/quirks.h +++ b/init/quirks.h @@ -34,4 +34,8 @@ namespace Quirks { void OverrideFileWith(filesystem::path p, function proc); void OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement); + + void OverrideFolderWith(filesystem::path p, function proc); + + void CopyFileKeepPerms(filesystem::path src, filesystem::path dst); } diff --git a/init/quirks/device/unihertz_keylayout.cpp b/init/quirks/device/unihertz_keylayout.cpp new file mode 100644 index 0000000..fc3d671 --- /dev/null +++ b/init/quirks/device/unihertz_keylayout.cpp @@ -0,0 +1,26 @@ +#include "../../quirks.h" + +#include + +#include + +using namespace std; + +class UnihertzKeylayoutQuirk : DeviceQuirk { +public: + bool ShouldRun() { + return android::base::GetProperty("ro.vendor.build.fingerprint", "") + .rfind("Unihertz/", 0) == 0; + } + + void Run() { + 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-kpd.kl", p / "mtk-kpd.kl"); + }); + } +}; + +static UnihertzKeylayoutQuirk* _ignored = new UnihertzKeylayoutQuirk(); diff --git a/quirks/keylayout/unihertz-fingerprint_key.kl b/quirks/keylayout/unihertz-fingerprint_key.kl new file mode 100644 index 0000000..792892e --- /dev/null +++ b/quirks/keylayout/unihertz-fingerprint_key.kl @@ -0,0 +1,3 @@ +# Key layout for Unihertz devices with fingerprint sensor +# For Atom {,L,XL}: fingerprint sensor as home +key 172 HOME VIRTUAL diff --git a/quirks/keylayout/unihertz-mtk-kpd.kl b/quirks/keylayout/unihertz-mtk-kpd.kl new file mode 100644 index 0000000..5f010b1 --- /dev/null +++ b/quirks/keylayout/unihertz-mtk-kpd.kl @@ -0,0 +1,13 @@ +# Keylayout for Unihertz devices with a dedicated PTT button +# Volume buttons +key 115 VOLUME_UP +key 114 VOLUME_DOWN + +# Power button +key 116 POWER + +# PTT - Remap to camera by default +# CAMERA is delivered to apps, so remapping via +# third-party apps is possible +key 249 CAMERA +key 250 CAMERA diff --git a/quirks/keylayout/unihertz-mtk-tpd-kpd.kl b/quirks/keylayout/unihertz-mtk-tpd-kpd.kl new file mode 100644 index 0000000..9024e2f --- /dev/null +++ b/quirks/keylayout/unihertz-mtk-tpd-kpd.kl @@ -0,0 +1,6 @@ +# 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/keylayout/unihertz-mtk-tpd.kl b/quirks/keylayout/unihertz-mtk-tpd.kl new file mode 100644 index 0000000..9024e2f --- /dev/null +++ b/quirks/keylayout/unihertz-mtk-tpd.kl @@ -0,0 +1,6 @@ +# 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 new file mode 100644 index 0000000..b82f7c9 --- /dev/null +++ b/quirks/quirks.mk @@ -0,0 +1,8 @@ +LOCAL_PATH := device/peter/gsi/quirks + +# Keylayout 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/file_contexts b/sepolicy/private/file_contexts index 44409c4..a319446 100644 --- a/sepolicy/private/file_contexts +++ b/sepolicy/private/file_contexts @@ -1 +1,2 @@ /system/system_ext/bin/init_gsi u:object_r:init_gsi_exec:s0 +/system/system_ext/quirks(/.*)? u:object_r:system_file:s0