Commit a74b62f5 authored by Yuwei Huang's avatar Yuwei Huang Committed by Commit Bot

[remoting] Migrate HeartbeatSender to Protobuf over HTTP

This CL makes HeartbeatSender send request via Protobuf over HTTP. This
is OK to be checked in now since unlike FTL, our backend is ready to
accept Protobuf/HTTP requests.

Bug: 1103416
Change-Id: Iefdbcb59602436e01dbf4475cab3f6db67004e2c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2311121
Commit-Queue: Yuwei Huang <yuweih@chromium.org>
Auto-Submit: Yuwei Huang <yuweih@chromium.org>
Reviewed-by: default avatarMartin Šrámek <msramek@chromium.org>
Reviewed-by: default avatarJoe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791025}
parent 3ddbb96e
......@@ -18,24 +18,53 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/network_interfaces.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "remoting/base/constants.h"
#include "remoting/base/grpc_support/grpc_async_unary_request.h"
#include "remoting/base/grpc_support/grpc_authenticated_executor.h"
#include "remoting/base/grpc_support/grpc_channel.h"
#include "remoting/base/grpc_support/grpc_util.h"
#include "remoting/base/logging.h"
#include "remoting/base/protobuf_http_client.h"
#include "remoting/base/protobuf_http_request.h"
#include "remoting/base/protobuf_http_request_config.h"
#include "remoting/base/protobuf_http_status.h"
#include "remoting/base/service_urls.h"
#include "remoting/host/host_config.h"
#include "remoting/host/host_details.h"
#include "remoting/host/server_log_entry_host.h"
#include "remoting/proto/remoting/v1/directory_service.grpc.pb.h"
#include "remoting/signaling/ftl_signal_strategy.h"
#include "remoting/signaling/signaling_address.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace remoting {
namespace {
constexpr char kHeartbeatPath[] = "/v1/directory:heartbeat";
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("heartbeat_sender",
R"(
semantics {
sender: "Chrome Remote Desktop"
description:
"Sends heartbeat data to the Chrome Remote Desktop backend so that "
"the client knows about the presence of the host."
trigger:
"Starting a Chrome Remote Desktop host."
data:
"Chrome Remote Desktop Host ID and some non-PII information about "
"the host system such as the Chrome Remote Desktop version and the "
"OS version."
destination: OTHER
destination_other: "Chrome Remote Desktop directory service"
}
policy {
cookies_allowed: NO
setting:
"This request cannot be stopped in settings, but will not be sent "
"if the user does not use Chrome Remote Desktop."
policy_exception_justification:
"Not implemented."
})");
constexpr base::TimeDelta kMinimumHeartbeatInterval =
base::TimeDelta::FromMinutes(3);
constexpr base::TimeDelta kHeartbeatResponseTimeout =
......@@ -81,64 +110,68 @@ const net::BackoffEntry::Policy kBackoffPolicy = {
class HeartbeatSender::HeartbeatClientImpl final
: public HeartbeatSender::HeartbeatClient {
public:
explicit HeartbeatClientImpl(OAuthTokenGetter* oauth_token_getter);
explicit HeartbeatClientImpl(
OAuthTokenGetter* oauth_token_getter,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
~HeartbeatClientImpl() override;
void Heartbeat(const apis::v1::HeartbeatRequest& request,
void Heartbeat(std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) override;
void CancelPendingRequests() override;
private:
using DirectoryService = apis::v1::RemotingDirectoryService;
std::unique_ptr<DirectoryService::Stub> directory_;
GrpcAuthenticatedExecutor executor_;
ProtobufHttpClient http_client_;
DISALLOW_COPY_AND_ASSIGN(HeartbeatClientImpl);
};
HeartbeatSender::HeartbeatClientImpl::HeartbeatClientImpl(
OAuthTokenGetter* oauth_token_getter)
: executor_(oauth_token_getter) {
directory_ = DirectoryService::NewStub(CreateSslChannelForEndpoint(
ServiceUrls::GetInstance()->remoting_server_endpoint()));
}
OAuthTokenGetter* oauth_token_getter,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
: http_client_(ServiceUrls::GetInstance()->remoting_server_endpoint(),
oauth_token_getter,
url_loader_factory) {}
HeartbeatSender::HeartbeatClientImpl::~HeartbeatClientImpl() = default;
void HeartbeatSender::HeartbeatClientImpl::Heartbeat(
const apis::v1::HeartbeatRequest& request,
std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) {
std::string host_offline_reason_or_empty_log =
request.has_host_offline_reason()
? (", host_offline_reason: " + request.host_offline_reason())
request->has_host_offline_reason()
? (", host_offline_reason: " + request->host_offline_reason())
: "";
HOST_LOG << "Sending outgoing heartbeat. tachyon_id: " << request.tachyon_id()
<< host_offline_reason_or_empty_log;
auto client_context = std::make_unique<grpc::ClientContext>();
auto async_request = CreateGrpcAsyncUnaryRequest(
base::BindOnce(&DirectoryService::Stub::AsyncHeartbeat,
base::Unretained(directory_.get())),
request, std::move(callback));
SetDeadline(async_request->context(),
base::Time::Now() + kHeartbeatResponseTimeout);
executor_.ExecuteRpc(std::move(async_request));
HOST_LOG << "Sending outgoing heartbeat. tachyon_id: "
<< request->tachyon_id() << host_offline_reason_or_empty_log;
auto request_config =
std::make_unique<ProtobufHttpRequestConfig>(kTrafficAnnotation);
request_config->path = kHeartbeatPath;
request_config->request_message = std::move(request);
auto http_request =
std::make_unique<ProtobufHttpRequest>(std::move(request_config));
http_request->SetTimeoutDuration(kHeartbeatResponseTimeout);
http_request->SetResponseCallback(std::move(callback));
http_client_.ExecuteRequest(std::move(http_request));
}
void HeartbeatSender::HeartbeatClientImpl::CancelPendingRequests() {
executor_.CancelPendingRequests();
http_client_.CancelPendingRequests();
}
// end of HeartbeatSender::HeartbeatClientImpl
HeartbeatSender::HeartbeatSender(Delegate* delegate,
HeartbeatSender::HeartbeatSender(
Delegate* delegate,
const std::string& host_id,
SignalStrategy* signal_strategy,
OAuthTokenGetter* oauth_token_getter,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
bool is_googler)
: delegate_(delegate),
host_id_(host_id),
signal_strategy_(signal_strategy),
client_(std::make_unique<HeartbeatClientImpl>(oauth_token_getter)),
client_(std::make_unique<HeartbeatClientImpl>(oauth_token_getter,
url_loader_factory)),
oauth_token_getter_(oauth_token_getter),
backoff_(&kBackoffPolicy) {
DCHECK(delegate_);
......@@ -245,8 +278,9 @@ void HeartbeatSender::SendHeartbeat() {
base::BindOnce(&HeartbeatSender::OnResponse, base::Unretained(this)));
}
void HeartbeatSender::OnResponse(const grpc::Status& status,
const apis::v1::HeartbeatResponse& response) {
void HeartbeatSender::OnResponse(
const ProtobufHttpStatus& status,
std::unique_ptr<apis::v1::HeartbeatResponse> response) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (status.ok()) {
......@@ -265,14 +299,17 @@ void HeartbeatSender::OnResponse(const grpc::Status& status,
return;
}
if (response.has_remote_command()) {
OnRemoteCommand(response.remote_command());
if (response->has_remote_command()) {
OnRemoteCommand(response->remote_command());
}
} else {
LOG(ERROR) << "Heartbeat failed. Error code: "
<< static_cast<int>(status.error_code()) << ", "
<< status.error_message();
backoff_.InformOfRequest(false);
}
if (status.error_code() == grpc::StatusCode::DEADLINE_EXCEEDED) {
if (status.error_code() == ProtobufHttpStatus::Code::DEADLINE_EXCEEDED) {
LOG(ERROR) << "Heartbeat timed out.";
}
......@@ -281,14 +318,14 @@ void HeartbeatSender::OnResponse(const grpc::Status& status,
// host ID in the heartbeat. So even if all of the first few heartbeats
// get a "host ID not found" error, that's not a good enough reason to
// exit.
if (status.error_code() == grpc::StatusCode::NOT_FOUND &&
if (status.error_code() == ProtobufHttpStatus::Code::NOT_FOUND &&
(initial_heartbeat_sent_ ||
(backoff_.failure_count() > kMaxResendOnHostNotFoundCount))) {
delegate_->OnHostNotFound();
return;
}
if (status.error_code() == grpc::StatusCode::UNAUTHENTICATED) {
if (status.error_code() == ProtobufHttpStatus::Code::UNAUTHENTICATED) {
oauth_token_getter_->InvalidateCache();
if (backoff_.failure_count() > kMaxResendOnUnauthenticatedCount) {
delegate_->OnAuthFailed();
......@@ -300,8 +337,8 @@ void HeartbeatSender::OnResponse(const grpc::Status& status,
base::TimeDelta delay;
// See CoreErrorDomainTranslator.java for the mapping
switch (status.error_code()) {
case grpc::StatusCode::OK:
delay = base::TimeDelta::FromSeconds(response.set_interval_seconds());
case ProtobufHttpStatus::Code::OK:
delay = base::TimeDelta::FromSeconds(response->set_interval_seconds());
if (delay < kMinimumHeartbeatInterval) {
LOG(WARNING) << "Received suspicious set_interval_seconds: " << delay
<< ". Using minimum interval: "
......@@ -309,17 +346,16 @@ void HeartbeatSender::OnResponse(const grpc::Status& status,
delay = kMinimumHeartbeatInterval;
}
break;
case grpc::StatusCode::NOT_FOUND:
case ProtobufHttpStatus::Code::NOT_FOUND:
delay = kResendDelayOnHostNotFound;
break;
case grpc::StatusCode::UNAUTHENTICATED:
case ProtobufHttpStatus::Code::UNAUTHENTICATED:
delay = kResendDelayOnUnauthenticated;
break;
default:
delay = backoff_.GetTimeUntilRelease();
LOG(ERROR) << "Heartbeat failed due to unexpected error: "
<< status.error_code() << ", " << status.error_message()
<< ". Will retry in " << delay;
LOG(ERROR) << "Heartbeat failed due to unexpected error. Will retry in "
<< delay;
break;
}
......@@ -342,25 +378,26 @@ void HeartbeatSender::OnRemoteCommand(
}
}
apis::v1::HeartbeatRequest HeartbeatSender::CreateHeartbeatRequest() {
std::unique_ptr<apis::v1::HeartbeatRequest>
HeartbeatSender::CreateHeartbeatRequest() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
apis::v1::HeartbeatRequest heartbeat;
heartbeat.set_tachyon_id(signal_strategy_->GetLocalAddress().id());
heartbeat.set_host_id(host_id_);
auto heartbeat = std::make_unique<apis::v1::HeartbeatRequest>();
heartbeat->set_tachyon_id(signal_strategy_->GetLocalAddress().id());
heartbeat->set_host_id(host_id_);
if (!host_offline_reason_.empty()) {
heartbeat.set_host_offline_reason(host_offline_reason_);
heartbeat->set_host_offline_reason(host_offline_reason_);
}
heartbeat.set_host_version(STRINGIZE(VERSION));
heartbeat.set_host_os_name(GetHostOperatingSystemName());
heartbeat.set_host_os_version(GetHostOperatingSystemVersion());
heartbeat.set_host_cpu_type(base::SysInfo::OperatingSystemArchitecture());
heartbeat.set_is_initial_heartbeat(!initial_heartbeat_sent_);
heartbeat->set_host_version(STRINGIZE(VERSION));
heartbeat->set_host_os_name(GetHostOperatingSystemName());
heartbeat->set_host_os_version(GetHostOperatingSystemVersion());
heartbeat->set_host_cpu_type(base::SysInfo::OperatingSystemArchitecture());
heartbeat->set_is_initial_heartbeat(!initial_heartbeat_sent_);
// Only set the hostname if the user's email is @google.com and they are using
// a Linux OS.
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
if (is_googler_) {
heartbeat.set_hostname_hash(base::MD5String(net::GetHostName()));
heartbeat->set_hostname_hash(base::MD5String(net::GetHostName()));
}
#endif
return heartbeat;
......
......@@ -21,13 +21,14 @@ namespace base {
class TimeDelta;
} // namespace base
namespace grpc {
class Status;
} // namespace grpc
namespace network {
class SharedURLLoaderFactory;
} // namespace network
namespace remoting {
class OAuthTokenGetter;
class ProtobufHttpStatus;
// HeartbeatSender periodically sends heartbeat to the directory service. See
// the HeartbeatRequest message in directory_messages.proto for more details.
......@@ -71,10 +72,12 @@ class HeartbeatSender final : public SignalStrategy::Listener {
};
// All raw pointers must be non-null and outlive this object.
HeartbeatSender(Delegate* delegate,
HeartbeatSender(
Delegate* delegate,
const std::string& host_id,
SignalStrategy* signal_strategy,
OAuthTokenGetter* oauth_token_getter,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
bool is_googler);
~HeartbeatSender() override;
......@@ -95,12 +98,12 @@ class HeartbeatSender final : public SignalStrategy::Listener {
class HeartbeatClient {
public:
using HeartbeatResponseCallback =
base::OnceCallback<void(const grpc::Status&,
const apis::v1::HeartbeatResponse&)>;
base::OnceCallback<void(const ProtobufHttpStatus&,
std::unique_ptr<apis::v1::HeartbeatResponse>)>;
virtual ~HeartbeatClient() = default;
virtual void Heartbeat(const apis::v1::HeartbeatRequest& request,
virtual void Heartbeat(std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) = 0;
virtual void CancelPendingRequests() = 0;
};
......@@ -115,8 +118,8 @@ class HeartbeatSender final : public SignalStrategy::Listener {
const jingle_xmpp::XmlElement* stanza) override;
void SendHeartbeat();
void OnResponse(const grpc::Status& status,
const apis::v1::HeartbeatResponse& response);
void OnResponse(const ProtobufHttpStatus& status,
std::unique_ptr<apis::v1::HeartbeatResponse> response);
// Handlers for host-offline-reason completion and timeout.
void OnHostOfflineReasonTimeout();
......@@ -126,7 +129,7 @@ class HeartbeatSender final : public SignalStrategy::Listener {
apis::v1::HeartbeatResponse::RemoteCommand remote_command);
// Helper methods used by DoSendStanza() to generate heartbeat stanzas.
apis::v1::HeartbeatRequest CreateHeartbeatRequest();
std::unique_ptr<apis::v1::HeartbeatRequest> CreateHeartbeatRequest();
Delegate* delegate_;
std::string host_id_;
......
......@@ -19,11 +19,12 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "remoting/base/fake_oauth_token_getter.h"
#include "remoting/proto/remoting/v1/directory_service.grpc.pb.h"
#include "remoting/base/protobuf_http_status.h"
#include "remoting/signaling/fake_signal_strategy.h"
#include "remoting/signaling/mock_signaling_tracker.h"
#include "remoting/signaling/signal_strategy.h"
#include "remoting/signaling/signaling_address.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -37,8 +38,8 @@ using testing::InSequence;
using testing::Return;
using HeartbeatResponseCallback =
base::OnceCallback<void(const grpc::Status&,
const apis::v1::HeartbeatResponse&)>;
base::OnceCallback<void(const ProtobufHttpStatus&,
std::unique_ptr<apis::v1::HeartbeatResponse>)>;
constexpr char kOAuthAccessToken[] = "fake_access_token";
constexpr char kHostId[] = "fake_host_id";
......@@ -55,31 +56,31 @@ constexpr base::TimeDelta kOfflineReasonTimeout =
constexpr base::TimeDelta kTestHeartbeatDelay =
base::TimeDelta::FromSeconds(350);
void ValidateHeartbeat(const apis::v1::HeartbeatRequest& request,
void ValidateHeartbeat(std::unique_ptr<apis::v1::HeartbeatRequest> request,
bool expected_is_initial_heartbeat = false,
const std::string& expected_host_offline_reason = {},
bool is_googler = false) {
ASSERT_TRUE(request.has_host_version());
ASSERT_TRUE(request->has_host_version());
if (expected_host_offline_reason.empty()) {
ASSERT_FALSE(request.has_host_offline_reason());
ASSERT_FALSE(request->has_host_offline_reason());
} else {
ASSERT_EQ(expected_host_offline_reason, request.host_offline_reason());
ASSERT_EQ(expected_host_offline_reason, request->host_offline_reason());
}
ASSERT_EQ(kHostId, request.host_id());
ASSERT_EQ(kFtlId, request.tachyon_id());
ASSERT_TRUE(request.has_host_version());
ASSERT_TRUE(request.has_host_os_version());
ASSERT_TRUE(request.has_host_os_name());
ASSERT_TRUE(request.has_host_cpu_type());
ASSERT_EQ(expected_is_initial_heartbeat, request.is_initial_heartbeat());
ASSERT_EQ(kHostId, request->host_id());
ASSERT_EQ(kFtlId, request->tachyon_id());
ASSERT_TRUE(request->has_host_version());
ASSERT_TRUE(request->has_host_os_version());
ASSERT_TRUE(request->has_host_os_name());
ASSERT_TRUE(request->has_host_cpu_type());
ASSERT_EQ(expected_is_initial_heartbeat, request->is_initial_heartbeat());
bool is_linux = false;
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
is_linux = true;
#endif
if (is_googler && is_linux) {
ASSERT_TRUE(request.has_hostname_hash());
ASSERT_TRUE(request->has_hostname_hash());
} else {
ASSERT_FALSE(request.has_hostname_hash());
ASSERT_FALSE(request->has_hostname_hash());
}
}
......@@ -87,13 +88,13 @@ decltype(auto) DoValidateHeartbeatAndRespondOk(
bool expected_is_initial_heartbeat = false,
const std::string& expected_host_offline_reason = {},
bool is_googler = false) {
return [=](const apis::v1::HeartbeatRequest& request,
return [=](std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) {
ValidateHeartbeat(request, expected_is_initial_heartbeat,
ValidateHeartbeat(std::move(request), expected_is_initial_heartbeat,
expected_host_offline_reason, is_googler);
apis::v1::HeartbeatResponse response;
response.set_set_interval_seconds(kGoodIntervalSeconds);
std::move(callback).Run(grpc::Status::OK, response);
auto response = std::make_unique<apis::v1::HeartbeatResponse>();
response->set_set_interval_seconds(kGoodIntervalSeconds);
std::move(callback).Run(ProtobufHttpStatus::OK, std::move(response));
};
}
......@@ -125,7 +126,7 @@ class HeartbeatSenderTest : public testing::Test {
heartbeat_sender_ = std::make_unique<HeartbeatSender>(
&mock_delegate_, kHostId, signal_strategy_.get(), &oauth_token_getter_,
false);
nullptr, false);
auto heartbeat_client = std::make_unique<MockHeartbeatClient>();
mock_client_ = heartbeat_client.get();
heartbeat_sender_->client_ = std::move(heartbeat_client);
......@@ -141,7 +142,7 @@ class HeartbeatSenderTest : public testing::Test {
class MockHeartbeatClient : public HeartbeatSender::HeartbeatClient {
public:
MOCK_METHOD2(Heartbeat,
void(const apis::v1::HeartbeatRequest&,
void(std::unique_ptr<apis::v1::HeartbeatRequest>,
HeartbeatResponseCallback));
void CancelPendingRequests() override {
......@@ -247,11 +248,13 @@ TEST_F(HeartbeatSenderTest, SetHostOfflineReason) {
TEST_F(HeartbeatSenderTest, UnknownHostId) {
EXPECT_CALL(*mock_client_, Heartbeat(_, _))
.WillRepeatedly([](const apis::v1::HeartbeatRequest& request,
.WillRepeatedly([](std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) {
ValidateHeartbeat(request, true);
ValidateHeartbeat(std::move(request), true);
std::move(callback).Run(
grpc::Status(grpc::StatusCode::NOT_FOUND, "not found"), {});
ProtobufHttpStatus(ProtobufHttpStatus::Code::NOT_FOUND,
"not found"),
nullptr);
});
EXPECT_CALL(mock_delegate_, OnHostNotFound()).Times(1);
......@@ -267,11 +270,13 @@ TEST_F(HeartbeatSenderTest, FailedToHeartbeat_Backoff) {
EXPECT_CALL(*mock_client_, Heartbeat(_, _))
.Times(2)
.WillRepeatedly([&](const apis::v1::HeartbeatRequest& request,
.WillRepeatedly([&](std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) {
ValidateHeartbeat(request, true);
ValidateHeartbeat(std::move(request), true);
std::move(callback).Run(
grpc::Status(grpc::StatusCode::UNAVAILABLE, "unavailable"), {});
ProtobufHttpStatus(ProtobufHttpStatus::Code::UNAVAILABLE,
"unavailable"),
nullptr);
});
EXPECT_CALL(*mock_client_, Heartbeat(_, _))
......@@ -290,13 +295,14 @@ TEST_F(HeartbeatSenderTest, FailedToHeartbeat_Backoff) {
TEST_F(HeartbeatSenderTest, Unauthenticated) {
int heartbeat_count = 0;
EXPECT_CALL(*mock_client_, Heartbeat(_, _))
.WillRepeatedly([&](const apis::v1::HeartbeatRequest& request,
.WillRepeatedly([&](std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) {
ValidateHeartbeat(request, true);
ValidateHeartbeat(std::move(request), true);
heartbeat_count++;
std::move(callback).Run(
grpc::Status(grpc::StatusCode::UNAUTHENTICATED, "unauthenticated"),
{});
ProtobufHttpStatus(ProtobufHttpStatus::Code::UNAUTHENTICATED,
"unauthenticated"),
nullptr);
});
EXPECT_CALL(mock_delegate_, OnAuthFailed()).Times(1);
......@@ -310,13 +316,13 @@ TEST_F(HeartbeatSenderTest, Unauthenticated) {
TEST_F(HeartbeatSenderTest, RemoteCommand) {
EXPECT_CALL(*mock_client_, Heartbeat(_, _))
.WillOnce([](const apis::v1::HeartbeatRequest& request,
.WillOnce([](std::unique_ptr<apis::v1::HeartbeatRequest> request,
HeartbeatResponseCallback callback) {
ValidateHeartbeat(request, true);
apis::v1::HeartbeatResponse response;
response.set_set_interval_seconds(kGoodIntervalSeconds);
response.set_remote_command(apis::v1::HeartbeatResponse::RESTART_HOST);
std::move(callback).Run(grpc::Status::OK, response);
ValidateHeartbeat(std::move(request), true);
auto response = std::make_unique<apis::v1::HeartbeatResponse>();
response->set_set_interval_seconds(kGoodIntervalSeconds);
response->set_remote_command(apis::v1::HeartbeatResponse::RESTART_HOST);
std::move(callback).Run(ProtobufHttpStatus::OK, std::move(response));
});
EXPECT_CALL(mock_delegate_, OnFirstHeartbeatSuccessful()).Times(1);
EXPECT_CALL(mock_delegate_, OnRemoteRestartHost()).Times(1);
......
......@@ -1414,7 +1414,7 @@ void HostProcess::InitializeSignaling() {
heartbeat_sender_ = std::make_unique<HeartbeatSender>(
this, host_id_, ftl_signal_strategy.get(), oauth_token_getter_.get(),
is_googler);
context_->url_loader_factory(), is_googler);
signal_strategy_ = std::move(ftl_signal_strategy);
}
......
......@@ -136,6 +136,7 @@ Refer to README.md for content description and update process.
<item id="geo_language_provider" hash_code="52821843" type="1" second_id="96590038" content_hash_code="65327456" os_list="linux,windows" semantics_fields="1" policy_fields="3,4" file_path="components/language/content/browser/geo_language_provider.cc"/>
<item id="google_url_tracker" hash_code="5492492" type="0" deprecated="2019-08-01" content_hash_code="54474899" file_path=""/>
<item id="headless_url_request" hash_code="29865866" type="0" deprecated="2018-07-10" content_hash_code="76700151" file_path=""/>
<item id="heartbeat_sender" hash_code="4883150" type="0" content_hash_code="131927805" os_list="linux,windows" file_path="remoting/host/heartbeat_sender.cc"/>
<item id="hintsfetcher_gethintsrequest" hash_code="34557599" type="0" content_hash_code="57003380" os_list="linux,windows" file_path="components/optimization_guide/hints_fetcher.cc"/>
<item id="history_notice_utils_notice" hash_code="102595701" type="1" second_id="110307337" content_hash_code="130829410" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/>
<item id="history_notice_utils_popup" hash_code="80832574" type="1" second_id="110307337" content_hash_code="30618510" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.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