Commit a23e2e59 authored by Jordan Bayles's avatar Jordan Bayles Committed by Commit Bot

(Re)implement Open Screen's ChromeUdpSocket class

This patch uncomments out and updates/fixes the ChromeUdpSocket class,
part of Open Screen's embedder platform code.

Change-Id: Ia66f2e92336f99202b33be7c2636f805e2e0dca3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1851230Reviewed-by: default avatarRamin Halavati <rhalavati@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Commit-Queue: Jordan Bayles <jophba@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707953}
parent 8ae8728a
......@@ -152,13 +152,15 @@ static_library("router") {
"providers/openscreen/network_service_async_packet_sender.h",
"providers/openscreen/network_service_quic_packet_writer.cc",
"providers/openscreen/network_service_quic_packet_writer.h",
"providers/openscreen/platform/chrome_platform_client.cc",
"providers/openscreen/platform/chrome_platform_client.h",
"providers/openscreen/platform/chrome_udp_socket.cc",
"providers/openscreen/platform/chrome_udp_socket.h",
"providers/openscreen/platform/logging.cc",
"providers/openscreen/platform/task_runner.cc",
"providers/openscreen/platform/task_runner.h",
"providers/openscreen/platform/time.cc",
"providers/openscreen/platform/trace_logging_platform.cc",
"providers/openscreen/platform/udp_socket.cc",
"providers/openscreen/platform/udp_socket.h",
]
configs +=
......
// Copyright (c) 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 "chrome/browser/media/router/providers/openscreen/platform/chrome_platform_client.h"
#include <mutex>
namespace media_router {
ChromePlatformClient::~ChromePlatformClient() {
// TODO(jophba, rwkeane): Handle threads and safely shutting down singletons.
}
// static
void ChromePlatformClient::Create(
std::unique_ptr<network::mojom::NetworkContext> network_context,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
PlatformClient::SetInstance(new ChromePlatformClient(
std::move(network_context), std::move(task_runner)));
}
// static
ChromePlatformClient* ChromePlatformClient::GetInstance() {
return reinterpret_cast<ChromePlatformClient*>(PlatformClient::GetInstance());
}
// static
void ChromePlatformClient::ShutDown() {
PlatformClient::ShutDown();
}
openscreen::platform::TaskRunner* ChromePlatformClient::GetTaskRunner() {
return task_runner_.get();
}
ChromePlatformClient::ChromePlatformClient(
std::unique_ptr<network::mojom::NetworkContext> network_context,
scoped_refptr<base::SequencedTaskRunner> task_runner)
: network_context_(std::move(network_context)),
task_runner_(
new openscreen::platform::ChromeTaskRunner(std::move(task_runner))) {}
} // namespace media_router
// 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.
#ifndef CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_CHROME_PLATFORM_CLIENT_H_
#define CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_CHROME_PLATFORM_CLIENT_H_
#include <memory>
#include "chrome/browser/media/router/providers/openscreen/platform/task_runner.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "third_party/openscreen/src/platform/api/platform_client.h"
namespace media_router {
class ChromePlatformClient : public openscreen::platform::PlatformClient {
public:
// NOTE: The initialization and shutdown routines are not threadsafe.
static void Create(
std::unique_ptr<network::mojom::NetworkContext> network_context,
scoped_refptr<base::SequencedTaskRunner> task_runner);
static ChromePlatformClient* GetInstance();
static void ShutDown();
// These methods are threadsafe.
network::mojom::NetworkContext* network_context() const {
return network_context_.get();
}
// PlatformClient overrides.
openscreen::platform::TaskRunner* GetTaskRunner() override;
protected:
~ChromePlatformClient() override;
private:
ChromePlatformClient(
std::unique_ptr<network::mojom::NetworkContext> network_context,
scoped_refptr<base::SequencedTaskRunner> task_runner);
const std::unique_ptr<network::mojom::NetworkContext> network_context_;
const std::unique_ptr<openscreen::platform::ChromeTaskRunner> task_runner_;
};
} // namespace media_router
#endif // CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_CHROME_PLATFORM_CLIENT_H_
// 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 "chrome/browser/media/router/providers/openscreen/platform/chrome_udp_socket.h"
#include <algorithm>
#include <utility>
#include "base/bind.h"
#include "base/containers/span.h"
#include "chrome/browser/media/router/providers/openscreen/platform/chrome_platform_client.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/address_family.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "third_party/openscreen/src/platform/api/udp_packet.h"
// Open Screen expects us to provide linked implementations of some of its
// static create methods, which have to be in their namespace.
namespace openscreen {
namespace platform {
// static
ErrorOr<UdpSocketUniquePtr> UdpSocket::Create(
TaskRunner* task_runner,
Client* client,
const IPEndpoint& local_endpoint) {
network::mojom::NetworkContext* const network_context =
media_router::ChromePlatformClient::GetInstance()->network_context();
if (!network_context) {
return Error::Code::kInitializationFailure;
}
mojo::PendingRemote<network::mojom::UDPSocketListener> listener_remote;
mojo::PendingReceiver<network::mojom::UDPSocketListener> pending_listener =
listener_remote.InitWithNewPipeAndPassReceiver();
mojo::Remote<network::mojom::UDPSocket> socket;
network_context->CreateUDPSocket(socket.BindNewPipeAndPassReceiver(),
std::move(listener_remote));
return ErrorOr<UdpSocketUniquePtr>(
std::make_unique<media_router::ChromeUdpSocket>(
task_runner, client, local_endpoint, std::move(socket),
std::move(pending_listener)));
}
} // namespace platform
} // namespace openscreen
namespace media_router {
namespace {
using openscreen::Error;
using openscreen::IPAddress;
using openscreen::IPEndpoint;
using openscreen::platform::TaskRunner;
using openscreen::platform::UdpPacket;
using openscreen::platform::UdpSocket;
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("open_screen_message", R"(
semantics {
sender: "Open Screen"
description:
"Open Screen messages are used by the third_party Open Screen "
"library, in accordance to the specification defined by the Open "
"Screen protocol. The protocol is available publicly at: "
"https://github.com/webscreens/openscreenprotocol"
trigger:
"Any message that needs to be sent or received by the Open Screen "
"library."
data:
"Messages defined by the Open Screen Protocol specification."
destination: OTHER
destination_other:
"The connection is made to an Open Screen endpoint on the LAN "
"selected by the user, i.e. via a dialog."
}
policy {
cookies_allowed: NO
setting:
"This request cannot be disabled, but it would not be sent if user "
"does not connect to a Open Screen endpoint on the local network."
policy_exception_justification: "Not implemented."
})");
const net::IPAddress ToChromeNetAddress(const IPAddress& address) {
switch (address.version()) {
case IPAddress::Version::kV4: {
std::array<uint8_t, IPAddress::kV4Size> bytes_v4;
address.CopyToV4(bytes_v4.data());
return net::IPAddress(bytes_v4.data(), bytes_v4.size());
}
case IPAddress::Version::kV6: {
std::array<uint8_t, IPAddress::kV6Size> bytes_v6;
address.CopyToV6(bytes_v6.data());
return net::IPAddress(bytes_v6.data(), bytes_v6.size());
}
}
}
const net::IPEndPoint ToChromeNetEndpoint(const IPEndpoint& endpoint) {
return net::IPEndPoint(ToChromeNetAddress(endpoint.address), endpoint.port);
}
IPAddress::Version ToOpenScreenVersion(const net::AddressFamily family) {
switch (family) {
case net::AddressFamily::ADDRESS_FAMILY_IPV6:
return IPAddress::Version::kV6;
case net::AddressFamily::ADDRESS_FAMILY_IPV4:
return IPAddress::Version::kV4;
case net::AddressFamily::ADDRESS_FAMILY_UNSPECIFIED:
NOTREACHED();
return IPAddress::Version::kV4;
}
}
const IPEndpoint ToOpenScreenEndpoint(const net::IPEndPoint& endpoint) {
const IPAddress::Version version = ToOpenScreenVersion(endpoint.GetFamily());
return IPEndpoint{IPAddress{version, endpoint.address().bytes().data()},
endpoint.port()};
}
} // namespace
ChromeUdpSocket::ChromeUdpSocket(
TaskRunner* task_runner,
Client* client,
const IPEndpoint& local_endpoint,
mojo::Remote<network::mojom::UDPSocket> udp_socket,
mojo::PendingReceiver<network::mojom::UDPSocketListener> pending_listener)
: UdpSocket(task_runner, client),
local_endpoint_(local_endpoint),
udp_socket_(std::move(udp_socket)),
pending_listener_(std::move(pending_listener)) {}
ChromeUdpSocket::~ChromeUdpSocket() = default;
bool ChromeUdpSocket::IsIPv4() const {
return local_endpoint_.address.IsV4();
}
bool ChromeUdpSocket::IsIPv6() const {
return local_endpoint_.address.IsV6();
}
IPEndpoint ChromeUdpSocket::GetLocalEndpoint() const {
return local_endpoint_;
}
void ChromeUdpSocket::Bind() {
udp_socket_->Bind(ToChromeNetEndpoint(local_endpoint_),
nullptr /* socket_options */,
base::BindOnce(&ChromeUdpSocket::BindCallback,
weak_ptr_factory_.GetWeakPtr()));
}
// mojom::UDPSocket doesn't have a concept of network interface indices, so
// this is a noop.
void ChromeUdpSocket::SetMulticastOutboundInterface(
openscreen::platform::NetworkInterfaceIndex ifindex) {}
// mojom::UDPSocket doesn't have a concept of network interface indices, so
// the ifindex argument is ignored here.
void ChromeUdpSocket::JoinMulticastGroup(
const IPAddress& address,
openscreen::platform::NetworkInterfaceIndex ifindex) {
const auto join_address = ToChromeNetAddress(address);
udp_socket_->JoinGroup(join_address,
base::BindOnce(&ChromeUdpSocket::JoinGroupCallback,
weak_ptr_factory_.GetWeakPtr()));
}
void ChromeUdpSocket::SendMessage(const void* data,
size_t length,
const IPEndpoint& dest) {
const auto send_to_address = ToChromeNetEndpoint(dest);
base::span<const uint8_t> data_span(static_cast<const uint8_t*>(data),
length);
udp_socket_->SendTo(
send_to_address, data_span,
net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
base::BindOnce(&ChromeUdpSocket::SendCallback,
weak_ptr_factory_.GetWeakPtr()));
}
// mojom::UDPSocket doesn't have a concept of DSCP, so this is a noop.
void ChromeUdpSocket::SetDscp(openscreen::platform::UdpSocket::DscpMode state) {
}
void ChromeUdpSocket::OnReceived(
int32_t net_result,
const base::Optional<net::IPEndPoint>& source_endpoint,
base::Optional<base::span<const uint8_t>> data) {
if (net_result != net::OK) {
OnRead(Error::Code::kSocketReadFailure);
} else if (data) {
// TODO(jophba): fixup when UdpPacket provides a data copy constructor.
UdpPacket packet;
packet.reserve(data.value().size_bytes());
std::copy(data.value().begin(), data.value().end(),
std::back_inserter(packet));
packet.set_socket(this);
if (source_endpoint) {
packet.set_source(ToOpenScreenEndpoint(source_endpoint.value()));
}
OnRead(std::move(packet));
}
udp_socket_->ReceiveMore(1);
}
void ChromeUdpSocket::BindCallback(
int32_t result,
const base::Optional<net::IPEndPoint>& address) {
if (result != net::OK) {
OnError(Error(Error::Code::kSocketBindFailure, net::ErrorToString(result)));
return;
}
// This is an approximate value for number of packets, and may need to be
// adjusted when we have real world data.
constexpr int kNumPacketsReadyFor = 30;
udp_socket_->ReceiveMore(kNumPacketsReadyFor);
if (address) {
local_endpoint_ = ToOpenScreenEndpoint(address.value());
if (pending_listener_.is_valid()) {
listener_.Bind(std::move(pending_listener_));
}
}
}
void ChromeUdpSocket::JoinGroupCallback(int32_t result) {
if (result != net::OK) {
OnError(Error(Error::Code::kSocketOptionSettingFailure,
net::ErrorToString(result)));
}
}
void ChromeUdpSocket::SendCallback(int32_t result) {
if (result != net::OK) {
OnError(Error(Error::Code::kSocketSendFailure, net::ErrorToString(result)));
}
}
} // namespace media_router
// 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.
#ifndef CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_CHROME_UDP_SOCKET_H_
#define CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_CHROME_UDP_SOCKET_H_
#include <memory>
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/mojom/udp_socket.mojom.h"
#include "third_party/openscreen/src/platform/api/udp_socket.h"
#include "third_party/openscreen/src/platform/base/error.h"
namespace net {
class IPEndPoint;
}
namespace media_router {
class ChromeUdpSocket : public openscreen::platform::UdpSocket,
network::mojom::UDPSocketListener {
public:
ChromeUdpSocket(openscreen::platform::TaskRunner* task_runner,
Client* client,
const openscreen::IPEndpoint& local_endpoint,
mojo::Remote<network::mojom::UDPSocket> udp_socket,
mojo::PendingReceiver<network::mojom::UDPSocketListener>
pending_listener);
~ChromeUdpSocket() final;
// Implementations of openscreen::platform::UdpSocket methods.
bool IsIPv4() const final;
bool IsIPv6() const final;
openscreen::IPEndpoint GetLocalEndpoint() const final;
void Bind() final;
void SetMulticastOutboundInterface(
openscreen::platform::NetworkInterfaceIndex ifindex) final;
void JoinMulticastGroup(
const openscreen::IPAddress& address,
openscreen::platform::NetworkInterfaceIndex ifindex) final;
void SendMessage(const void* data,
size_t length,
const openscreen::IPEndpoint& dest) final;
void SetDscp(openscreen::platform::UdpSocket::DscpMode state) final;
// network::mojom::UDPSocketListener overrides:
void OnReceived(int32_t net_result,
const base::Optional<net::IPEndPoint>& source_endpoint,
base::Optional<base::span<const uint8_t>> data) override;
private:
void BindCallback(int32_t result,
const base::Optional<net::IPEndPoint>& address);
void JoinGroupCallback(int32_t result);
void SendCallback(int32_t result);
// The local endpoint can change as a result of bind calls.
openscreen::IPEndpoint local_endpoint_;
mojo::Remote<network::mojom::UDPSocket> udp_socket_;
// The pending listener gets converted to a proper Receiver when this socket
// gets bound.
mojo::PendingReceiver<network::mojom::UDPSocketListener> pending_listener_;
mojo::Receiver<network::mojom::UDPSocketListener> listener_{this};
base::WeakPtrFactory<ChromeUdpSocket> weak_ptr_factory_{this};
};
} // namespace media_router
#endif // CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_CHROME_UDP_SOCKET_H_
// 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 "chrome/browser/media/router/providers/openscreen/platform/udp_socket.h"
// #include <utility>
// #include "base/bind.h"
// #include "base/containers/span.h"
// #include "net/base/address_family.h"
// #include "net/base/ip_endpoint.h"
namespace openscreen {
namespace platform {
// namespace {
// constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
// net::DefineNetworkTrafficAnnotation("open_screen_message", R"(
// semantics {
// sender: "Open Screen"
// description:
// "Open Screen messages are used by the third_party Open Screen "
// "library, in accordance to the specification defined by the Open "
// "Screen protocol. The protocol is available publicly at: "
// "https://github.com/webscreens/openscreenprotocol"
// trigger:
// "Any message that needs to be sent or received by the Open Screen "
// "library."
// data:
// "Messages defined by the Open Screen Protocol specification."
// destination: OTHER
// destination_other:
// "The connection is made to an Open Screen endpoint on the LAN "
// "selected by the user, i.e. via a dialog."
// }
// policy {
// cookies_allowed: NO
// setting:
// "This request cannot be disabled, but it would not be sent if user
// " "does not connect to a Open Screen endpoint on the local
// network." policy_exception_justification: "Not implemented."
// })");
// const auto kMutableTrafficAnnotation =
// net::CreateMutableNetworkTrafficAnnotationTag(
// kTrafficAnnotation.unique_id_hash_code);
// const net::IPAddress ToChromeNetAddress(const IPAddress& address) {
// if (address.IsV4()) {
// std::array<uint8_t, IPAddress::kV4Size> bytes_v4;
// address.CopyToV4(bytes_v4.data());
// return net::IPAddress(bytes_v4.data(), bytes_v4.size());
// }
// std::array<uint8_t, IPAddress::kV6Size> bytes_v6;
// address.CopyToV6(bytes_v6.data());
// return net::IPAddress(bytes_v6.data(), bytes_v6.size());
// }
// const net::IPEndPoint ToChromeNetEndpoint(const IPEndpoint& endpoint) {
// return net::IPEndPoint(ToChromeNetAddress(endpoint.address), endpoint.port);
// }
// } // namespace
// // static
// ErrorOr<UdpSocketUniquePtr> UdpSocket::Create(
// TaskRunner* task_runner,
// Client* client,
// const IPEndpoint& local_endpoint) {
// // TODO(jophba): implement create method.
// NOTIMPLEMENTED();
// return Error::None();
// }
// ChromeUdpSocket::ChromeUdpSocket(std::unique_ptr<network::UDPSocket>
// udp_socket,
// TaskRunner* task_runner,
// Client* client,
// const IPEndpoint& local_endpoint)
// : UdpSocket(task_runner, client),
// local_endpoint_(ToChromeNetEndpoint(local_endpoint)),
// udp_socket_(std::move(udp_socket)) {}
// ChromeUdpSocket::~ChromeUdpSocket() = default;
// bool ChromeUdpSocket::IsIPv4() const {
// return local_endpoint_.GetFamily() ==
// net::AddressFamily::ADDRESS_FAMILY_IPV4;
// }
// bool ChromeUdpSocket::IsIPv6() const {
// return local_endpoint_.GetFamily() ==
// net::AddressFamily::ADDRESS_FAMILY_IPV6;
// }
// Error ChromeUdpSocket::Bind() {
// udp_socket_->Bind(local_endpoint_, nullptr,
// base::BindOnce(&ChromeUdpSocket::BindCallback,
// weak_ptr_factory_.GetWeakPtr()));
// // Errors are reported using the callback message, so no error to return
// here. return Error::None();
// }
// // TODO(jophba): how does the network service handle multiple interfaces?
// // mojom::UDPSocket doesn't have a concept of network interface indices, so
// // the ifindex argument is ignored here.
// Error ChromeUdpSocket::SetMulticastOutboundInterface(
// NetworkInterfaceIndex ifindex) {
// return Error::Code::kNotImplemented;
// }
// // mojom::UDPSocket doesn't have a concept of network interface indices, so
// // the ifindex argument is ignored here.
// Error ChromeUdpSocket::JoinMulticastGroup(const IPAddress& address,
// NetworkInterfaceIndex ifindex) {
// const auto join_address = ToChromeNetAddress(address);
// udp_socket_->JoinGroup(join_address,
// base::BindOnce(&ChromeUdpSocket::JoinGroupCallback,
// weak_ptr_factory_.GetWeakPtr()));
// // Errors are reported using the callback message, so no error to return
// here. return Error::None();
// }
// // mojom::UDPSocket has the receiver set before construction, so receiving
// // messages in this fashion doesn't actually make sense.
// ErrorOr<UdpPacket> ChromeUdpSocket::ReceiveMessage() {
// return Error::Code::kNotImplemented;
// }
// Error ChromeUdpSocket::SendMessage(const void* data,
// size_t length,
// const IPEndpoint& dest) {
// const auto send_to_address = ToChromeNetEndpoint(dest);
// const base::span<const uint8_t> data_span(
// reinterpret_cast<const uint8_t*>(data), length);
// udp_socket_->SendTo(send_to_address, data_span, kMutableTrafficAnnotation,
// base::BindOnce(&ChromeUdpSocket::SendToCallback,
// weak_ptr_factory_.GetWeakPtr()));
// // Errors are reported using the callback message, so no error to return
// here. return Error::None();
// }
// // mojom::UDPSocket doesn't have a concept of DSCP, so this is a noop.
// Error ChromeUdpSocket::SetDscp(DscpMode state) {
// return Error::Code::kNotImplemented;
// }
// // TODO(jophba): change UDPSocket API to use callbacks, so clients don't have
// // to randomly check GetLastError().
// int32_t ChromeUdpSocket::GetLastError() {
// return last_error_;
// }
// void ChromeUdpSocket::BindCallback(
// int32_t result,
// const base::Optional<net::IPEndPoint>& address) {
// if (result != 0) {
// last_error_ = result;
// } else {
// is_bound_ = true;
// }
// }
// void ChromeUdpSocket::JoinGroupCallback(int32_t result) {
// if (result != 0) {
// last_error_ = result;
// }
// }
// void ChromeUdpSocket::SendToCallback(int32_t result) {
// if (result != 0) {
// last_error_ = result;
// }
// }
} // namespace platform
} // namespace openscreen
// 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.
#ifndef CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_UDP_SOCKET_H_
#define CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_UDP_SOCKET_H_
// #include <memory>
// #include "base/memory/weak_ptr.h"
// #include "services/network/udp_socket.h"
// #include "third_party/openscreen/src/platform/api/udp_socket.h"
// #include "third_party/openscreen/src/platform/base/error.h"
// namespace net {
// class IPEndPoint;
// }
namespace openscreen {
namespace platform {
struct ChromeUdpSocket {
// public:
// ChromeUdpSocket(std::unique_ptr<network::UDPSocket> udp_socket,
// TaskRunner* task_runner,
// Client* client,
// const IPEndpoint& local_endpoint);
// ~ChromeUdpSocket() final;
// ErrorOr<UdpPacket> ReceiveMessage();
// // Implementations of UdpSocket methods.
// bool IsIPv4() const final;
// bool IsIPv6() const final;
// Error Bind() final;
// Error SetMulticastOutboundInterface(NetworkInterfaceIndex ifindex) final;
// Error JoinMulticastGroup(const IPAddress& address,
// NetworkInterfaceIndex ifindex) final;
// Error SendMessage(const void* data,
// size_t length,
// const IPEndpoint& dest) final;
// Error SetDscp(DscpMode state) final;
// // Method that allows for getting the last async error, set by internal
// // callback methods.
// int32_t GetLastError();
// private:
// void BindCallback(int32_t result,
// const base::Optional<net::IPEndPoint>& address);
// void JoinGroupCallback(int32_t result);
// void SendToCallback(int32_t result);
// bool is_bound_ = false;
// int32_t last_error_ = 0;
// const net::IPEndPoint local_endpoint_;
// std::unique_ptr<network::UDPSocket> udp_socket_;
// base::WeakPtrFactory<ChromeUdpSocket> weak_ptr_factory_{this};
};
} // namespace platform
} // namespace openscreen
#endif // CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_OPENSCREEN_PLATFORM_UDP_SOCKET_H_
......@@ -178,7 +178,7 @@ Refer to README.md for content description and update process.
<item id="omnibox_suggest_deletion" hash_code="84212388" type="0" content_hash_code="24981550" os_list="linux,windows" file_path="components/omnibox/browser/base_search_provider.cc"/>
<item id="omnibox_zerosuggest" hash_code="7687691" type="0" content_hash_code="119419625" os_list="linux,windows" file_path="components/omnibox/browser/remote_suggestions_service.cc"/>
<item id="one_google_bar_service" hash_code="78917933" type="0" content_hash_code="46527252" os_list="linux,windows" file_path="chrome/browser/search/one_google_bar/one_google_bar_loader_impl.cc"/>
<item id="open_screen_message" hash_code="95250780" type="0" deprecated="2019-09-05" content_hash_code="39027953" file_path=""/>
<item id="open_screen_message" hash_code="95250780" type="0" content_hash_code="39027953" os_list="linux" file_path="chrome/browser/media/router/providers/openscreen/platform/chrome_udp_socket.cc"/>
<item id="open_search" hash_code="107267424" type="0" content_hash_code="83025542" os_list="linux,windows" file_path="components/search_engines/template_url_fetcher.cc"/>
<item id="optimization_guide_model" hash_code="106373593" type="0" content_hash_code="32403047" os_list="linux,windows" file_path="chrome/browser/optimization_guide/prediction/prediction_model_fetcher.cc"/>
<item id="origin_policy_loader" hash_code="6483617" type="0" content_hash_code="20680909" os_list="linux,windows" file_path="services/network/origin_policy/origin_policy_fetcher.cc"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment