init: implement folder replacement quirks

* As a test, we import Unihertz keylayout hacks from phh GSI
This commit is contained in:
Peter Cai 2021-10-17 21:33:20 -04:00
parent 297b1c2313
commit 6870114c33
11 changed files with 131 additions and 18 deletions

View File

@ -32,3 +32,5 @@ include vendor/hardware_overlay/overlay.mk
PRODUCT_PACKAGES += \
init_gsi
# Quirks
include device/peter/gsi/quirks/quirks.mk

View File

@ -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"],

View File

@ -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<void(istream&, ostream&)> proc) {
if (!filesystem::is_regular_file(p)) return;
@ -79,26 +105,10 @@ void Quirks::OverrideFileWith(filesystem::path p, function<void(istream&, ostrea
ifs.close();
ofs.close();
// Synchronize ownership and permission
// C++ filesystem does not support uid / gid manipulation
struct stat st;
int err = stat(p.c_str(), &st);
if (err < 0) {
ALOGE("Failed to stat %s: %d\n", tmp_path.c_str(), errno);
return;
}
err = chown(tmp_path.c_str(), st.st_uid, st.st_gid);
if (err < 0) {
ALOGE("Failed to chown %s: %d\n", tmp_path.c_str(), errno);
}
err = chmod(tmp_path.c_str(), st.st_mode);
if (err < 0) {
ALOGE("Failed to chmod %s: %d\n", tmp_path.c_str(), errno);
}
RestoreFilePermissions(p, tmp_path);
// Bind mount and override the file
err = mount(tmp_path.c_str(), p.c_str(), nullptr, MS_BIND, nullptr);
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);
@ -117,3 +127,34 @@ void Quirks::OverrideFileReplaceSubstr(filesystem::path p, string pattern, strin
os << regex_replace(str, regex(pattern), replacement);;
});
}
void Quirks::OverrideFolderWith(filesystem::path p, function<void(filesystem::path)> 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());
}

View File

@ -34,4 +34,8 @@ namespace Quirks {
void OverrideFileWith(filesystem::path p, function<void(istream&, ostream&)> proc);
void OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement);
void OverrideFolderWith(filesystem::path p, function<void(filesystem::path)> proc);
void CopyFileKeepPerms(filesystem::path src, filesystem::path dst);
}

View File

@ -0,0 +1,26 @@
#include "../../quirks.h"
#include <android-base/properties.h>
#include <filesystem>
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();

View File

@ -0,0 +1,3 @@
# Key layout for Unihertz devices with fingerprint sensor
# For Atom {,L,XL}: fingerprint sensor as home
key 172 HOME VIRTUAL

View File

@ -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

View File

@ -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

View File

@ -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

8
quirks/quirks.mk Normal file
View File

@ -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 \

View File

@ -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