Add DVT screenshot bindings

This commit is contained in:
Jackson Coxson
2025-10-21 08:47:07 -06:00
parent 779db7ecec
commit a7daac3a46
17 changed files with 326 additions and 17 deletions

View File

@@ -0,0 +1,38 @@
// Jackson Coxson
#pragma once
#include <idevice++/bindings.hpp>
#include <idevice++/dvt/remote_server.hpp>
#include <idevice++/result.hpp>
#include <memory>
namespace IdeviceFFI {
using LocSimPtr = std::unique_ptr<LocationSimulationHandle,
FnDeleter<LocationSimulationHandle, location_simulation_free>>;
class LocationSimulation {
public:
// Factory: borrows the RemoteServer; not consumed
static Result<LocationSimulation, FfiError> create(RemoteServer& server);
Result<void, FfiError> clear();
Result<void, FfiError> set(double latitude, double longitude);
~LocationSimulation() noexcept = default;
LocationSimulation(LocationSimulation&&) noexcept = default;
LocationSimulation& operator=(LocationSimulation&&) noexcept = default;
LocationSimulation(const LocationSimulation&) = delete;
LocationSimulation& operator=(const LocationSimulation&) = delete;
LocationSimulationHandle* raw() const noexcept { return handle_.get(); }
static LocationSimulation adopt(LocationSimulationHandle* h) noexcept {
return LocationSimulation(h);
}
private:
explicit LocationSimulation(LocationSimulationHandle* h) noexcept : handle_(h) {}
LocSimPtr handle_{};
};
} // namespace IdeviceFFI

View File

@@ -0,0 +1,41 @@
// Jackson Coxson
#pragma once
#include <idevice++/bindings.hpp>
#include <idevice++/dvt/remote_server.hpp>
#include <idevice++/result.hpp>
#include <memory>
namespace IdeviceFFI {
using ProcessControlPtr =
std::unique_ptr<ProcessControlHandle, FnDeleter<ProcessControlHandle, process_control_free>>;
class ProcessControl {
public:
// Factory: borrows the RemoteServer; not consumed
static Result<ProcessControl, FfiError> create(RemoteServer& server);
Result<u_int64_t, FfiError> launch_app(std::string bundle_id,
Option<std::vector<std::string>> env_vars,
Option<std::vector<std::string>> arguments,
bool start_suspended,
bool kill_existing);
Result<void, FfiError> kill_app(u_int64_t pid);
Result<void, FfiError> disable_memory_limit(u_int64_t pid);
~ProcessControl() noexcept = default;
ProcessControl(ProcessControl&&) noexcept = default;
ProcessControl& operator=(ProcessControl&&) noexcept = default;
ProcessControl(const ProcessControl&) = delete;
ProcessControl& operator=(const ProcessControl&) = delete;
ProcessControlHandle* raw() const noexcept { return handle_.get(); }
static ProcessControl adopt(ProcessControlHandle* h) noexcept { return ProcessControl(h); }
private:
explicit ProcessControl(ProcessControlHandle* h) noexcept : handle_(h) {}
ProcessControlPtr handle_{};
};
} // namespace IdeviceFFI

View File

@@ -0,0 +1,42 @@
// Jackson Coxson
#ifndef IDEVICE_REMOTE_SERVER_H
#define IDEVICE_REMOTE_SERVER_H
#pragma once
#include <idevice++/core_device_proxy.hpp>
#include <idevice++/idevice.hpp>
#include <idevice++/readwrite.hpp>
#include <idevice++/rsd.hpp>
#include <memory>
namespace IdeviceFFI {
using RemoteServerPtr =
std::unique_ptr<RemoteServerHandle, FnDeleter<RemoteServerHandle, remote_server_free>>;
class RemoteServer {
public:
// Factory: consumes the ReadWrite stream regardless of result
static Result<RemoteServer, FfiError> from_socket(ReadWrite&& rw);
// Factory: borrows adapter + handshake (neither is consumed)
static Result<RemoteServer, FfiError> connect_rsd(Adapter& adapter, RsdHandshake& rsd);
// RAII / moves
~RemoteServer() noexcept = default;
RemoteServer(RemoteServer&&) noexcept = default;
RemoteServer& operator=(RemoteServer&&) noexcept = default;
RemoteServer(const RemoteServer&) = delete;
RemoteServer& operator=(const RemoteServer&) = delete;
RemoteServerHandle* raw() const noexcept { return handle_.get(); }
static RemoteServer adopt(RemoteServerHandle* h) noexcept { return RemoteServer(h); }
private:
explicit RemoteServer(RemoteServerHandle* h) noexcept : handle_(h) {}
RemoteServerPtr handle_{};
};
} // namespace IdeviceFFI
#endif

View File

@@ -0,0 +1,49 @@
// Jackson Coxson
#pragma once
#include <cstring>
#include <idevice++/bindings.hpp>
#include <idevice++/dvt/remote_server.hpp>
#include <idevice++/result.hpp>
#include <memory>
#include <vector>
namespace IdeviceFFI {
using ScreenshotClientPtr =
std::unique_ptr<ScreenshotClientHandle,
FnDeleter<ScreenshotClientHandle, screenshot_client_free>>;
/// C++ wrapper around the ScreenshotClient FFI handle
///
/// Provides a high-level interface for capturing screenshots
/// from a connected iOS device through the DVT service.
class ScreenshotClient {
public:
/// Creates a new ScreenshotClient using an existing RemoteServer.
///
/// The RemoteServer is borrowed, not consumed.
static Result<ScreenshotClient, FfiError> create(RemoteServer& server);
/// Captures a screenshot and returns it as a PNG buffer.
///
/// On success, returns a vector containing PNG-encoded bytes.
Result<std::vector<uint8_t>, FfiError> capture();
~ScreenshotClient() noexcept = default;
ScreenshotClient(ScreenshotClient&&) noexcept = default;
ScreenshotClient& operator=(ScreenshotClient&&) noexcept = default;
ScreenshotClient(const ScreenshotClient&) = delete;
ScreenshotClient& operator=(const ScreenshotClient&) = delete;
ScreenshotClientHandle* raw() const noexcept { return handle_.get(); }
static ScreenshotClient adopt(ScreenshotClientHandle* h) noexcept {
return ScreenshotClient(h);
}
private:
explicit ScreenshotClient(ScreenshotClientHandle* h) noexcept : handle_(h) {}
ScreenshotClientPtr handle_{};
};
} // namespace IdeviceFFI