Skip to content

Commit

Permalink
refactor: 重构 toolkit adb device finder (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
MistEO committed Jun 13, 2024
1 parent 8372f64 commit bd6c56b
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 348 deletions.
138 changes: 136 additions & 2 deletions source/MaaToolkit/AdbDevice/DeviceMgr.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "DeviceMgr.h"

#include <future>
#include <filesystem>
#include <ranges>

#include "ControlUnit/ControlUnitAPI.h"
#include "LibraryHolder/ControlUnit.h"
#include "Utils/IOStream/BoostIO.hpp"
#include "Utils/Logger.h"

MAA_TOOLKIT_NS_BEGIN
Expand Down Expand Up @@ -71,6 +74,136 @@ const std::optional<std::vector<Device>>& DeviceMgr::get_devices()
return devices_;
}

json::object
DeviceMgr::get_adb_config(const Emulator& emulator, const std::string& adb_serial) const
{
std::ignore = emulator;
std::ignore = adb_serial;

return {};
}

void DeviceMgr::set_emulator_const_data(std::unordered_map<std::string, EmulatorConstantData> data)
{
const_data_ = std::move(data);
}

std::vector<Device> DeviceMgr::find_device_impl()
{
std::vector<Device> result;

auto all_emulators = find_emulators();
for (const Emulator& e : all_emulators) {
std::filesystem::path adb_path = get_adb_path(e.const_data, e.process.pid);

std::vector<std::string> serials = e.const_data.adb_common_serials;

auto requested = request_adb_serials(adb_path, json::object());

serials.insert(
serials.end(),
std::make_move_iterator(requested.begin()),
std::make_move_iterator(requested.end()));

// Deduplication
std::sort(serials.begin(), serials.end());
serials.erase(std::unique(serials.begin(), serials.end()), serials.end());

serials = check_available_adb_serials(adb_path, serials, json::object());

for (const std::string& ser : serials) {
Device device;
device.name = e.name;
device.adb_path = path_to_utf8_string(adb_path);
device.adb_serial = ser;
device.adb_config = get_adb_config(e, ser).to_string();
device.adb_controller_type =
check_adb_controller_type(device.adb_path, device.adb_serial, device.adb_config);
result.emplace_back(std::move(device));
}
}

auto env_adb = boost::process::search_path("adb");

if (std::filesystem::exists(env_adb)) {
auto env_adb_devices = find_device_with_adb_impl(env_adb);
result.insert(
result.end(),
std::make_move_iterator(env_adb_devices.begin()),
std::make_move_iterator(env_adb_devices.end()));
}

// Deduplication
std::sort(result.begin(), result.end());
result.erase(std::unique(result.begin(), result.end()), result.end());

return result;
}

std::vector<Device> DeviceMgr::find_device_with_adb_impl(std::filesystem::path adb_path)
{
std::vector<Device> result;

auto serials = request_adb_serials(adb_path, json::object());

for (const std::string& ser : serials) {
Device device;
device.adb_path = path_to_utf8_string(adb_path);
device.name = device.adb_path;
device.adb_serial = ser;
device.adb_config = json::object().to_string();
device.adb_controller_type =
check_adb_controller_type(adb_path, device.adb_serial, device.adb_config);
result.emplace_back(std::move(device));
}
return result;
}

std::vector<DeviceMgr::Emulator> DeviceMgr::find_emulators() const
{
std::vector<Emulator> result;

auto all_processes = list_processes();
for (const auto& process : all_processes) {
auto find_it = std::ranges::find_if(const_data_, [&process](const auto& pair) -> bool {
return process.name.find(pair.second.keyword) != std::string::npos;
});
if (find_it == const_data_.cend()) {
continue;
}

Emulator emulator {
.name = find_it->first,
.process = process,
.const_data = find_it->second,
};
result.emplace_back(std::move(emulator));
}

LogInfo << VAR(result);

return result;
}

std::filesystem::path
DeviceMgr::get_adb_path(const EmulatorConstantData& emulator, os_pid pid) const
{
auto path_opt = get_process_path(pid);
if (!path_opt) {
return {};
}
auto dir = path_opt->parent_path();

for (const auto& adb_rel_path : emulator.adb_candidate_paths) {
auto adb_path = dir / adb_rel_path;
if (!std::filesystem::exists(adb_path)) {
continue;
}
return adb_path;
}
return {};
}

std::vector<std::string> DeviceMgr::request_adb_serials(
const std::filesystem::path& adb_path,
const json::value& adb_config) const
Expand Down Expand Up @@ -164,9 +297,10 @@ MaaAdbControllerType DeviceMgr::check_adb_controller_type(
std::ignore = adb_config;

constexpr MaaAdbControllerType kInputType = MaaAdbControllerType_Input_Preset_AutoDetect;
constexpr MaaAdbControllerType kScreencapType = MaaAdbControllerType_Screencap_FastestLosslessWay;
constexpr MaaAdbControllerType kScreencapType =
MaaAdbControllerType_Screencap_FastestLosslessWay;

return kInputType | kScreencapType;
}

MAA_TOOLKIT_NS_END
MAA_TOOLKIT_NS_END
26 changes: 22 additions & 4 deletions source/MaaToolkit/AdbDevice/DeviceMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <ostream>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

#include <meojson/json.hpp>
Expand All @@ -18,25 +19,41 @@ MAA_TOOLKIT_NS_BEGIN
class DeviceMgr : public MaaToolkitDeviceMgrAPI
{
public:
virtual ~DeviceMgr() noexcept override = default;
struct EmulatorConstantData
{
std::string keyword;
std::vector<std::filesystem::path> adb_candidate_paths;
std::vector<std::string> adb_common_serials;
};

public: // from MaaToolkitDeviceMgrAPI
struct Emulator
{
std::string name;
ProcessInfo process;
const EmulatorConstantData const_data;
};

public:
virtual ~DeviceMgr() override = default;

public: // from MaaToolkitDeviceMgrAPI
virtual bool post_find_device() override final;
virtual bool post_find_device_with_adb(std::filesystem::path adb_path) override final;
virtual bool is_find_completed() const override final;
virtual const std::optional<std::vector<Device>>& get_devices() override final;

protected:
virtual std::vector<Device> find_device_impl() = 0;
virtual std::vector<Device> find_device_with_adb_impl(std::filesystem::path adb_path) = 0;
virtual json::object
get_adb_config(const Emulator& emulator, const std::string& adb_serial) const;

protected:
void set_emulator_const_data(std::unordered_map<std::string, EmulatorConstantData> data);
std::vector<Device> find_device_impl();
std::vector<Device> find_device_with_adb_impl(std::filesystem::path adb_path);

std::vector<Emulator> find_emulators() const;
std::filesystem::path get_adb_path(const EmulatorConstantData& emulator, os_pid pid) const;

std::vector<std::string> request_adb_serials(
const std::filesystem::path& adb_path,
const json::value& adb_config) const;
Expand All @@ -56,6 +73,7 @@ class DeviceMgr : public MaaToolkitDeviceMgrAPI
private:
std::optional<std::vector<Device>> devices_;
std::future<std::vector<Device>> find_device_future_;
std::unordered_map<std::string, EmulatorConstantData> const_data_;
};

std::ostream& operator<<(std::ostream& os, const DeviceMgr::Emulator& emulator);
Expand Down
15 changes: 1 addition & 14 deletions source/MaaToolkit/AdbDevice/DeviceMgrLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,8 @@

#include "DeviceMgrLinux.h"

#include <tuple> // for std::ignore

MAA_TOOLKIT_NS_BEGIN

std::vector<Device> DeviceMgrLinux::find_device_impl()
{
return {};
}

std::vector<Device> DeviceMgrLinux::find_device_with_adb_impl(std::filesystem::path adb_path)
{
std::ignore = adb_path;
return {};
}

MAA_TOOLKIT_NS_END

#endif
#endif
6 changes: 1 addition & 5 deletions source/MaaToolkit/AdbDevice/DeviceMgrLinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ class DeviceMgrLinux
friend class SingletonHolder<DeviceMgrLinux>;

public:
virtual ~DeviceMgrLinux() noexcept override = default;

public: // from DeviceMgr
virtual std::vector<Device> find_device_impl() override;
virtual std::vector<Device> find_device_with_adb_impl(std::filesystem::path adb_path) override;
virtual ~DeviceMgrLinux() override = default;

private:
DeviceMgrLinux() = default;
Expand Down
Loading

0 comments on commit bd6c56b

Please sign in to comment.