You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
5.4 KiB
167 lines
5.4 KiB
// Copyright 2019 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "cast/common/channel/message_util.h"
|
|
|
|
#include <sstream>
|
|
#include <utility>
|
|
|
|
#include "cast/common/channel/virtual_connection.h"
|
|
#include "util/json/json_serialization.h"
|
|
#include "util/json/json_value.h"
|
|
#include "util/osp_logging.h"
|
|
|
|
#if defined(__APPLE__) || defined(__MACH__)
|
|
#include <TargetConditionals.h>
|
|
#endif
|
|
|
|
namespace openscreen {
|
|
namespace cast {
|
|
namespace {
|
|
|
|
using ::cast::channel::CastMessage;
|
|
|
|
// The value used for "sdkType" in a virtual CONNECT request. Historically, this
|
|
// value was used in Chrome's C++ impl even though "2" refers to the Media
|
|
// Router Extension.
|
|
constexpr int kVirtualConnectSdkType = 2;
|
|
|
|
// The value used for "connectionType" in a virtual CONNECT request. This value
|
|
// stands for CONNECTION_TYPE_LOCAL.
|
|
constexpr int kVirtualConnectTypeLocal = 1;
|
|
|
|
// The value to be set as the "platform" value in a virtual CONNECT request.
|
|
// Source (in Chromium source tree):
|
|
// src/third_party/metrics_proto/cast_logs.proto
|
|
enum VirtualConnectPlatformValue {
|
|
kOtherPlatform = 0,
|
|
kAndroid = 1,
|
|
kIOS = 2,
|
|
kWindows = 3,
|
|
kMacOSX = 4,
|
|
kChromeOS = 5,
|
|
kLinux = 6,
|
|
kCastDevice = 7,
|
|
};
|
|
|
|
#if defined(__APPLE__) || defined(__MACH__)
|
|
constexpr VirtualConnectPlatformValue GetVirtualConnectPlatformMacFlavor() {
|
|
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
|
return kIOS;
|
|
#else
|
|
return kMacOSX;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
constexpr VirtualConnectPlatformValue GetVirtualConnectPlatform() {
|
|
// Based on //build/build_config.h in the Chromium project. The order of these
|
|
// matters!
|
|
#if defined(__ANDROID__)
|
|
return kAndroid;
|
|
#elif defined(__APPLE__) || defined(__MACH__)
|
|
return GetVirtualConnectPlatformMacFlavor();
|
|
#elif defined(_WIN32) || defined(_WIN64)
|
|
return kWindows;
|
|
#elif defined(OS_CHROMEOS)
|
|
// Note: OS_CHROMEOS is defined via the compiler's command line in Chromium
|
|
// embedder builds by Chromium's //build/config/linux:runtime_library config.
|
|
return kChromeOS;
|
|
#elif defined(__linux__)
|
|
return kLinux;
|
|
#else
|
|
return kOtherPlatform;
|
|
#endif
|
|
}
|
|
|
|
CastMessage MakeConnectionMessage(const std::string& source_id,
|
|
const std::string& destination_id) {
|
|
CastMessage connect_message;
|
|
connect_message.set_protocol_version(kDefaultOutgoingMessageVersion);
|
|
connect_message.set_source_id(source_id);
|
|
connect_message.set_destination_id(destination_id);
|
|
connect_message.set_namespace_(kConnectionNamespace);
|
|
return connect_message;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::string ToString(AppAvailabilityResult availability) {
|
|
switch (availability) {
|
|
case AppAvailabilityResult::kAvailable:
|
|
return "Available";
|
|
case AppAvailabilityResult::kUnavailable:
|
|
return "Unavailable";
|
|
case AppAvailabilityResult::kUnknown:
|
|
return "Unknown";
|
|
default:
|
|
OSP_NOTREACHED();
|
|
}
|
|
}
|
|
|
|
CastMessage MakeSimpleUTF8Message(const std::string& namespace_,
|
|
std::string payload) {
|
|
CastMessage message;
|
|
message.set_protocol_version(kDefaultOutgoingMessageVersion);
|
|
message.set_namespace_(namespace_);
|
|
message.set_payload_type(::cast::channel::CastMessage_PayloadType_STRING);
|
|
message.set_payload_utf8(std::move(payload));
|
|
return message;
|
|
}
|
|
|
|
CastMessage MakeConnectMessage(const std::string& source_id,
|
|
const std::string& destination_id) {
|
|
CastMessage connect_message =
|
|
MakeConnectionMessage(source_id, destination_id);
|
|
connect_message.set_payload_type(
|
|
::cast::channel::CastMessage_PayloadType_STRING);
|
|
|
|
// Historically, the CONNECT message was meant to come from a Chrome browser.
|
|
// However, this library could be embedded in any app. So, properties like
|
|
// user agent, application version, etc. are not known here.
|
|
static constexpr char kUnknownVersion[] = "Unknown (Open Screen)";
|
|
|
|
Json::Value message(Json::objectValue);
|
|
message[kMessageKeyType] = CastMessageTypeToString(CastMessageType::kConnect);
|
|
for (int i = 0; i <= 3; ++i) {
|
|
message[kMessageKeyProtocolVersionList][i] =
|
|
::cast::channel::CastMessage_ProtocolVersion_CASTV2_1_0 + i;
|
|
}
|
|
message[kMessageKeyUserAgent] = kUnknownVersion;
|
|
message[kMessageKeyConnType] =
|
|
static_cast<int>(VirtualConnection::Type::kStrong);
|
|
message[kMessageKeyOrigin] = Json::Value(Json::objectValue);
|
|
|
|
Json::Value sender_info(Json::objectValue);
|
|
sender_info[kMessageKeySdkType] = kVirtualConnectSdkType;
|
|
sender_info[kMessageKeyVersion] = kUnknownVersion;
|
|
sender_info[kMessageKeyBrowserVersion] = kUnknownVersion;
|
|
sender_info[kMessageKeyPlatform] = GetVirtualConnectPlatform();
|
|
sender_info[kMessageKeyConnectionType] = kVirtualConnectTypeLocal;
|
|
message[kMessageKeySenderInfo] = std::move(sender_info);
|
|
|
|
connect_message.set_payload_utf8(json::Stringify(std::move(message)).value());
|
|
return connect_message;
|
|
}
|
|
|
|
CastMessage MakeCloseMessage(const std::string& source_id,
|
|
const std::string& destination_id) {
|
|
CastMessage close_message = MakeConnectionMessage(source_id, destination_id);
|
|
close_message.set_payload_type(
|
|
::cast::channel::CastMessage_PayloadType_STRING);
|
|
close_message.set_payload_utf8(R"!({"type": "CLOSE"})!");
|
|
return close_message;
|
|
}
|
|
|
|
std::string MakeUniqueSessionId(const char* prefix) {
|
|
static int next_id = 10000;
|
|
|
|
std::ostringstream oss;
|
|
oss << prefix << '-' << (next_id++);
|
|
return oss.str();
|
|
}
|
|
|
|
} // namespace cast
|
|
} // namespace openscreen
|