#include "remoting/host/corp_heartbeat_service_client.h"
#include <string_view>
#include "base/strings/stringize_macros.h"
#include "remoting/base/environment_details.h"
#include "remoting/base/protobuf_http_client.h"
#include "remoting/host/version.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace remoting {
CorpHeartbeatServiceClient::CorpHeartbeatServiceClient(
const std::string& directory_id,
const std::string& refresh_token,
const std::string& service_account_email,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::unique_ptr<net::ClientCertStore> client_cert_store)
: directory_id_(directory_id),
client_(refresh_token,
service_account_email,
url_loader_factory,
std::move(client_cert_store)) {}
CorpHeartbeatServiceClient::~CorpHeartbeatServiceClient() = default;
void CorpHeartbeatServiceClient::SendFullHeartbeat(
bool is_initial_heartbeat,
std::optional<std::string> signaling_id,
std::optional<std::string> offline_reason,
HeartbeatResponseCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (offline_reason.has_value() && !offline_reason->empty()) {
MakeUpdateRemoteAccessHostCall(
signaling_id, offline_reason,
base::BindOnce(&CorpHeartbeatServiceClient::OnReportHostOffline,
weak_factory_.GetWeakPtr(), std::move(callback)));
} else if (is_initial_heartbeat) {
MakeUpdateRemoteAccessHostCall(
signaling_id, offline_reason,
base::BindOnce(
&CorpHeartbeatServiceClient::OnUpdateRemoteAccessHostResponse,
weak_factory_.GetWeakPtr(), std::move(callback)));
} else {
SendLiteHeartbeat(std::move(callback));
}
}
void CorpHeartbeatServiceClient::SendLiteHeartbeat(
HeartbeatResponseCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
client_.SendHeartbeat(
directory_id_,
base::BindOnce(&CorpHeartbeatServiceClient::OnSendHeartbeatResponse,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void CorpHeartbeatServiceClient::CancelPendingRequests() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
client_.CancelPendingRequests();
}
void CorpHeartbeatServiceClient::OnSendHeartbeatResponse(
HeartbeatResponseCallback callback,
const HttpStatus& status,
std::unique_ptr<Empty>) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
RunHeartbeatResponseCallback(std::move(callback), status);
}
void CorpHeartbeatServiceClient::OnUpdateRemoteAccessHostResponse(
HeartbeatResponseCallback callback,
const HttpStatus& status,
std::unique_ptr<internal::RemoteAccessHostV1Proto>) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (status.ok()) {
SendLiteHeartbeat(std::move(callback));
} else {
RunHeartbeatResponseCallback(std::move(callback), status);
}
}
void CorpHeartbeatServiceClient::OnReportHostOffline(
HeartbeatResponseCallback callback,
const HttpStatus& status,
std::unique_ptr<internal::RemoteAccessHostV1Proto>) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
RunHeartbeatResponseCallback(std::move(callback), status);
}
void CorpHeartbeatServiceClient::MakeUpdateRemoteAccessHostCall(
std::optional<std::string> signaling_id,
std::optional<std::string> offline_reason,
CorpServiceClient::UpdateRemoteAccessHostCallback callback) {
constexpr char kHostVersion[] = STRINGIZE(VERSION);
client_.UpdateRemoteAccessHost(directory_id_, kHostVersion, signaling_id,
offline_reason, GetOperatingSystemName(),
GetOperatingSystemVersion(),
std::move(callback));
}
void CorpHeartbeatServiceClient::RunHeartbeatResponseCallback(
HeartbeatResponseCallback callback,
const HttpStatus& status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!status.ok()) {
OnError(std::move(callback), status);
return;
}
std::move(callback).Run(status, std::nullopt,
"",
std::nullopt,
true);
}
}