mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-20 11:06:46 +08:00
[feat] add host platform metadata and iOS platform placeholders
This commit is contained in:
@@ -116,11 +116,18 @@ struct CursorState {
|
||||
CursorHiddenReason hidden_reason;
|
||||
};
|
||||
|
||||
enum class HostPlatform { Unknown, Windows, MacOS, Linux, IOS };
|
||||
|
||||
const char* HostPlatformName(HostPlatform platform);
|
||||
HostPlatform ParseHostPlatform(const std::string& platform);
|
||||
|
||||
struct HostInfo {
|
||||
char host_name[64];
|
||||
std::size_t host_name_size;
|
||||
// Optional; an empty string means the peer version is unknown.
|
||||
char app_version[64];
|
||||
// Optional on the wire; missing or unrecognized values are unknown.
|
||||
HostPlatform platform;
|
||||
char** display_list;
|
||||
std::size_t display_num;
|
||||
int* left;
|
||||
@@ -219,7 +226,8 @@ struct HostDisplay {
|
||||
RemoteAction MakeHostInformation(const std::string& host_name,
|
||||
const std::vector<HostDisplay>& displays,
|
||||
bool supports_privacy_screen,
|
||||
const std::string& app_version = {});
|
||||
const std::string& app_version = {},
|
||||
HostPlatform platform = HostPlatform::Unknown);
|
||||
|
||||
} // namespace crossdesk
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ void ResetHostInfo(HostInfo& info) {
|
||||
info.host_name[0] = '\0';
|
||||
info.host_name_size = 0;
|
||||
info.app_version[0] = '\0';
|
||||
info.platform = HostPlatform::Unknown;
|
||||
info.display_list = nullptr;
|
||||
info.display_num = 0;
|
||||
info.left = nullptr;
|
||||
@@ -49,10 +50,29 @@ char* DuplicateString(const std::string& value) {
|
||||
|
||||
} // namespace
|
||||
|
||||
const char* HostPlatformName(HostPlatform platform) {
|
||||
switch (platform) {
|
||||
case HostPlatform::Windows: return "windows";
|
||||
case HostPlatform::MacOS: return "macos";
|
||||
case HostPlatform::Linux: return "linux";
|
||||
case HostPlatform::IOS: return "ios";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
HostPlatform ParseHostPlatform(const std::string& platform) {
|
||||
if (platform == "windows") return HostPlatform::Windows;
|
||||
if (platform == "macos") return HostPlatform::MacOS;
|
||||
if (platform == "linux") return HostPlatform::Linux;
|
||||
if (platform == "ios") return HostPlatform::IOS;
|
||||
return HostPlatform::Unknown;
|
||||
}
|
||||
|
||||
RemoteAction MakeHostInformation(const std::string& host_name,
|
||||
const std::vector<HostDisplay>& displays,
|
||||
bool supports_privacy_screen,
|
||||
const std::string& app_version) {
|
||||
const std::string& app_version,
|
||||
HostPlatform platform) {
|
||||
RemoteAction action{};
|
||||
action.type = ControlType::host_infomation;
|
||||
ResetHostInfo(action.i);
|
||||
@@ -73,6 +93,7 @@ RemoteAction MakeHostInformation(const std::string& host_name,
|
||||
}
|
||||
|
||||
action.i.supports_privacy_screen = supports_privacy_screen;
|
||||
action.i.platform = platform;
|
||||
const std::size_t name_size =
|
||||
std::min(host_name.size(), sizeof(action.i.host_name) - 1);
|
||||
std::memcpy(action.i.host_name, host_name.data(), name_size);
|
||||
@@ -192,6 +213,7 @@ std::string RemoteAction::ToJson(const RemoteAction& action) {
|
||||
object["host_info"] = {
|
||||
{"host_name", action.i.host_name},
|
||||
{"app_version", action.i.app_version},
|
||||
{"platform", HostPlatformName(action.i.platform)},
|
||||
{"display_num", action.i.display_num},
|
||||
{"displays", displays},
|
||||
{"supports_privacy_screen", action.i.supports_privacy_screen},
|
||||
@@ -368,6 +390,11 @@ bool RemoteAction::FromJson(const std::string& json_string,
|
||||
ResetHostInfo(output.i);
|
||||
owns_host_info = true;
|
||||
const auto& host_info_object = object.at("host_info");
|
||||
const auto platform = host_info_object.find("platform");
|
||||
if (platform != host_info_object.end() && platform->is_string()) {
|
||||
output.i.platform =
|
||||
ParseHostPlatform(platform->get_ref<const std::string&>());
|
||||
}
|
||||
const auto app_version = host_info_object.find("app_version");
|
||||
if (app_version != host_info_object.end() && app_version->is_string()) {
|
||||
const auto& version = app_version->get_ref<const std::string&>();
|
||||
|
||||
@@ -135,6 +135,7 @@ int main() {
|
||||
host.type = crossdesk::ControlType::host_infomation;
|
||||
std::strcpy(host.i.host_name, "Test Mac");
|
||||
std::strcpy(host.i.app_version, "1.5.3-2-20260928");
|
||||
host.i.platform = crossdesk::HostPlatform::MacOS;
|
||||
host.i.host_name_size = std::strlen(host.i.host_name);
|
||||
host.i.display_list = display_names;
|
||||
host.i.display_num = 1;
|
||||
@@ -147,6 +148,7 @@ int main() {
|
||||
parsed_host.i.display_num == 1 &&
|
||||
std::string(parsed_host.i.host_name) == "Test Mac" &&
|
||||
std::string(parsed_host.i.app_version) == "1.5.3-2-20260928" &&
|
||||
parsed_host.i.platform == crossdesk::HostPlatform::MacOS &&
|
||||
std::string(parsed_host.i.display_list[0]) ==
|
||||
"Built-in Display" &&
|
||||
parsed_host.i.right[0] == 2560 &&
|
||||
@@ -162,6 +164,48 @@ int main() {
|
||||
crossdesk::FreeRemoteAction(parsed_host);
|
||||
crossdesk::FreeRemoteAction(advertised);
|
||||
|
||||
// The platform is optional metadata, not a requirement for connecting.
|
||||
for (const auto& platform : std::vector<std::string>{
|
||||
"windows", "linux", "macos", "ios", "unknown"}) {
|
||||
advertised = crossdesk::MakeHostInformation(
|
||||
"Host", {}, true, "1.5.3-20260928",
|
||||
crossdesk::ParseHostPlatform(platform));
|
||||
const auto message = advertised.to_json();
|
||||
ok &= Expect(message.find("\"platform\":\"" + platform + "\"") !=
|
||||
std::string::npos,
|
||||
"host factory must advertise the canonical platform string");
|
||||
ok &= Expect(parsed_host.from_json(message) &&
|
||||
crossdesk::HostPlatformName(parsed_host.i.platform) == platform,
|
||||
"host platform must survive a JSON round trip");
|
||||
crossdesk::FreeRemoteAction(parsed_host);
|
||||
crossdesk::FreeRemoteAction(advertised);
|
||||
}
|
||||
|
||||
for (const auto& platform_field : std::vector<std::string>{
|
||||
"", ",\"platform\":null", ",\"platform\":123", ",\"platform\":true",
|
||||
",\"platform\":[]", ",\"platform\":{}", ",\"platform\":\"\"",
|
||||
",\"platform\":\"future-os\"", ",\"platform\":\"windows\\u0000extra\"",
|
||||
",\"platform\":\"" + std::string(256, 'x') + "\""}) {
|
||||
const auto message =
|
||||
"{\"type\":3,\"host_info\":{\"host_name\":\"Legacy\","
|
||||
"\"display_num\":1,\"displays\":[{\"name\":\"Screen\",\"left\":0,"
|
||||
"\"top\":0,\"right\":1920,\"bottom\":1080}]" + platform_field + "}}";
|
||||
parsed_host.i.platform = crossdesk::HostPlatform::Windows;
|
||||
ok &= Expect(parsed_host.from_json(message) &&
|
||||
parsed_host.i.platform == crossdesk::HostPlatform::Unknown &&
|
||||
std::string(parsed_host.i.host_name) == "Legacy" &&
|
||||
parsed_host.i.display_num == 1 &&
|
||||
parsed_host.i.right[0] == 1920 && parsed_host.i.bottom[0] == 1080,
|
||||
"missing or invalid platform must be unknown without losing host info");
|
||||
crossdesk::FreeRemoteAction(parsed_host);
|
||||
}
|
||||
advertised = crossdesk::MakeHostInformation("Legacy", {}, false);
|
||||
ok &= Expect(advertised.i.platform == crossdesk::HostPlatform::Unknown &&
|
||||
advertised.to_json().find("\"platform\":\"unknown\"") !=
|
||||
std::string::npos,
|
||||
"unspecified platform must be advertised as unknown");
|
||||
crossdesk::FreeRemoteAction(advertised);
|
||||
|
||||
// Missing and malformed optional versions must not break legacy host info.
|
||||
for (const auto& version_field : std::vector<std::string>{
|
||||
"", ",\"app_version\":null", ",\"app_version\":123",
|
||||
|
||||
Reference in New Issue
Block a user