Skip to content

feat: android native support#1222

Merged
MistEO merged 20 commits intomainfrom
feat/native-android-support
Mar 31, 2026
Merged

feat: android native support#1222
MistEO merged 20 commits intomainfrom
feat/native-android-support

Conversation

@Aliothmoon
Copy link
Copy Markdown
Member

@Aliothmoon Aliothmoon commented Mar 22, 2026

仅构建 libMaaAndroidNativeControlUnit.so 先不参与MaaFramework Controller流程
用于在 MAA-Meow 中复用

Summary by Sourcery

添加一个 Android 原生控制单元库,并将其接入构建和控制器基础设施,但暂未集成到主 MaaFramework 控制器流程中。

新功能:

  • 引入一个 Android 原生控制单元共享库,用于封装外部 Android 库,实现屏幕捕获、触控、按键输入和应用生命周期控制。
  • 暴露一个 C API,用于创建、销毁和管理 Android 原生控制单元的线程,并可通过 JSON 进行配置(库路径、屏幕分辨率、显示 ID、强制停止行为)。

增强:

  • 扩展核心 CMake 和源码配置,以便可选地包含 Android 原生控制器,并在通用控制单元 API 中暴露其句柄类型。

构建:

  • 添加 WITH_ANDROID_NATIVE_CONTROLLER CMake 选项以及相关子目录、目标和依赖项,用于构建 Android 原生控制单元共享库。
  • 更新 CMake 预设和 GitHub Actions 中的 Android 构建步骤,使用按架构划分的 Android 预设和安装路径,并导出 ANDROID_NDK_ROOT 供下游工具使用。

CI:

  • 调整 Android CI 工作流,使其依赖按架构命名的 CMake 预设,而不是手动指定 Android 工具链参数,并从按架构划分的构建目录中进行安装。
Original summary in English

Summary by Sourcery

Add an Android native control unit library and wire it into the build and controller infrastructure, without yet integrating it into the main MaaFramework controller flow.

New Features:

  • Introduce an Android native control unit shared library that wraps an external Android library for screen capture, touch, key input, and app lifecycle control.
  • Expose a C API for creating, destroying, and managing threads for the Android native control unit, configurable via JSON (library path, screen resolution, display ID, force-stop behavior).

Enhancements:

  • Extend core CMake and source configuration to optionally include the Android native controller and expose its handle type in the common control unit API.

Build:

  • Add a WITH_ANDROID_NATIVE_CONTROLLER CMake option and associated subdirectory, target, and dependencies for building the Android native control unit shared library.
  • Update CMake presets and GitHub Actions Android build steps to use architecture-specific Android presets and install paths, and to export ANDROID_NDK_ROOT for downstream tools.

CI:

  • Adjust the Android CI workflow to rely on named CMake presets per-architecture instead of manual Android toolchain flags and to install from architecture-specific build directories.

Summary by Sourcery

添加一个基于全新 Android 原生控制单元库的 Android 原生控制器,并将其接入现有框架、绑定层以及构建/CI 流程,通过仅限 Android 的构建选项进行控制。

新特性:

  • 引入一个 Android 原生控制单元共享库,用于封装外部 Android 库,实现 Android 上的截图、触摸、按键输入以及应用生命周期控制。
  • 提供 C 和 Python API,可根据 JSON 配置创建 Android 原生控制器;配置中可指定外部库路径、分辨率、显示 ID,以及是否执行强制停止行为。

增强功能:

  • 扩展通用控制单元 API 和库持有器以支持 Android 原生控制单元,包括在控制器代理中处理 Android 特有的线程附加/分离逻辑。
  • 在集成接口和 control-methods 文档中补充 Android 原生控制器的使用方法和配置说明。

构建:

  • 新增 WITH_ANDROID_NATIVE_CONTROLLER CMake 选项,并将 MaaAndroidNativeControlUnit 目标接入核心构建和安装流程,仅在 Android 平台启用。
  • 调整 Android CMake 预设和 GitHub Actions 中的 Android 任务,以使用按架构划分的预设,导出 ANDROID_NDK_ROOT,并从特定架构的构建目录进行安装。

CI:

  • 更新 Android CI,使用按架构划分的预设和路径进行构建和安装,而不再依赖手动指定工具链参数。
Original summary in English

Summary by Sourcery

Add an Android-native controller backed by a new Android native control unit library and wire it into the framework, bindings, and build/CI, gated behind an Android-only build option.

New Features:

  • Introduce an Android native control unit shared library that wraps an external Android library for screenshots, touch, key input, and app lifecycle control on Android.
  • Expose a C and Python API to create Android-native controllers from JSON configuration specifying the external library path, resolution, display ID, and force-stop behavior.

Enhancements:

  • Extend the common control unit API and library holder to support the Android native control unit, including Android-specific thread attach/detach handling in the controller agent.
  • Document the Android native controller usage and configuration in the integrated interface and control-methods documentation.

Build:

  • Add a WITH_ANDROID_NATIVE_CONTROLLER CMake option and wire the MaaAndroidNativeControlUnit target into the core build and installation flow, limited to Android platforms.
  • Adjust Android CMake presets and GitHub Actions Android jobs to use per-architecture presets, export ANDROID_NDK_ROOT, and install from architecture-specific build directories.

CI:

  • Update Android CI to build and install using architecture-specific presets and paths instead of manual toolchain flags.
Original summary in English

Summary by Sourcery

添加一个基于全新 Android 原生控制单元库的 Android 原生控制器,并将其接入现有框架、绑定层以及构建/CI 流程,通过仅限 Android 的构建选项进行控制。

新特性:

  • 引入一个 Android 原生控制单元共享库,用于封装外部 Android 库,实现 Android 上的截图、触摸、按键输入以及应用生命周期控制。
  • 提供 C 和 Python API,可根据 JSON 配置创建 Android 原生控制器;配置中可指定外部库路径、分辨率、显示 ID,以及是否执行强制停止行为。

增强功能:

  • 扩展通用控制单元 API 和库持有器以支持 Android 原生控制单元,包括在控制器代理中处理 Android 特有的线程附加/分离逻辑。
  • 在集成接口和 control-methods 文档中补充 Android 原生控制器的使用方法和配置说明。

构建:

  • 新增 WITH_ANDROID_NATIVE_CONTROLLER CMake 选项,并将 MaaAndroidNativeControlUnit 目标接入核心构建和安装流程,仅在 Android 平台启用。
  • 调整 Android CMake 预设和 GitHub Actions 中的 Android 任务,以使用按架构划分的预设,导出 ANDROID_NDK_ROOT,并从特定架构的构建目录进行安装。

CI:

  • 更新 Android CI,使用按架构划分的预设和路径进行构建和安装,而不再依赖手动指定工具链参数。
Original summary in English

Summary by Sourcery

Add an Android-native controller backed by a new Android native control unit library and wire it into the framework, bindings, and build/CI, gated behind an Android-only build option.

New Features:

  • Introduce an Android native control unit shared library that wraps an external Android library for screenshots, touch, key input, and app lifecycle control on Android.
  • Expose a C and Python API to create Android-native controllers from JSON configuration specifying the external library path, resolution, display ID, and force-stop behavior.

Enhancements:

  • Extend the common control unit API and library holder to support the Android native control unit, including Android-specific thread attach/detach handling in the controller agent.
  • Document the Android native controller usage and configuration in the integrated interface and control-methods documentation.

Build:

  • Add a WITH_ANDROID_NATIVE_CONTROLLER CMake option and wire the MaaAndroidNativeControlUnit target into the core build and installation flow, limited to Android platforms.
  • Adjust Android CMake presets and GitHub Actions Android jobs to use per-architecture presets, export ANDROID_NDK_ROOT, and install from architecture-specific build directories.

CI:

  • Update Android CI to build and install using architecture-specific presets and paths instead of manual toolchain flags.
Original summary in English

Summary by Sourcery

添加一个基于全新 Android 原生控制单元库的 Android 原生控制器,并将其接入现有框架、绑定层以及构建/CI 流程,通过仅限 Android 的构建选项进行控制。

新特性:

  • 引入一个 Android 原生控制单元共享库,用于封装外部 Android 库,实现 Android 上的截图、触摸、按键输入以及应用生命周期控制。
  • 提供 C 和 Python API,可根据 JSON 配置创建 Android 原生控制器;配置中可指定外部库路径、分辨率、显示 ID,以及是否执行强制停止行为。

增强功能:

  • 扩展通用控制单元 API 和库持有器以支持 Android 原生控制单元,包括在控制器代理中处理 Android 特有的线程附加/分离逻辑。
  • 在集成接口和 control-methods 文档中补充 Android 原生控制器的使用方法和配置说明。

构建:

  • 新增 WITH_ANDROID_NATIVE_CONTROLLER CMake 选项,并将 MaaAndroidNativeControlUnit 目标接入核心构建和安装流程,仅在 Android 平台启用。
  • 调整 Android CMake 预设和 GitHub Actions 中的 Android 任务,以使用按架构划分的预设,导出 ANDROID_NDK_ROOT,并从特定架构的构建目录进行安装。

CI:

  • 更新 Android CI,使用按架构划分的预设和路径进行构建和安装,而不再依赖手动指定工具链参数。
Original summary in English

Summary by Sourcery

Add an Android-native controller backed by a new Android native control unit library and wire it into the framework, bindings, and build/CI, gated behind an Android-only build option.

New Features:

  • Introduce an Android native control unit shared library that wraps an external Android library for screenshots, touch, key input, and app lifecycle control on Android.
  • Expose a C and Python API to create Android-native controllers from JSON configuration specifying the external library path, resolution, display ID, and force-stop behavior.

Enhancements:

  • Extend the common control unit API and library holder to support the Android native control unit, including Android-specific thread attach/detach handling in the controller agent.
  • Document the Android native controller usage and configuration in the integrated interface and control-methods documentation.

Build:

  • Add a WITH_ANDROID_NATIVE_CONTROLLER CMake option and wire the MaaAndroidNativeControlUnit target into the core build and installation flow, limited to Android platforms.
  • Adjust Android CMake presets and GitHub Actions Android jobs to use per-architecture presets, export ANDROID_NDK_ROOT, and install from architecture-specific build directories.

CI:

  • Update Android CI to build and install using architecture-specific presets and paths instead of manual toolchain flags.
Original summary in English

Summary by Sourcery

添加一个基于全新 Android 原生控制单元库的 Android 原生控制器,并将其接入现有框架、绑定层以及构建/CI 流程,通过仅限 Android 的构建选项进行控制。

新特性:

  • 引入一个 Android 原生控制单元共享库,用于封装外部 Android 库,实现 Android 上的截图、触摸、按键输入以及应用生命周期控制。
  • 提供 C 和 Python API,可根据 JSON 配置创建 Android 原生控制器;配置中可指定外部库路径、分辨率、显示 ID,以及是否执行强制停止行为。

增强功能:

  • 扩展通用控制单元 API 和库持有器以支持 Android 原生控制单元,包括在控制器代理中处理 Android 特有的线程附加/分离逻辑。
  • 在集成接口和 control-methods 文档中补充 Android 原生控制器的使用方法和配置说明。

构建:

  • 新增 WITH_ANDROID_NATIVE_CONTROLLER CMake 选项,并将 MaaAndroidNativeControlUnit 目标接入核心构建和安装流程,仅在 Android 平台启用。
  • 调整 Android CMake 预设和 GitHub Actions 中的 Android 任务,以使用按架构划分的预设,导出 ANDROID_NDK_ROOT,并从特定架构的构建目录进行安装。

CI:

  • 更新 Android CI,使用按架构划分的预设和路径进行构建和安装,而不再依赖手动指定工具链参数。
Original summary in English

Summary by Sourcery

Add an Android-native controller backed by a new Android native control unit library and wire it into the framework, bindings, and build/CI, gated behind an Android-only build option.

New Features:

  • Introduce an Android native control unit shared library that wraps an external Android library for screenshots, touch, key input, and app lifecycle control on Android.
  • Expose a C and Python API to create Android-native controllers from JSON configuration specifying the external library path, resolution, display ID, and force-stop behavior.

Enhancements:

  • Extend the common control unit API and library holder to support the Android native control unit, including Android-specific thread attach/detach handling in the controller agent.
  • Document the Android native controller usage and configuration in the integrated interface and control-methods documentation.

Build:

  • Add a WITH_ANDROID_NATIVE_CONTROLLER CMake option and wire the MaaAndroidNativeControlUnit target into the core build and installation flow, limited to Android platforms.
  • Adjust Android CMake presets and GitHub Actions Android jobs to use per-architecture presets, export ANDROID_NDK_ROOT, and install from architecture-specific build directories.

CI:

  • Update Android CI to build and install using architecture-specific presets and paths instead of manual toolchain flags.

@Aliothmoon Aliothmoon marked this pull request as draft March 22, 2026 20:59
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • AndroidNativeControlUnitMgr 中,MethodParam 的字符串字段(例如 package_nameclient_typetext)是通过函数参数的 std::string::c_str() 设置的;如果外部库异步使用这些指针,就会产生悬空指针——建议在文档中明确或在实现上强制只进行同步使用,或者把这些字符串存储在对象成员所拥有的存储中,以确保它们在调用期间及必要时在调用之后的生命周期是有保障的。
  • AndroidNativeControlUnitMgr 中的 scroll(int dx, int dy) 方法不像其他 ControlUnit 的重写方法那样带有 override 说明符;如果它是用于实现 ControlUnitAPI 中的虚函数,建议添加 override,既保持一致性,又能在编译期发现签名不匹配的问题。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AndroidNativeControlUnitMgr`, the `MethodParam` string fields (e.g., `package_name`, `client_type`, `text`) are set to `std::string::c_str()` from function parameters; if the external library uses these pointers asynchronously, this will dangle—consider documenting or enforcing synchronous use, or storing the strings in member-owned storage so their lifetime is guaranteed during and after the call as needed.
- The `scroll(int dx, int dy)` method in `AndroidNativeControlUnitMgr` lacks an `override` specifier unlike the other ControlUnit overrides; if it is meant to implement a virtual in `ControlUnitAPI`, consider adding `override` for consistency and to catch signature mismatches at compile time.

## Individual Comments

### Comment 1
<location path="source/MaaAndroidNativeControlUnit/Manager/AndroidNativeControlUnitMgr.h" line_range="53" />
<code_context>
+    bool key_down(int key) override;
+    bool key_up(int key) override;
+
+    bool scroll(int dx, int dy);
+
+    bool inactive() override;
</code_context>
<issue_to_address>
**issue (bug_risk):** The scroll method is missing an override specifier and may not match the base class signature.

Please add `override` to `scroll` and verify its full signature (including constness and parameter types) exactly matches the declaration in `ControlUnitAPI`. Otherwise, calls via a `ControlUnitAPI*` may not dispatch to this implementation as intended.
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • In AndroidNativeControlUnitMgr, the MethodParam string fields (e.g., package_name, client_type, text) are set to std::string::c_str() from function parameters; if the external library uses these pointers asynchronously, this will dangle—consider documenting or enforcing synchronous use, or storing the strings in member-owned storage so their lifetime is guaranteed during and after the call as needed.
  • The scroll(int dx, int dy) method in AndroidNativeControlUnitMgr lacks an override specifier unlike the other ControlUnit overrides; if it is meant to implement a virtual in ControlUnitAPI, consider adding override for consistency and to catch signature mismatches at compile time.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AndroidNativeControlUnitMgr`, the `MethodParam` string fields (e.g., `package_name`, `client_type`, `text`) are set to `std::string::c_str()` from function parameters; if the external library uses these pointers asynchronously, this will dangle—consider documenting or enforcing synchronous use, or storing the strings in member-owned storage so their lifetime is guaranteed during and after the call as needed.
- The `scroll(int dx, int dy)` method in `AndroidNativeControlUnitMgr` lacks an `override` specifier unlike the other ControlUnit overrides; if it is meant to implement a virtual in `ControlUnitAPI`, consider adding `override` for consistency and to catch signature mismatches at compile time.

## Individual Comments

### Comment 1
<location path="source/MaaAndroidNativeControlUnit/Manager/AndroidNativeControlUnitMgr.h" line_range="53" />
<code_context>
+    bool key_down(int key) override;
+    bool key_up(int key) override;
+
+    bool scroll(int dx, int dy);
+
+    bool inactive() override;
</code_context>
<issue_to_address>
**issue (bug_risk):** The scroll method is missing an override specifier and may not match the base class signature.

Please add `override` to `scroll` and verify its full signature (including constness and parameter types) exactly matches the declaration in `ControlUnitAPI`. Otherwise, calls via a `ControlUnitAPI*` may not dispatch to this implementation as intended.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@MistEO
Copy link
Copy Markdown
Member

MistEO commented Mar 27, 2026

ControlUnit 重构了下,有冲突了 #1235

@Aliothmoon
Copy link
Copy Markdown
Member Author

ControlUnit 重构了下,有冲突了 #1235

OK

@Aliothmoon Aliothmoon force-pushed the feat/native-android-support branch from c783b8b to df114d0 Compare March 27, 2026 11:30
@Aliothmoon Aliothmoon requested review from Copilot March 27, 2026 12:36
@Aliothmoon
Copy link
Copy Markdown
Member Author

@sourcery-ai review it

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题

供 AI 代理使用的提示词
请根据本次代码审查中的评论进行修改:

## 单条评论

### 评论 1
<location path="source/MaaAndroidNativeControlUnit/General/AndroidExternalLib.h" line_range="147-156" />
<code_context>
+
+MAA_NS_BEGIN
+
+class AndroidNativeExternalLibraryHolder : public LibraryHolder<AndroidNativeExternalLibraryHolder>
+{
+public:
+    static std::optional<AndroidNativeNS::AndroidExternalFunctions>
+        create_functions(const std::filesystem::path& library_path);
+
+private:
+    static constexpr std::string get_locked_pixels_func_name_ = "GetLockedPixels";
+    static constexpr std::string unlock_pixels_func_name_ = "UnlockPixels";
+    static constexpr std::string attach_thread_func_name_ = "AttachThread";
+    static constexpr std::string detach_thread_func_name_ = "DetachThread";
+    static constexpr std::string dispatch_input_message_func_name_ = "DispatchInputMessage";
+};
+
</code_context>
<issue_to_address>
**issue (bug_risk):** `static constexpr std::string` 成员是非良构的;请改用 `const char*``inline const std::string``std::string` 不是字面量类型,因此这些声明无法作为 `static constexpr` 通过编译。可以使用:

```cpp
static constexpr const char* get_locked_pixels_func_name_ = "GetLockedPixels";
// ... etc
```

或者,如果你确实需要 `std::string` 且使用的是 C++17 及以上:

```cpp
static inline const std::string get_locked_pixels_func_name_ = "GetLockedPixels";
// ... etc
```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,请考虑分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="source/MaaAndroidNativeControlUnit/General/AndroidExternalLib.h" line_range="147-156" />
<code_context>
+
+MAA_NS_BEGIN
+
+class AndroidNativeExternalLibraryHolder : public LibraryHolder<AndroidNativeExternalLibraryHolder>
+{
+public:
+    static std::optional<AndroidNativeNS::AndroidExternalFunctions>
+        create_functions(const std::filesystem::path& library_path);
+
+private:
+    static constexpr std::string get_locked_pixels_func_name_ = "GetLockedPixels";
+    static constexpr std::string unlock_pixels_func_name_ = "UnlockPixels";
+    static constexpr std::string attach_thread_func_name_ = "AttachThread";
+    static constexpr std::string detach_thread_func_name_ = "DetachThread";
+    static constexpr std::string dispatch_input_message_func_name_ = "DispatchInputMessage";
+};
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The `static constexpr std::string` members are ill-formed; use `const char*` or `inline const std::string` instead.

`std::string` is not a literal type, so these declarations won’t compile as `static constexpr`. Use either:

```cpp
static constexpr const char* get_locked_pixels_func_name_ = "GetLockedPixels";
// ... etc
```

or, if you specifically need `std::string` and are on C++17+:

```cpp
static inline const std::string get_locked_pixels_func_name_ = "GetLockedPixels";
// ... etc
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an Android-native ControlUnit shared library and wires it into the optional build/CI flow so it can be reused by external Android projects (e.g., MAA-Meow), without integrating it into the main MaaFramework controller selection/runtime flow yet.

Changes:

  • Introduce MaaAndroidNativeControlUnit shared library with a ControlUnitAPI implementation and a small C API for creation + JNI thread attach/detach.
  • Add WITH_ANDROID_NATIVE_CONTROLLER build option and hook the new target into the source/ and MaaFramework/ CMake dependency graph (Android-only).
  • Update Android CMake presets and GitHub Actions Android build to use arch-specific presets and export ANDROID_NDK_ROOT.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
source/MaaFramework/CMakeLists.txt Make MaaFramework depend on the new Android native control unit when enabled.
source/CMakeLists.txt Conditionally add the new control unit subdirectory to the build.
source/MaaAndroidNativeControlUnit/CMakeLists.txt Define the new shared library target and install rules.
source/MaaAndroidNativeControlUnit/Manager/AndroidNativeControlUnitMgr.h New Android native ControlUnit manager interface (implements ControlUnitAPI).
source/MaaAndroidNativeControlUnit/Manager/AndroidNativeControlUnitMgr.cpp New Android native ControlUnit behavior (screencap + input dispatch).
source/MaaAndroidNativeControlUnit/General/ScopedThreadAttach.h RAII helper for JNI thread attach/detach.
source/MaaAndroidNativeControlUnit/General/AndroidExternalLib.h External Android library ABI wrapper definitions + loader holder.
source/MaaAndroidNativeControlUnit/General/AndroidExternalLib.cpp External library dynamic loading + function resolution and dispatch.
source/MaaAndroidNativeControlUnit/API/AndroidNativeControlUnitAPI.cpp Public C API to create/destroy and manage thread attach/detach.
include/MaaControlUnit/AndroidNativeControlUnitAPI.h New exported header for the Android native control unit C API.
include/MaaControlUnit/MaaControlUnitAPI.h Add the new Android native control unit API header to the umbrella include.
include/MaaControlUnit/ControlUnitAPI.h Add the MaaAndroidNativeControlUnitHandle handle type alias.
CMakeLists.txt Add WITH_ANDROID_NATIVE_CONTROLLER option and auto-disable it off-Android.
CMakePresets.json Add arch-specific Android presets (x86_64, arm64-v8a) using ANDROID_NDK_ROOT.
.github/workflows/build.yml Switch Android CI build/install to use the new presets and export ANDROID_NDK_ROOT.

@Aliothmoon Aliothmoon requested a review from MistEO March 27, 2026 16:07
@Aliothmoon Aliothmoon marked this pull request as ready for review March 27, 2026 17:23
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了两个问题,并给出了一些高层次的反馈:

  • AndroidNativeExternalLibraryHolder 中,静态函数名成员被声明为 static constexpr std::string,在很多标准库组合下这是不合法的;建议将它们改为 inline static constexpr const char[](或 constexpr std::string_view),并将这些值传给 get_function
  • AndroidNativeControlUnitMgr::screencap 中,抓取到的帧始终被当作 CV_8UC3 来处理,而没有参考 ImageFormat 或由 stride 隐含的每像素字节数;如果外部库返回的是 RGBA 或其它格式,就会导致数据被误读,因此更安全的做法是检查 ImageFormat 并进行相应的转换,或者在文档中明确并通过断言保证期望的格式。
面向 AI Agent 的提示
请根据以下代码审查意见进行修改:

## 整体意见
-`AndroidNativeExternalLibraryHolder` 中,静态函数名成员被声明为 `static constexpr std::string`,在很多标准库组合下这是不合法的;建议将它们改为 `inline static constexpr const char[]`(或 `constexpr std::string_view`),并将这些值传给 `get_function`-`AndroidNativeControlUnitMgr::screencap` 中,抓取到的帧始终被当作 `CV_8UC3` 来处理,而没有参考 `ImageFormat` 或由 `stride` 隐含的每像素字节数;如果外部库返回的是 RGBA 或其它格式,就会导致数据被误读,因此更安全的做法是检查 `ImageFormat` 并进行相应的转换,或者在文档中明确并通过断言保证期望的格式。

## 单条评论

### 评论 1
<location path=".github/workflows/build.yml" line_range="406-415" />
<code_context>
+            - name: Build MAA
</code_context>
<issue_to_address>
**suggestion (bug_risk):** 预设名称和安装时的 build_dir 逻辑存在重复,可能随着时间产生偏移。

`matrix.arch` → 预设名称 → 构建目录 的映射被定义了两次:一次在 `Build MAA``preset`)中,一次在 `Install``build_dir`)中。如果两者有任何一处单独修改,`cmake --install` 可能会指向错误的目录。请将这部分映射逻辑集中管理(例如,从 `matrix.arch` 推导出一个构建目录环境变量,并在两个步骤中共享使用),以保持同步。

建议实现方式:

```
            - name: Build MAA
              shell: bash
              run: |
                  if [[ "${{ matrix.arch }}" == "x86_64" ]]; then
                      preset='NinjaMulti Android x64'
                      build_dir='build/android/x64'
                  else
                      preset='NinjaMulti Android arm64'
                      build_dir='build/android/arm64'
                  fi

                  # Export for subsequent steps (e.g. Install)
                  echo "MAA_BUILD_PRESET=$preset" >> "$GITHUB_ENV"
                  echo "MAA_BUILD_DIR=$build_dir" >> "$GITHUB_ENV"

                  cmake --preset "$preset" --build "$build_dir"

```

为了彻底落实该建议并避免 `Build MAA``Install` 之间的偏移,你还应该:

1. 找到当前在 `Install` 步骤中基于 `matrix.arch`(或预设)推导 `build_dir` 的代码,并移除这段本地映射逻辑。
2.`Install` 步骤中对本地计算 `build_dir` 的所有使用,替换为集中管理的环境变量:
   - 例如,对 CMake 安装目录使用 `${{ env.MAA_BUILD_DIR }}``cmake --install "${{ env.MAA_BUILD_DIR }}"`(对其它使用构建目录的地方同理)。
3. 如果实际构建目录路径与 `build/android/x64``build/android/arm64` 不同,请在更新后的 `Build MAA` 步骤中相应调整 `build_dir` 的赋值,使两个步骤保持一致。
</issue_to_address>

### 评论 2
<location path="CMakeLists.txt" line_range="12" />
<code_context>
 option(WITH_ADB_CONTROLLER "build with adb controller" ON)
 option(WITH_WIN32_CONTROLLER "build with win32 controller" ON)
 option(WITH_MACOS_CONTROLLER "build with macOS controller" ON)
+option(WITH_ANDROID_NATIVE_CONTROLLER "build with android native controller" ON)
 option(WITH_CUSTOM_CONTROLLER "build with custom controller" ON)
 option(WITH_PLAYCOVER_CONTROLLER "build with PlayCover controller for macOS" ON)
</code_context>
<issue_to_address>
**suggestion (typo):** 建议在选项描述中将 "Android" 首字母大写,以保持一致性与正确性。

该帮助字符串中使用了小写的 "android",而其它消息中都是以专有名词形式书写的 "Android"。请将此描述更新为 "build with Android native controller" 以保持一致。

```suggestion
option(WITH_ANDROID_NATIVE_CONTROLLER "build with Android native controller" ON)
```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的 Review 有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会基于你的反馈改进后续 Review。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • In AndroidNativeExternalLibraryHolder, the static function name members are declared as static constexpr std::string, which is ill-formed on many standard/library combinations; consider making them inline static constexpr const char[] (or constexpr std::string_view) and passing those to get_function instead.
  • In AndroidNativeControlUnitMgr::screencap, the captured frame is always treated as CV_8UC3 without consulting the ImageFormat or bytes-per-pixel implied by stride; if the external library returns RGBA or other formats this will misinterpret the data, so it would be safer either to check ImageFormat and convert appropriately or to document and assert the expected format.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AndroidNativeExternalLibraryHolder`, the static function name members are declared as `static constexpr std::string`, which is ill-formed on many standard/library combinations; consider making them `inline static constexpr const char[]` (or `constexpr std::string_view`) and passing those to `get_function` instead.
- In `AndroidNativeControlUnitMgr::screencap`, the captured frame is always treated as `CV_8UC3` without consulting the `ImageFormat` or bytes-per-pixel implied by `stride`; if the external library returns RGBA or other formats this will misinterpret the data, so it would be safer either to check `ImageFormat` and convert appropriately or to document and assert the expected format.

## Individual Comments

### Comment 1
<location path=".github/workflows/build.yml" line_range="406-415" />
<code_context>
+            - name: Build MAA
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Preset name and install build_dir logic are duplicated and can drift over time.

The `matrix.arch` → preset name → build directory mapping is defined twice: once in `Build MAA` (`preset`) and again in `Install` (`build_dir`). If either changes independently, `cmake --install` may target the wrong directory. Please centralize this mapping (e.g., derive a single build-dir env var from `matrix.arch` and use it for both steps) to keep them in sync.

Suggested implementation:

```
            - name: Build MAA
              shell: bash
              run: |
                  if [[ "${{ matrix.arch }}" == "x86_64" ]]; then
                      preset='NinjaMulti Android x64'
                      build_dir='build/android/x64'
                  else
                      preset='NinjaMulti Android arm64'
                      build_dir='build/android/arm64'
                  fi

                  # Export for subsequent steps (e.g. Install)
                  echo "MAA_BUILD_PRESET=$preset" >> "$GITHUB_ENV"
                  echo "MAA_BUILD_DIR=$build_dir" >> "$GITHUB_ENV"

                  cmake --preset "$preset" --build "$build_dir"

```

To fully implement the suggestion and avoid drift between `Build MAA` and `Install`, you should also:

1. Locate the `Install` step that currently derives `build_dir` based on `matrix.arch` (or the preset) and remove that local mapping logic.
2. Replace any usage of the locally computed `build_dir` in the `Install` step with the centralized environment variable:
   - Use `${{ env.MAA_BUILD_DIR }}` for the CMake install directory, for example:
     `cmake --install "${{ env.MAA_BUILD_DIR }}"` (and similarly for any other references to the build directory).
3. If the actual build directory paths differ from `build/android/x64` and `build/android/arm64`, adjust the `build_dir` assignments in the updated `Build MAA` step to match your existing layout so that both steps remain consistent.
</issue_to_address>

### Comment 2
<location path="CMakeLists.txt" line_range="12" />
<code_context>
 option(WITH_ADB_CONTROLLER "build with adb controller" ON)
 option(WITH_WIN32_CONTROLLER "build with win32 controller" ON)
 option(WITH_MACOS_CONTROLLER "build with macOS controller" ON)
+option(WITH_ANDROID_NATIVE_CONTROLLER "build with android native controller" ON)
 option(WITH_CUSTOM_CONTROLLER "build with custom controller" ON)
 option(WITH_PLAYCOVER_CONTROLLER "build with PlayCover controller for macOS" ON)
</code_context>
<issue_to_address>
**suggestion (typo):** Consider capitalizing "Android" in the option description for consistency and correctness.

The help string uses lowercase "android" while other messages use capitalized "Android" as a proper noun. Please update this description to "build with Android native controller" for consistency.

```suggestion
option(WITH_ANDROID_NATIVE_CONTROLLER "build with Android native controller" ON)
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

#include "MaaControlUnit/ControlUnitAPI.h"
#include "MaaFramework/MaaDef.h"

#ifdef __ANDROID__
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些接口不放在平台宏里吧,参考 win32 和 playcover,impl 里报错就行了

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

virtual bool find_device(/*out*/ std::vector<std::string>& devices) = 0;
};

#ifdef __ANDROID__
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些也是,还有后面的

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

return false;
}

if (loaded_) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些玩要自己写吗,能不能用 LibraryHolder?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改好了,之间不太会用LibraryHolder,包了一层

Comment on lines +18 to +23
uint32_t width;
uint32_t height;
uint32_t stride;
uint32_t length;
void* data;
void* frame_ref;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

初始化一下

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

uint32_t length;
void* data;
void* frame_ref;
} FrameInfo;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要 C 风格.jpg

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

后面还有一些

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

return false;
}

std::this_thread::sleep_for(std::chrono::milliseconds(50));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看看能不能用 MaaControllerFeature_UseMouseDownAndUpInsteadOfClick 和 MaaControllerFeature_UseKeyboardDownAndUpInsteadOfClick

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swipe 和 key 的也是

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

"jobs": 16
}
]
"version": 5,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

怎么给格式化了()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一定是Clion干的!(乆)

@Aliothmoon Aliothmoon requested a review from MistEO March 31, 2026 02:05
@Aliothmoon
Copy link
Copy Markdown
Member Author

@sourcery-ai review it

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你好——我发现了 1 个问题,并给出了一些整体性的反馈:

  • 针对 Android 的线程附加逻辑目前分散在 ControllerAgent(通过 ScopedAndroidNativeThreadAttachdynamic_pointer_cast)以及控制单元本身之间;建议将这套 RAII 式的 attach/detach 处理集中到 Android 原生的控制单元层(或一个共享的辅助工具)中,这样可以让 ControllerAgent 保持平台无关性,并避免引入 Android 特定的 #ifdef/类型转换。
面向 AI 代理的提示词
Please address the comments from this code review:

## Overall Comments
- The Android-specific thread attach logic is currently split between `ControllerAgent` (via `ScopedAndroidNativeThreadAttach` and a `dynamic_pointer_cast`) and the control unit itself; consider centralizing this RAII attach/detach handling in the Android-native control unit layer (or a shared helper) so `ControllerAgent` can remain platform-agnostic and avoid the Android-specific `#ifdef`/cast.

## Individual Comments

### Comment 1
<location path="docs/en_us/2.2-IntegratedInterfaceOverview.md" line_range="267" />
<code_context>
+
+Create an Android native controller backed by `MaaAndroidNativeControlUnit` for native screenshot and input on Android.
+
+> `screen_resolution` must match both the control unit's raw screenshot resolution and touch coordinate space, otherwise screencap fails immediately.
+
 ### MaaCustomControllerCreate
</code_context>
<issue_to_address>
**nitpick (typo):** Consider fixing the comma splice in this sentence for clearer grammar.

The phrase `, otherwise` joins two independent clauses and creates a comma splice. Consider instead: `...touch coordinate space; otherwise, screencap fails immediately.` or `...touch coordinate space. Otherwise, screencap fails immediately.`

```suggestion
> `screen_resolution` must match both the control unit's raw screenshot resolution and touch coordinate space; otherwise, screencap fails immediately.
```
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的代码审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The Android-specific thread attach logic is currently split between ControllerAgent (via ScopedAndroidNativeThreadAttach and a dynamic_pointer_cast) and the control unit itself; consider centralizing this RAII attach/detach handling in the Android-native control unit layer (or a shared helper) so ControllerAgent can remain platform-agnostic and avoid the Android-specific #ifdef/cast.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Android-specific thread attach logic is currently split between `ControllerAgent` (via `ScopedAndroidNativeThreadAttach` and a `dynamic_pointer_cast`) and the control unit itself; consider centralizing this RAII attach/detach handling in the Android-native control unit layer (or a shared helper) so `ControllerAgent` can remain platform-agnostic and avoid the Android-specific `#ifdef`/cast.

## Individual Comments

### Comment 1
<location path="docs/en_us/2.2-IntegratedInterfaceOverview.md" line_range="267" />
<code_context>
+
+Create an Android native controller backed by `MaaAndroidNativeControlUnit` for native screenshot and input on Android.
+
+> `screen_resolution` must match both the control unit's raw screenshot resolution and touch coordinate space, otherwise screencap fails immediately.
+
 ### MaaCustomControllerCreate
</code_context>
<issue_to_address>
**nitpick (typo):** Consider fixing the comma splice in this sentence for clearer grammar.

The phrase `, otherwise` joins two independent clauses and creates a comma splice. Consider instead: `...touch coordinate space; otherwise, screencap fails immediately.` or `...touch coordinate space. Otherwise, screencap fails immediately.`

```suggestion
> `screen_resolution` must match both the control unit's raw screenshot resolution and touch coordinate space; otherwise, screencap fails immediately.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@MistEO MistEO merged commit e48b97d into main Mar 31, 2026
14 checks passed
@MistEO MistEO deleted the feat/native-android-support branch March 31, 2026 06:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants