From c0d5d9f5f6371848b6129e1bb70332e30b745c7e Mon Sep 17 00:00:00 2001 From: kotori0 Date: Fri, 29 Jan 2021 01:39:29 +0800 Subject: [PATCH] [key-selector] Detects x86 and refactor code --- key-selector/build.gradle | 6 +- key-selector/src/main/cpp/Languages.h | 8 +- key-selector/src/main/cpp/key_selector.cpp | 116 ++++++++++++--------- key-selector/src/main/cpp/key_selector.h | 32 +++++- 4 files changed, 107 insertions(+), 55 deletions(-) diff --git a/key-selector/build.gradle b/key-selector/build.gradle index eccfe352..cc1694f3 100644 --- a/key-selector/build.gradle +++ b/key-selector/build.gradle @@ -10,7 +10,7 @@ android { externalNativeBuild { cmake { abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64' - cppFlags "-std=c++17" + cppFlags "-std=c++20" cFlags "-std=gnu99" } } @@ -28,8 +28,8 @@ android { release { externalNativeBuild { cmake { - cppFlags "-fvisibility=hidden -fvisibility-inlines-hidden -O2 -s -Wno-unused-value" - cFlags "-fvisibility=hidden -fvisibility-inlines-hidden -O2 -s -Wno-unused-value" + cppFlags "-fvisibility=hidden -fvisibility-inlines-hidden -Os -s -Wno-unused-value" + cFlags "-fvisibility=hidden -fvisibility-inlines-hidden -Os -s -Wno-unused-value" } } } diff --git a/key-selector/src/main/cpp/Languages.h b/key-selector/src/main/cpp/Languages.h index f889a818..0d95ce19 100644 --- a/key-selector/src/main/cpp/Languages.h +++ b/key-selector/src/main/cpp/Languages.h @@ -11,8 +11,8 @@ public: virtual const std::string desc_line_1() { return "Select variant. Use Volume Down to move and Volume Up to confirm."; } - virtual const std::string desc_line_2(int seconds) { - const char base[] = "The program will select YAHFA for you in %d seconds if you don't \nhave a physical volume button. "; + virtual const std::string desc_line_2(uint16_t seconds) { + const char base[] = "The program will select YAHFA for you in %hu seconds if you don't \nhave a physical volume button. "; std::string out; out.resize(sizeof(base) + 20); sprintf(out.data(), base, seconds); @@ -25,8 +25,8 @@ public: const std::string desc_line_1() override { return "请选择变种。使用音量减切换,音量加确定。"; } - const std::string desc_line_2(int seconds) override { - const char base[] = "如果您的设备没有音量键,本程序将会在 %d 秒后自动选择 YAHFA 。"; + const std::string desc_line_2(uint16_t seconds) override { + const char base[] = "如果您的设备没有音量键,本程序将会在 %hu 秒后自动选择 YAHFA 。"; std::string out; out.resize(sizeof(base) + 20); sprintf(out.data(), base, seconds); diff --git a/key-selector/src/main/cpp/key_selector.cpp b/key-selector/src/main/cpp/key_selector.cpp index 5ace72b7..a48924d8 100644 --- a/key-selector/src/main/cpp/key_selector.cpp +++ b/key-selector/src/main/cpp/key_selector.cpp @@ -16,19 +16,20 @@ * limitations under the License. */ -#include +#include #include +#include #include #include -#include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include #include +#include #include "Languages.h" #include "key_selector.h" @@ -48,7 +49,7 @@ static int open_device(const char *device) char name[80]; char location[80]; char idstr[80]; - struct input_id id; + input_id id{}; fd = open(device, O_RDWR); if (fd < 0) { @@ -128,7 +129,7 @@ static int read_notify(const char *dirname, int nfd) char devname[PATH_MAX]; char *filename; char event_buf[512]; - int event_size; + uint32_t event_size; int event_pos = 0; struct inotify_event *event; @@ -163,30 +164,15 @@ static int read_notify(const char *dirname, int nfd) static int scan_dir(const char *dirname) { - char devname[PATH_MAX]; - char *filename; - DIR *dir; - struct dirent *de; - - dir = opendir(dirname); - if (dir == NULL) { + namespace fs = std::filesystem; + try { + for (auto &item: fs::directory_iterator(dirname)) { + open_device(item.path().c_str()); + } + } catch (const fs::filesystem_error &e) { + std::cerr << e.what(); return -1; } - - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - - while ((de = readdir(dir))) { - if (de->d_name[0] == '.' && (de->d_name[1] == '\0' || - (de->d_name[1] == '.' && de->d_name[2] == '\0'))) { - continue; - } - - strcpy(filename, de->d_name); - open_device(devname); - } - closedir(dir); return 0; } @@ -194,7 +180,7 @@ static int scan_dir(const char *dirname) uint32_t get_event() { int i; int res; - struct input_event event; + input_event event{}; const char *device_path = "/dev/input"; unsigned char keys; @@ -206,12 +192,14 @@ uint32_t get_event() { res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); if (res < 0) { - throw std::logic_error("inotify_add_watch failed"); + std::cerr << "inotify_add_watch failed" << std::endl; + exit(1); } res = scan_dir(device_path); if (res < 0) { - throw std::logic_error("scan dev failed"); + std::cerr << "scan dev failed" << std::endl; + exit(1); } while (true) { @@ -245,7 +233,7 @@ uint32_t get_event() { int main() { if (getuid() != 0) { - std::cout << "Root required" << std::endl; + std::cerr << "Root required" << std::endl; exit(1); } @@ -254,20 +242,57 @@ int main() { alarm(timeout); auto sig_handler = [](int){ std::cout << "No operation after " << timeout << " seconds" << std::endl; - exit(YAHFA); + exit(static_cast(Variant::YAHFA)); }; signal(SIGALRM, sig_handler); - int cursor = YAHFA; - const int cursor_max = SandHook; + // get current arch +#if defined(__arm__) + const Arch arch = ARM; +#elif defined(__aarch64__) + const Arch arch = ARM64; +#elif defined(__i386__) + const Arch arch = x86; +#elif defined(__x86_64__) + const Arch arch = x86_64; +#else +#error "Unsupported arch" +#endif - auto print_status = [&cursor](){ + std::unordered_map variants; + for (const auto i: AllVariants) { + switch (i) { + case Variant::YAHFA: + variants[i] = { + .expression = "YAHFA", + .supported_arch = {ARM, ARM64, x86, x86_64} + }; + break; + case Variant::SandHook: + variants[i] = { + .expression = "SandHook", + .supported_arch = {ARM, ARM64} + }; + break; + } + } + + Variant cursor = Variant::YAHFA; + + auto print_status = [&cursor, variants, arch](){ //std::cout << "\33[2K\r"; // clear this line - std::cout << "["; - std::cout << (cursor == YAHFA ? "x" : " "); - std::cout << "] YAHFA ["; - std::cout << (cursor == SandHook ? "x" : " "); - std::cout << "] SandHook" << std::endl; + std::stringstream ss; + for (const auto &i: variants) { + if (!i.second.supported_arch.contains(arch)) { + continue; + } + ss << "["; + ss << (cursor == i.first ? "x" : " "); + ss << "] "; + ss << i.second.expression; + ss << " "; + } + std::cout << ss.str() << std::endl; }; // languages @@ -292,9 +317,6 @@ int main() { break; case KEYCHECK_PRESSED_VOLUMEDOWN: cursor++; - if (cursor > cursor_max) { - cursor = YAHFA; - } break; default: std::cout << "ERROR\n"; @@ -307,5 +329,5 @@ int main() { // std::cout << std::endl << cursor << std::endl; delete l; - return cursor; + return static_cast(cursor); } \ No newline at end of file diff --git a/key-selector/src/main/cpp/key_selector.h b/key-selector/src/main/cpp/key_selector.h index 730c4f0f..98e3f188 100644 --- a/key-selector/src/main/cpp/key_selector.h +++ b/key-selector/src/main/cpp/key_selector.h @@ -17,6 +17,8 @@ #ifndef __KEYCHECK_H__ #define __KEYCHECK_H__ +#include +#include // Constants: pressed keys #define KEYCHECK_CHECK_VOLUMEDOWN 0x01u @@ -24,9 +26,37 @@ #define KEYCHECK_PRESSED_VOLUMEDOWN 41u #define KEYCHECK_PRESSED_VOLUMEUP 42u -enum Variant { +enum class Variant { YAHFA = 0x11, SandHook = 0x12, + End = SandHook, +}; +const auto AllVariants = { Variant::YAHFA, Variant::SandHook }; + +Variant& operator++( Variant &c ) { + using IntType = typename std::underlying_type::type; + c = static_cast( static_cast(c) + 1 ); + if ( c > Variant::End ) + c = Variant::YAHFA; + return c; +} + +Variant operator++( Variant &c, int ) { + Variant result = c; + ++c; + return result; +} + +enum Arch { + ARM, + ARM64, + x86, + x86_64 +}; + +struct VariantDetail { + const char* expression; + std::unordered_set supported_arch; }; #endif // __KEYCHECK_H__ \ No newline at end of file