Compare commits

...

4 Commits

Author SHA1 Message Date
Loong
f6f7a7d204 fix(controller): initialize adb-lite client from serial 2026-05-24 20:50:15 +01:00
uye
d7cacdfbee chore: 调整注释 2026-05-25 03:49:37 +08:00
uye
a2134532de feat: adb lite 实现中 get_adb_client 与 release_adb 增加锁 2026-05-25 03:39:19 +08:00
Loong
bd76516688 fix(controller): initialize adb-lite client from serial 2026-05-24 19:51:41 +01:00
4 changed files with 67 additions and 25 deletions

View File

@@ -915,6 +915,7 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string
// 设置配置 connect、release 命令,即使这里不连接,后续也会需要用到
m_adb.connect = m_conn_ctx.replace_cmd(adb_cfg.connect);
m_adb.release = m_conn_ctx.replace_cmd(adb_cfg.release);
m_platform_io->set_adb_serial(address);
if (need_connect) {
// 如果不包含 `:` 且需要连接connect 命令也不会成功
if (address.find(':') == std::string::npos) {

View File

@@ -28,9 +28,9 @@ std::optional<int> asst::AdbLiteIO::call_command(
static const boost::regex devices_regex(R"(^.+ devices$)");
static const boost::regex release_regex(R"(^.+ kill-server$)");
static const boost::regex connect_regex(R"(^.+ connect (\S+)$)");
static const boost::regex shell_regex(R"(^.+ -s \S+ shell (.+)$)");
static const boost::regex exec_regex(R"(^.+ -s \S+ exec-out (.+)$)");
static const boost::regex push_regex(R"#(^.+ -s \S+ push "(.+)" "(.+)"$)#");
static const boost::regex shell_regex(R"(^.+ -s (\S+) shell (.+)$)");
static const boost::regex exec_regex(R"(^.+ -s (\S+) exec-out (.+)$)");
static const boost::regex push_regex(R"#(^.+ -s (\S+) push "(.+)" "(.+)"$)#");
// adb devices
if (boost::regex_match(cmd, devices_regex)) {
@@ -61,9 +61,14 @@ std::optional<int> asst::AdbLiteIO::call_command(
}
// adb connect
// TODO: adb server 尚未实现,第一次连接需要执行一次 adb.exe 启动 daemon
if (boost::regex_match(cmd, match, connect_regex)) {
m_adb_client = adb::client::create(match[1].str()); // TODO: compare address with existing (if any)
const std::string serial = match[1].str();
std::lock_guard lock(m_adb_client_mutex);
if (!m_adb_client || m_adb_serial != serial) {
Log.error("adb client not initialized for serial:", serial, "current:", m_adb_serial);
ret = std::nullopt;
goto ret_exit;
}
try {
pipe_data = m_adb_client->connect();
@@ -80,15 +85,17 @@ std::optional<int> asst::AdbLiteIO::call_command(
// adb shell
if (boost::regex_match(cmd, match, shell_regex)) {
if (!m_adb_client) {
Log.error("adb client not initialized");
const std::string serial = match[1].str();
std::string command = match[2].str();
remove_quotes(command);
std::lock_guard lock(m_adb_client_mutex);
if (!m_adb_client || m_adb_serial != serial) {
Log.error("adb client not initialized for serial:", serial, "current:", m_adb_serial);
ret = std::nullopt;
goto ret_exit;
}
std::string command = match[1].str();
remove_quotes(command);
try {
pipe_data = m_adb_client->shell(command);
ret = 0;
@@ -103,15 +110,17 @@ std::optional<int> asst::AdbLiteIO::call_command(
// adb exec-out
if (boost::regex_match(cmd, match, exec_regex)) {
if (!m_adb_client) {
Log.error("adb client not initialized");
const std::string serial = match[1].str();
std::string command = match[2].str();
remove_quotes(command);
std::lock_guard lock(m_adb_client_mutex);
if (!m_adb_client || m_adb_serial != serial) {
Log.error("adb client not initialized for serial:", serial, "current:", m_adb_serial);
ret = std::nullopt;
goto ret_exit;
}
std::string command = match[1].str();
remove_quotes(command);
try {
pipe_data = m_adb_client->exec(command);
ret = 0;
@@ -126,14 +135,16 @@ std::optional<int> asst::AdbLiteIO::call_command(
// adb push
if (boost::regex_match(cmd, match, push_regex)) {
if (!m_adb_client) {
Log.error("adb client not initialized");
const std::string serial = match[1].str();
std::lock_guard lock(m_adb_client_mutex);
if (!m_adb_client || m_adb_serial != serial) {
Log.error("adb client not initialized for serial:", serial, "current:", m_adb_serial);
ret = std::nullopt;
goto ret_exit;
}
try {
m_adb_client->push(match[1].str(), match[2].str(), 0644);
m_adb_client->push(match[2].str(), match[3].str(), 0644);
ret = 0;
goto ret_exit;
}
@@ -156,20 +167,32 @@ ret_exit:
return ret;
}
void asst::AdbLiteIO::set_adb_serial(std::string_view serial)
{
std::lock_guard lock(m_adb_client_mutex);
const std::string serial_str(serial);
if (!m_adb_client || m_adb_serial != serial_str) {
m_adb_serial = serial_str;
m_adb_client = adb::client::create(m_adb_serial);
}
}
std::shared_ptr<asst::IOHandler> asst::AdbLiteIO::interactive_shell(const std::string& cmd)
{
static const boost::regex shell_regex(R"(^.+ -s \S+ shell (.+)$)");
static const boost::regex shell_regex(R"(^.+ -s (\S+) shell (.+)$)");
boost::smatch match;
if (boost::regex_match(cmd, match, shell_regex)) {
if (!m_adb_client) {
Log.error("adb client not initialized");
const std::string serial = match[1].str();
std::string command = match[2].str();
remove_quotes(command);
std::lock_guard lock(m_adb_client_mutex);
if (!m_adb_client || m_adb_serial != serial) {
Log.error("adb client not initialized for serial:", serial, "current:", m_adb_serial);
return nullptr;
}
std::string command = match[1].str();
remove_quotes(command);
try {
return std::make_shared<IOHandlerAdbLite>(m_adb_client->interactive_shell(command));
}
@@ -186,7 +209,13 @@ std::shared_ptr<asst::IOHandler> asst::AdbLiteIO::interactive_shell(const std::s
void asst::AdbLiteIO::release_adb(const std::string& adb_release, int64_t timeout)
{
if (m_adb_client) {
bool has_adb_client = false;
{
std::lock_guard lock(m_adb_client_mutex);
has_adb_client = static_cast<bool>(m_adb_client);
}
if (has_adb_client) {
std::string pipe_data;
std::string sock_data;
auto start_time = std::chrono::steady_clock::now();

View File

@@ -12,6 +12,10 @@
#include "Utils/Logger.hpp"
#include <mutex>
#include <string>
#include <string_view>
namespace asst
{
#ifdef _WIN32
@@ -38,12 +42,17 @@ public:
virtual std::shared_ptr<IOHandler> interactive_shell(const std::string& cmd) override;
virtual void set_adb_serial(std::string_view serial) override;
virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) override;
private:
static bool remove_quotes(std::string& data);
// 保护 m_adb_client / m_adb_serial防止 call_command 与 interactive_shell 并发访问
std::mutex m_adb_client_mutex;
std::shared_ptr<adb::client> m_adb_client = nullptr;
std::string m_adb_serial;
};
class IOHandlerAdbLite : public IOHandler

View File

@@ -4,6 +4,7 @@
#include <memory>
#include <optional>
#include <string>
#include <string_view>
namespace asst
{
@@ -33,6 +34,8 @@ public:
virtual std::shared_ptr<IOHandler> interactive_shell(const std::string& cmd) = 0;
virtual void set_adb_serial(std::string_view) {}
virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) = 0;
bool m_support_socket = false;