Skip to content

Commit

Permalink
Stop and unregister existing host when running start_host.
Browse files Browse the repository at this point in the history
Change-Id: I6580d6544444c9c78deb280d2d7c35094c16a07a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2511856
Commit-Queue: Jamie Walch <jamiewalch@chromium.org>
Reviewed-by: Joe Downing <joedow@google.com>
Cr-Commit-Position: refs/heads/master@{#823299}
  • Loading branch information
jamiewalch authored and Commit Bot committed Nov 2, 2020
1 parent feb9871 commit dc597a5
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 17 deletions.
2 changes: 2 additions & 0 deletions remoting/host/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ if (enable_remoting_host) {
sources += [
"setup/host_starter.cc",
"setup/host_starter.h",
"setup/host_stopper.cc",
"setup/host_stopper.h",
"setup/start_host_main.cc",
"setup/start_host_main.h",
]
Expand Down
43 changes: 27 additions & 16 deletions remoting/host/setup/host_starter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ namespace remoting {
HostStarter::HostStarter(
std::unique_ptr<gaia::GaiaOAuthClient> oauth_client,
std::unique_ptr<remoting::ServiceClient> service_client,
scoped_refptr<remoting::DaemonController> daemon_controller)
scoped_refptr<remoting::DaemonController> daemon_controller,
std::unique_ptr<remoting::HostStopper> host_stopper)
: oauth_client_(std::move(oauth_client)),
service_client_(std::move(service_client)),
daemon_controller_(daemon_controller),
host_stopper_(std::move(host_stopper)),
consent_to_data_collection_(false),
unregistering_host_(false) {
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
Expand All @@ -41,10 +43,13 @@ HostStarter::~HostStarter() = default;

std::unique_ptr<HostStarter> HostStarter::Create(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
auto controller = remoting::DaemonController::Create();
return base::WrapUnique(new HostStarter(
std::make_unique<gaia::GaiaOAuthClient>(url_loader_factory),
std::make_unique<remoting::ServiceClient>(url_loader_factory),
remoting::DaemonController::Create()));
std::make_unique<remoting::ServiceClient>(url_loader_factory), controller,
std::make_unique<remoting::HostStopper>(
std::make_unique<remoting::ServiceClient>(url_loader_factory),
controller)));
}

void HostStarter::StartHost(const std::string& host_id,
Expand Down Expand Up @@ -138,19 +143,12 @@ void HostStarter::OnGetUserEmailResponse(const std::string& user_email) {
std::move(on_done_).Run(OAUTH_ERROR);
return;
}

// Now register the host with the Directory.
if (host_id_.empty())
host_id_ = base::GenerateGUID();
key_pair_ = RsaKeyPair::Generate();

std::string host_client_id;
host_client_id = google_apis::GetOAuth2ClientID(
google_apis::CLIENT_REMOTING_HOST);

service_client_->RegisterHost(host_id_, host_name_,
key_pair_->GetPublicKey(), host_client_id,
directory_access_token_, this);
// If the host is already running, stop it; then register a new host with
// with the directory.
host_stopper_->StopLocalHost(
directory_access_token_,
base::BindOnce(&HostStarter::OnLocalHostStopped,
base::Unretained(this)));
} else {
// This is the second callback, with the service account credentials.
// This email is the service account's email, used to login to XMPP.
Expand Down Expand Up @@ -205,6 +203,19 @@ void HostStarter::StartHostProcess() {
base::BindOnce(&HostStarter::OnHostStarted, base::Unretained(this)));
}

void HostStarter::OnLocalHostStopped() {
if (host_id_.empty())
host_id_ = base::GenerateGUID();
key_pair_ = RsaKeyPair::Generate();

std::string host_client_id;
host_client_id =
google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING_HOST);

service_client_->RegisterHost(host_id_, host_name_, key_pair_->GetPublicKey(),
host_client_id, directory_access_token_, this);
}

void HostStarter::OnHostStarted(DaemonController::AsyncResult result) {
if (!main_task_runner_->BelongsToCurrentThread()) {
main_task_runner_->PostTask(
Expand Down
6 changes: 5 additions & 1 deletion remoting/host/setup/host_starter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "google_apis/gaia/gaia_oauth_client.h"
#include "remoting/base/rsa_key_pair.h"
#include "remoting/host/setup/daemon_controller.h"
#include "remoting/host/setup/host_stopper.h"
#include "remoting/host/setup/service_client.h"

namespace network {
Expand Down Expand Up @@ -85,15 +86,18 @@ class HostStarter : public gaia::GaiaOAuthClient::Delegate,

HostStarter(std::unique_ptr<gaia::GaiaOAuthClient> oauth_client,
std::unique_ptr<remoting::ServiceClient> service_client,
scoped_refptr<remoting::DaemonController> daemon_controller);
scoped_refptr<remoting::DaemonController> daemon_controller,
std::unique_ptr<remoting::HostStopper> host_stopper);

void StartHostProcess();

void OnLocalHostStopped();
void OnHostStarted(DaemonController::AsyncResult result);

std::unique_ptr<gaia::GaiaOAuthClient> oauth_client_;
std::unique_ptr<remoting::ServiceClient> service_client_;
scoped_refptr<remoting::DaemonController> daemon_controller_;
std::unique_ptr<remoting::HostStopper> host_stopper_;
gaia::OAuthClientInfo oauth_client_info_;
std::string host_name_;
std::string host_pin_;
Expand Down
77 changes: 77 additions & 0 deletions remoting/host/setup/host_stopper.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2020 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 "remoting/host/setup/host_stopper.h"
#include "base/logging.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"

namespace remoting {

HostStopper::HostStopper(std::unique_ptr<ServiceClient> service_client,
scoped_refptr<DaemonController> daemon_controller)
: service_client_(std::move(service_client)),
daemon_controller_(daemon_controller) {
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
}

HostStopper::~HostStopper() = default;

void HostStopper::StopLocalHost(std::string access_token,
base::OnceClosure on_done) {
DCHECK(!on_done_);
access_token_ = access_token;
on_done_ = std::move(on_done);
daemon_controller_->GetConfig(
base::BindOnce(&HostStopper::OnConfigLoaded, weak_ptr_));
}

void HostStopper::OnConfigLoaded(
std::unique_ptr<base::DictionaryValue> config) {
const std::string* hostId = nullptr;
if (!config || !(hostId = config->FindStringPath("host_id"))) {
std::move(on_done_).Run();
return;
}

LOG(INFO) << "Stopping existing host: " << *hostId
<< ". This may take a few seconds.";
service_client_->UnregisterHost(*hostId, access_token_, this);
}

void HostStopper::StopHost() {
daemon_controller_->Stop(base::BindOnce(&HostStopper::OnStopped, weak_ptr_));
}

void HostStopper::OnStopped(DaemonController::AsyncResult) {
bool stopped = false;
for (auto i = 0; !stopped && i < 10; i++) {
stopped =
(daemon_controller_->GetState() == DaemonController::STATE_STOPPED);
if (!stopped)
base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
}
if (!stopped)
LOG(WARNING) << "Unable to stop existing host process. Setup will "
<< "continue, but you may need to reboot to complete it.";
std::move(on_done_).Run();
}

void HostStopper::OnHostRegistered(const std::string& authorization_code) {
NOTREACHED();
}

void HostStopper::OnHostUnregistered() {
StopHost();
}

void HostStopper::OnOAuthError() {
StopHost();
}

void HostStopper::OnNetworkError(int response_code) {
StopHost();
}

} // namespace remoting
49 changes: 49 additions & 0 deletions remoting/host/setup/host_stopper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2020 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 REMOTING_HOST_SETUP_HOST_STOPPER_H_
#define REMOTING_HOST_SETUP_HOST_STOPPER_H_

#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "remoting/host/setup/daemon_controller.h"
#include "remoting/host/setup/service_client.h"

namespace remoting {

// A helper class that stops and unregisters a host.
class HostStopper : public ServiceClient::Delegate {
public:
HostStopper(std::unique_ptr<ServiceClient> service_client,
scoped_refptr<DaemonController> daemon_controller);
HostStopper(const HostStopper&) = delete;
HostStopper& operator=(const HostStopper&) = delete;
~HostStopper() final;

// Stops the host running on the local computer, if any, and unregisters it.
void StopLocalHost(std::string access_token, base::OnceClosure on_done);

private:
void OnConfigLoaded(std::unique_ptr<base::DictionaryValue> config);
void StopHost();
void OnStopped(DaemonController::AsyncResult);

// remoting::ServiceClient::Delegate
void OnHostRegistered(const std::string& authorization_code) override;
void OnHostUnregistered() override;
void OnOAuthError() override;
void OnNetworkError(int response_code) override;

std::unique_ptr<remoting::ServiceClient> service_client_;
scoped_refptr<remoting::DaemonController> daemon_controller_;
std::string access_token_;
base::OnceClosure on_done_;

base::WeakPtr<HostStopper> weak_ptr_;
base::WeakPtrFactory<HostStopper> weak_ptr_factory_{this};
};

} // namespace remoting

#endif // REMOTING_HOST_SETUP_HOST_STOPPER_H_
2 changes: 2 additions & 0 deletions remoting/host/win/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ shared_library("remoting_core") {
"//remoting/host/it2me/it2me_native_messaging_host_main.h",
"//remoting/host/setup/host_starter.cc",
"//remoting/host/setup/host_starter.h",
"//remoting/host/setup/host_stopper.cc",
"//remoting/host/setup/host_stopper.h",
"//remoting/host/setup/me2me_native_messaging_host_main.cc",
"//remoting/host/setup/me2me_native_messaging_host_main.h",
"//remoting/host/setup/start_host_main.cc",
Expand Down

0 comments on commit dc597a5

Please sign in to comment.