// Jackson Coxson #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace IdeviceFFI { using AppServicePtr = std::unique_ptr>; struct AppInfo { bool is_removable{}; std::string name; bool is_first_party{}; std::string path; std::string bundle_identifier; bool is_developer_app{}; std::optional bundle_version; bool is_internal{}; bool is_hidden{}; bool is_app_clip{}; std::optional version; }; struct LaunchResponse { uint32_t process_identifier_version{}; uint32_t pid{}; std::string executable_url; std::vector audit_token; // raw words }; struct ProcessToken { uint32_t pid{}; std::optional executable_url; }; struct SignalResponse { uint32_t pid{}; std::optional executable_url; uint64_t device_timestamp_ms{}; uint32_t signal{}; }; struct IconData { std::vector data; double icon_width{}; double icon_height{}; double minimum_width{}; double minimum_height{}; }; class AppService { public: // Factory: connect via RSD (borrows adapter & handshake) static std::optional connect_rsd(Adapter& adapter, RsdHandshake& rsd, FfiError& err); // Factory: from socket Box (consumes it). static std::optional from_readwrite_ptr(ReadWriteOpaque* consumed, FfiError& err); // nice ergonomic overload: consume a C++ ReadWrite by releasing it static std::optional from_readwrite(ReadWrite&& rw, FfiError& err); // API std::optional> list_apps(bool app_clips, bool removable, bool hidden, bool internal, bool default_apps, FfiError& err) const; std::optional launch(const std::string& bundle_id, const std::vector& argv, bool kill_existing, bool start_suspended, FfiError& err); std::optional> list_processes(FfiError& err) const; bool uninstall(const std::string& bundle_id, FfiError& err); std::optional send_signal(uint32_t pid, uint32_t signal, FfiError& err); std::optional fetch_icon(const std::string& bundle_id, float width, float height, float scale, bool allow_placeholder, FfiError& err); // RAII / moves ~AppService() noexcept = default; AppService(AppService&&) noexcept = default; AppService& operator=(AppService&&) noexcept = default; AppService(const AppService&) = delete; AppService& operator=(const AppService&) = delete; AppServiceHandle* raw() const noexcept { return handle_.get(); } static AppService adopt(AppServiceHandle* h) noexcept { return AppService(h); } private: explicit AppService(AppServiceHandle* h) noexcept : handle_(h) {} AppServicePtr handle_{}; }; } // namespace IdeviceFFI