universal7885: host_tools: Introduce a tool to update fp

This commit is contained in:
roynatech2544 2022-09-22 18:11:50 +09:00
commit 2fd6a2cb26
4 changed files with 209 additions and 0 deletions

17
.github/workflows/update_fp.yml vendored Normal file
View file

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

View file

@ -0,0 +1 @@
updater

View file

@ -0,0 +1,178 @@
#include <curl/curl.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <fstream>
// 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<std::string *>(userp)->append(static_cast<char *>(contents), size * nmemb);
return size * nmemb;
}
static std::vector<std::string> splitNewLines (const std::string& buffer)
{
auto result = std::vector<std::string>{};
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 <codename>?
if (!STD_STRING_CONTAINS(line, DEVICE_CODENAME))
return res;
// Remove non-fingerprint stuff.
// It should be <vendor>/<codename>/.. 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<char> 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<char> 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<std::string>{};
auto ss = std::stringstream{fpdata};
auto data = new struct build_data;
for (std::string line; std::getline(ss, line, '/');)
split.push_back(line);
// Fingerprint: "<VENDOR>/<CODENAME>/<CODENAME>:<AND_VER>/<BUILDID>/<VENDORDATA>: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;
}

View file

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