From 2fd6a2cb26d3c81eef306ac65f59aa14b4007014 Mon Sep 17 00:00:00 2001 From: roynatech2544 Date: Thu, 22 Sep 2022 18:11:50 +0900 Subject: [PATCH] universal7885: host_tools: Introduce a tool to update fp --- .github/workflows/update_fp.yml | 17 ++ universal7885-common/host-tools/.gitignore | 1 + .../host-tools/BuildFpUpdater.cc | 178 ++++++++++++++++++ universal7885-common/host-tools/update_fp.sh | 13 ++ 4 files changed, 209 insertions(+) create mode 100644 .github/workflows/update_fp.yml create mode 100644 universal7885-common/host-tools/.gitignore create mode 100644 universal7885-common/host-tools/BuildFpUpdater.cc create mode 100755 universal7885-common/host-tools/update_fp.sh diff --git a/.github/workflows/update_fp.yml b/.github/workflows/update_fp.yml new file mode 100644 index 0000000..b22d828 --- /dev/null +++ b/.github/workflows/update_fp.yml @@ -0,0 +1,17 @@ +name: check fp update + +on: + schedule: + - cron: '0 7 * * 2,5' + push: + workflow_dispatch: + +jobs: + update: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + + - name: Install dependencies + run: bash universal7885-common/host-tools/update_fp.sh diff --git a/universal7885-common/host-tools/.gitignore b/universal7885-common/host-tools/.gitignore new file mode 100644 index 0000000..7e65a78 --- /dev/null +++ b/universal7885-common/host-tools/.gitignore @@ -0,0 +1 @@ +updater diff --git a/universal7885-common/host-tools/BuildFpUpdater.cc b/universal7885-common/host-tools/BuildFpUpdater.cc new file mode 100644 index 0000000..982d8d0 --- /dev/null +++ b/universal7885-common/host-tools/BuildFpUpdater.cc @@ -0,0 +1,178 @@ +#include + +#include +#include +#include +#include +#include + +// Tracking Evolution-X's PixelPropsUtils +#define UPSTREAM_URL "https://raw.githubusercontent.com/Evolution-X/frameworks_base/tiramisu/core/java/com/android/internal/util/evolution/PixelPropsUtils.java" + +// Use Pixel 6 Pro's fingerprint +#define DEVICE_CODENAME "raven" +#define DEVICE_VENDOR "google" + +#define STD_STRING_CONTAINS(str, search) (str.find(search) != std::string::npos) + +typedef struct result { + bool vaild = false; + std::string data = ""; +} result_t; + +struct build_data { + std::string vendor; + std::string codename; + int android_version; + std::string buildid; + std::string vendordata; +}; + +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, + void *userp) { + static_cast(userp)->append(static_cast(contents), size * nmemb); + return size * nmemb; +} + +static std::vector splitNewLines (const std::string& buffer) +{ + auto result = std::vector{}; + auto ss = std::stringstream{buffer}; + + for (std::string line; std::getline(ss, line, '\n');) + result.push_back(line); + + return result; +} + +static result_t *checkIfVaild(const std::string& line) +{ + auto res = new result_t; + + // Is it related to ? + if (!STD_STRING_CONTAINS(line, DEVICE_CODENAME)) + return res; + + // Remove non-fingerprint stuff. + // It should be //.. format + if (!STD_STRING_CONTAINS(line, DEVICE_VENDOR)) + return res; + + res->vaild = true; + res->data = line; + return res; +} + +static result_t *parseJavaFile(const std::string& buffer) +{ + auto kLines = splitNewLines(buffer); + for (const auto line : kLines) { + const auto res = checkIfVaild(line); + if (res->vaild) { + std::string data = res->data; + res->data = data.substr(data.find(DEVICE_VENDOR)); + data = res->data; + res->data = data.substr(0, data.find_last_of('"')); + return res; + } else + delete res; + } + // We failed to find the line. return nothing. + return new result_t; +} + +static std::string dirname(const std::string& arg) +{ + auto idx = arg.find_last_of("/\\"); + return arg.substr(0, idx); +} + +static std::string fromBuildDataToFP(struct build_data *data) +{ + const char *fmt = "%s/%s/%s:%d/%s/%s:user/release-keys"; + int size = std::snprintf(nullptr, 0, fmt, data->vendor.c_str(), data->codename.c_str(), data->codename.c_str(), data->android_version, data->buildid.c_str(), data->vendordata.c_str()); + std::vector buf(size + 1); + std::snprintf(&buf[0], buf.size(), fmt, data->vendor.c_str(), data->codename.c_str(), data->codename.c_str(), data->android_version, data->buildid.c_str(), data->vendordata.c_str()); + + return std::string(buf.begin(), buf.end()); +} + +static std::string fromBuildDataToDesc(struct build_data *data) +{ + const char *fmt = "%s-user %d %s %s release-keys"; + int size = std::snprintf(nullptr, 0, fmt, data->codename.c_str(), data->android_version, data->buildid.c_str(), data->vendordata.c_str()); + std::vector buf(size + 1); + std::snprintf(&buf[0], buf.size(), fmt, data->codename.c_str(), data->android_version, data->buildid.c_str(), data->vendordata.c_str()); + + return std::string(buf.begin(), buf.end()); +} + +static struct build_data *serialize(const std::string& fpdata) +{ + auto split = std::vector{}; + auto ss = std::stringstream{fpdata}; + auto data = new struct build_data; + for (std::string line; std::getline(ss, line, '/');) + split.push_back(line); + + // Fingerprint: "//://:user/release-keys" + data->vendor = split[0]; + std::string mixed = split[2]; + int idx = mixed.find(':'); + data->codename = mixed.substr(0, idx); + data->android_version = stoi(mixed.substr(idx + 1)); + data->buildid = split[3]; + mixed = split[4]; + idx = mixed.find(':'); + data->vendordata = mixed.substr(0, idx); + return data; +} + +static void apply(const std::string& path, struct build_data *data) +{ + std::remove(path.c_str()); + std::ofstream file(path); + if (file.is_open()) { + std::string str; + file << "# Autogenerated by " << __FILE__ << std::endl; + file << "PRODUCT_GMS_CLIENTID_BASE := android-google" << std::endl; + file << std::endl; + str = fromBuildDataToFP(data); + str.resize(str.find('\0')); + file << "BUILD_FINGERPRINT := \"" << str << "\"" << std::endl; + file << std::endl; + file << "PRODUCT_BUILD_PROP_OVERRIDES += \\" << std::endl; + str = fromBuildDataToDesc(data); + str.resize(str.find('\0')); + file << "\tPRIVATE_BUILD_DESC=\"" << str << "\"" << std::endl; + file.close(); + } +} + +int main(int argc, const char **argv) { + CURL *curl; + CURLcode res; + std::string readBuffer = ""; + std::string execDir = dirname(argv[0]); + + curl = curl_easy_init(); + if (curl != nullptr) { + curl_easy_setopt(curl, CURLOPT_URL, UPSTREAM_URL); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + if (res) + return res; + } + + auto parseRes = parseJavaFile(readBuffer); + if (!parseRes->vaild) + return 1; + + auto build = serialize(parseRes->data); + delete parseRes; + apply(execDir + "/../fingerprint.mk", build); + + return 0; +} diff --git a/universal7885-common/host-tools/update_fp.sh b/universal7885-common/host-tools/update_fp.sh new file mode 100755 index 0000000..e79932a --- /dev/null +++ b/universal7885-common/host-tools/update_fp.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" +git config --local user.name "github-actions[bot]" + +sudo apt update +sudo apt install -y libcurl4-openssl-dev clang +cd universal7885-common/host-tools/ +clang++ BuildFpUpdater.cc -o updater -lcurl +./updater +git add .. +git commit -m "universal7885: Update fp [`date`]" +git push