[WIP] init: initial implementation of "quirks" support
This commit is contained in:
parent
3e3c06374d
commit
37f6b0069d
|
@ -1,10 +1,19 @@
|
||||||
cc_binary {
|
cc_binary {
|
||||||
name: "init_gsi",
|
name: "init_gsi",
|
||||||
system_ext_specific: true,
|
system_ext_specific: true,
|
||||||
srcs: ["init_gsi.cpp"],
|
srcs: [
|
||||||
shared_libs: ["libbase", "libdl", "libutils"],
|
"init_gsi.cpp",
|
||||||
static_libs: ["libresetprop"],
|
"quirks.cpp",
|
||||||
|
|
||||||
|
// SoC-specific quirks
|
||||||
|
"quirks/soc/mtk_ril.cpp",
|
||||||
|
],
|
||||||
|
shared_libs: ["libbase", "libdl", "liblog", "libutils"],
|
||||||
|
static_libs: ["libresetprop", "libc++fs"],
|
||||||
init_rc: ["init_gsi.rc"],
|
init_rc: ["init_gsi.rc"],
|
||||||
|
cflags: [
|
||||||
|
"-std=gnu++17",
|
||||||
|
],
|
||||||
target: {
|
target: {
|
||||||
android: {
|
android: {
|
||||||
ldflags: ["-Wl,--rpath,/system/${LIB}/bootstrap"],
|
ldflags: ["-Wl,--rpath,/system/${LIB}/bootstrap"],
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "quirks.h"
|
||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -31,7 +33,7 @@ std::string RO_PROP_SOURCES[] = {
|
||||||
"", "product", "odm", "vendor", "system_ext", "system", "bootimage",
|
"", "product", "odm", "vendor", "system_ext", "system", "bootimage",
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
void handle_device_model_props() {
|
||||||
string device = base::GetProperty("ro.product.vendor.device", "");
|
string device = base::GetProperty("ro.product.vendor.device", "");
|
||||||
string model = base::GetProperty("ro.product.vendor.model", "");
|
string model = base::GetProperty("ro.product.vendor.model", "");
|
||||||
string name = base::GetProperty("ro.product.vendor.name", "");
|
string name = base::GetProperty("ro.product.vendor.name", "");
|
||||||
|
@ -48,6 +50,10 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override_ro_prop("ro", "", "build.stock_fingerprint", fingerprint);
|
override_ro_prop("ro", "", "build.stock_fingerprint", fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
handle_device_model_props();
|
||||||
|
Quirks::Run();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
on post-fs
|
on post-fs
|
||||||
exec -- /system_ext/bin/init_gsi
|
exec u:r:init_gsi:s0 root -- /system_ext/bin/init_gsi
|
||||||
|
|
77
init/quirks.cpp
Normal file
77
init/quirks.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#define LOG_TAG "init_gsi_quirks"
|
||||||
|
#include <utils/Log.h>
|
||||||
|
|
||||||
|
#include "quirks.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <sys/mount.h>
|
||||||
|
|
||||||
|
// Default destructor for DeviceQuirk
|
||||||
|
DeviceQuirk::~DeviceQuirk() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<DeviceQuirk*>* quirks = nullptr;
|
||||||
|
|
||||||
|
void Quirks::Add(DeviceQuirk* quirk) {
|
||||||
|
if (quirks == nullptr) {
|
||||||
|
quirks = new std::vector<DeviceQuirk*>();
|
||||||
|
}
|
||||||
|
quirks->push_back(quirk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quirks::Run() {
|
||||||
|
if (quirks == nullptr) return;
|
||||||
|
|
||||||
|
for (DeviceQuirk* quirk : *quirks) {
|
||||||
|
if (quirk->ShouldRun()) {
|
||||||
|
quirk->Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility functions for use with quirks
|
||||||
|
#define QUIRKS_TMP_BASE_PATH "/mnt/quirks"
|
||||||
|
#define QUIRKS_TMP_FILES_PATH QUIRKS_TMP_BASE_PATH "/files"
|
||||||
|
|
||||||
|
void EnsureDirectory(filesystem::path p) {
|
||||||
|
if (!filesystem::is_directory(p)) {
|
||||||
|
filesystem::create_directories(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnsureTmpMount() {
|
||||||
|
if (filesystem::is_directory(QUIRKS_TMP_BASE_PATH)) return;
|
||||||
|
|
||||||
|
EnsureDirectory(QUIRKS_TMP_BASE_PATH);
|
||||||
|
int err = mount("tmpfs", QUIRKS_TMP_BASE_PATH, "tmpfs", 0, "mode=755,gid=0");
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
ALOGE("mount tmpfs on %s err = %d\n", QUIRKS_TMP_BASE_PATH, errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quirks::OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement) {
|
||||||
|
if (!filesystem::is_regular_file(p)) return;
|
||||||
|
|
||||||
|
EnsureTmpMount();
|
||||||
|
EnsureDirectory(QUIRKS_TMP_FILES_PATH);
|
||||||
|
|
||||||
|
filesystem::path tmp_path = QUIRKS_TMP_FILES_PATH + p.string();
|
||||||
|
EnsureDirectory(tmp_path.parent_path());
|
||||||
|
|
||||||
|
// TODO: Actually implement pattern replacement
|
||||||
|
filesystem::copy_file(p, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call restorecon via execl, because for some reason
|
||||||
|
// libselinux functions will segfault in our case
|
||||||
|
// (probably related to other magic present in our process)
|
||||||
|
fork_execl("/system/bin/restorecon", "restorecon", p.c_str());
|
||||||
|
}
|
32
init/quirks.h
Normal file
32
init/quirks.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void fork_execl(Args... args) {
|
||||||
|
int pid, status;
|
||||||
|
if ((pid = fork()) == 0) {
|
||||||
|
execl(args..., nullptr);
|
||||||
|
} else {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeviceQuirk {
|
||||||
|
public:
|
||||||
|
virtual bool ShouldRun();
|
||||||
|
virtual void Run();
|
||||||
|
virtual ~DeviceQuirk();
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Quirks {
|
||||||
|
void Add(DeviceQuirk* quirk);
|
||||||
|
void Run();
|
||||||
|
|
||||||
|
void OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement);
|
||||||
|
}
|
38
init/quirks/soc/mtk_ril.cpp
Normal file
38
init/quirks/soc/mtk_ril.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include "../../quirks.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const string PATHS[] = {
|
||||||
|
"/vendor/lib/libmtk-ril.so",
|
||||||
|
"/vendor/lib/mtk-ril.so",
|
||||||
|
"/vendor/lib64/libmtk-ril.so",
|
||||||
|
"/vendor/lib64/mtk-ril.so"
|
||||||
|
};
|
||||||
|
|
||||||
|
class MtkRilQuirk : DeviceQuirk {
|
||||||
|
public:
|
||||||
|
MtkRilQuirk() {
|
||||||
|
Quirks::Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShouldRun() {
|
||||||
|
for (auto& p : PATHS) {
|
||||||
|
if (filesystem::exists(p)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Run() {
|
||||||
|
for (auto& p : PATHS) {
|
||||||
|
if (filesystem::exists(p)) {
|
||||||
|
Quirks::OverrideFileReplaceSubstr(p, "AT+EAIC=2", "AT+EAIC=3");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static MtkRilQuirk* _ignored = new MtkRilQuirk();
|
Loading…
Reference in a new issue