diff options
-rw-r--r-- | remoting/host/chromoting_host_context.cc | 13 | ||||
-rw-r--r-- | remoting/host/host_signaling_manager.cc | 11 | ||||
-rw-r--r-- | remoting/host/host_signaling_manager.h | 12 | ||||
-rw-r--r-- | remoting/host/remoting_me2me_host.cc | 89 |
4 files changed, 84 insertions, 41 deletions
diff --git a/remoting/host/chromoting_host_context.cc b/remoting/host/chromoting_host_context.cc index 60e3a73..319cc77 100644 --- a/remoting/host/chromoting_host_context.cc +++ b/remoting/host/chromoting_host_context.cc @@ -4,12 +4,22 @@ #include "remoting/host/chromoting_host_context.h" +#include "base/threading/thread_restrictions.h" #include "content/public/browser/browser_thread.h" #include "remoting/base/auto_thread.h" #include "remoting/base/url_request_context_getter.h" namespace remoting { +namespace { + +void DisallowBlockingOperations() { + base::ThreadRestrictions::SetIOAllowed(false); + base::ThreadRestrictions::DisallowWaiting(); +} + +} // namespace + ChromotingHostContext::ChromotingHostContext( scoped_refptr<AutoThreadTaskRunner> ui_task_runner, scoped_refptr<AutoThreadTaskRunner> audio_task_runner, @@ -96,9 +106,12 @@ scoped_ptr<ChromotingHostContext> ChromotingHostContext::Create( scoped_refptr<AutoThreadTaskRunner> file_task_runner = AutoThread::CreateWithType("ChromotingFileThread", ui_task_runner, base::MessageLoop::TYPE_IO); + scoped_refptr<AutoThreadTaskRunner> network_task_runner = AutoThread::CreateWithType("ChromotingNetworkThread", ui_task_runner, base::MessageLoop::TYPE_IO); + network_task_runner->PostTask(FROM_HERE, + base::Bind(&DisallowBlockingOperations)); return make_scoped_ptr(new ChromotingHostContext( ui_task_runner, diff --git a/remoting/host/host_signaling_manager.cc b/remoting/host/host_signaling_manager.cc index 37da304..20abbd1 100644 --- a/remoting/host/host_signaling_manager.cc +++ b/remoting/host/host_signaling_manager.cc @@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/time/time.h" -#include "net/base/network_change_notifier.h" #include "net/socket/client_socket_factory.h" #include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/logging.h" @@ -22,13 +21,11 @@ namespace remoting { HostSignalingManager::HostSignalingManager( scoped_ptr<base::WeakPtrFactory<Listener>> weak_factory_for_listener, const scoped_refptr<AutoThreadTaskRunner>& network_task_runner, - scoped_ptr<net::NetworkChangeNotifier> network_change_notifier, scoped_ptr<SignalStrategy> signal_strategy, scoped_ptr<SignalingConnector> signaling_connector, scoped_ptr<HeartbeatSender> heartbeat_sender) : weak_factory_for_listener_(weak_factory_for_listener.Pass()), network_task_runner_(network_task_runner), - network_change_notifier_(network_change_notifier.Pass()), signal_strategy_(signal_strategy.Pass()), signaling_connector_(signaling_connector.Pass()), heartbeat_sender_(heartbeat_sender.Pass()) { @@ -50,9 +47,6 @@ scoped_ptr<HostSignalingManager> HostSignalingManager::Create( scoped_ptr<base::WeakPtrFactory<Listener>> weak_factory( new base::WeakPtrFactory<Listener>(listener)); - scoped_ptr<net::NetworkChangeNotifier> network_change_notifier( - net::NetworkChangeNotifier::Create()); - scoped_ptr<XmppSignalStrategy> signal_strategy( new XmppSignalStrategy(net::ClientSocketFactory::GetDefaultFactory(), url_request_context_getter, xmpp_server_config)); @@ -77,9 +71,8 @@ scoped_ptr<HostSignalingManager> HostSignalingManager::Create( host_id, signal_strategy.get(), host_key_pair, directory_bot_jid)); return scoped_ptr<HostSignalingManager>(new HostSignalingManager( - weak_factory.Pass(), network_task_runner, network_change_notifier.Pass(), - signal_strategy.Pass(), signaling_connector.Pass(), - heartbeat_sender.Pass())); + weak_factory.Pass(), network_task_runner, signal_strategy.Pass(), + signaling_connector.Pass(), heartbeat_sender.Pass())); } HostSignalingManager::~HostSignalingManager() { diff --git a/remoting/host/host_signaling_manager.h b/remoting/host/host_signaling_manager.h index 1004dd8..22f0567 100644 --- a/remoting/host/host_signaling_manager.h +++ b/remoting/host/host_signaling_manager.h @@ -90,7 +90,6 @@ class HostSignalingManager { HostSignalingManager( scoped_ptr<base::WeakPtrFactory<Listener>> weak_factory_for_listener, const scoped_refptr<AutoThreadTaskRunner>& network_task_runner, - scoped_ptr<net::NetworkChangeNotifier> network_change_notifier, scoped_ptr<SignalStrategy> signal_strategy, scoped_ptr<SignalingConnector> signaling_connector, scoped_ptr<HeartbeatSender> heartbeat_sender); @@ -109,14 +108,9 @@ class HostSignalingManager { // host-offline-reason. scoped_refptr<AutoThreadTaskRunner> network_task_runner_; - // Order of fields below is important for destroying them in the right order. - // - |heartbeat_sender_| and |signaling_connector_| have to be destroyed - // before |signal_strategy_| because their destructors need to call - // signal_strategy_->RemoveListener(this) - // - |signaling_connector_| has to be destroyed before - // |network_change_notifier_| because its destructor needs to deregister - // network change notifications - scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; + // |heartbeat_sender_| and |signaling_connector_| have to be destroyed before + // |signal_strategy_| because their destructors need to call + // signal_strategy_->RemoveListener(this) scoped_ptr<SignalStrategy> signal_strategy_; scoped_ptr<SignalingConnector> signaling_connector_; scoped_ptr<HeartbeatSender> heartbeat_sender_; diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index aa0bf6f..291aba6 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -26,6 +26,7 @@ #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_listener.h" #include "media/base/media.h" +#include "net/base/network_change_notifier.h" #include "net/socket/client_socket_factory.h" #include "net/socket/ssl_server_socket.h" #include "net/url_request/url_fetcher.h" @@ -259,6 +260,7 @@ class HostProcess : public ConfigWatcher::Delegate, scoped_ptr<HostSignalingManager> CreateHostSignalingManager(); + void StartHostIfReady(); void StartHost(); // Overrides for HostSignalingManager::Listener interface. @@ -323,6 +325,7 @@ class HostProcess : public ConfigWatcher::Delegate, int64_t frame_recorder_buffer_size_; scoped_ptr<PolicyWatcher> policy_watcher_; + bool policies_loaded_; std::string host_domain_; bool host_username_match_required_; bool allow_nat_traversal_; @@ -336,7 +339,7 @@ class HostProcess : public ConfigWatcher::Delegate, ThirdPartyAuthConfig third_party_auth_config_; bool enable_gnubby_auth_; - // Boolean to change flow, where ncessary, if we're + // Boolean to change flow, where necessary, if we're // capturing a window instead of the entire desktop. bool enable_window_capture_; @@ -378,6 +381,7 @@ HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, use_service_account_(false), enable_vp9_(false), frame_recorder_buffer_size_(0), + policies_loaded_(false), host_username_match_required_(false), allow_nat_traversal_(true), allow_relay_(true), @@ -548,26 +552,18 @@ void HostProcess::OnConfigUpdated( } if (state_ == HOST_INITIALIZING) { - // TODO(sergeyu): Currently OnPolicyUpdate() assumes that host config is - // already loaded so PolicyWatcher has to be started here. Separate policy - // loading from policy verifications and move |policy_watcher_| - // initialization to StartOnNetworkThread(). - policy_watcher_ = - PolicyWatcher::Create(nullptr, context_->file_task_runner()); - policy_watcher_->StartWatching( - base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this)), - base::Bind(&HostProcess::OnPolicyError, base::Unretained(this))); - } else { + StartHostIfReady(); + } else if (state_ == HOST_STARTED) { + DCHECK(policies_loaded_); + // Reapply policies that could be affected by a new config. ApplyHostDomainPolicy(); ApplyUsernamePolicy(); - if (state_ == HOST_STARTED) { - // TODO(sergeyu): Here we assume that PIN is the only part of the config - // that may change while the service is running. Change ApplyConfig() to - // detect other changes in the config and restart host if necessary here. - CreateAuthenticatorFactory(); - } + // TODO(sergeyu): Here we assume that PIN is the only part of the config + // that may change while the service is running. Change ApplyConfig() to + // detect other changes in the config and restart host if necessary here. + CreateAuthenticatorFactory(); } } @@ -724,6 +720,12 @@ void HostProcess::StartOnUiThread() { return; } + policy_watcher_ = + PolicyWatcher::Create(nullptr, context_->file_task_runner()); + policy_watcher_->StartWatching( + base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this)), + base::Bind(&HostProcess::OnPolicyError, base::Unretained(this))); + #if defined(OS_LINUX) // If an audio pipe is specific on the command-line then initialize // AudioCapturerLinux to capture from it. @@ -784,6 +786,8 @@ void HostProcess::ShutdownOnUiThread() { daemon_channel_.reset(); desktop_environment_factory_.reset(); + policy_watcher_.reset(); + // It is now safe for the HostProcess to be deleted. self_ = nullptr; @@ -956,7 +960,12 @@ bool HostProcess::ApplyConfig(const base::DictionaryValue& config) { } void HostProcess::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { - DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); + if (!context_->network_task_runner()->BelongsToCurrentThread()) { + context_->network_task_runner()->PostTask( + FROM_HERE, base::Bind(&HostProcess::OnPolicyUpdate, this, + base::Passed(&policies))); + return; + } bool restart_required = false; restart_required |= OnHostDomainPolicyUpdate(policies.get()); @@ -971,20 +980,30 @@ void HostProcess::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { restart_required |= OnPairingPolicyUpdate(policies.get()); restart_required |= OnGnubbyAuthPolicyUpdate(policies.get()); + policies_loaded_ = true; + if (state_ == HOST_INITIALIZING) { - StartHost(); - } else if (state_ == HOST_STARTED && restart_required) { - RestartHost(); + StartHostIfReady(); + } else if (state_ == HOST_STARTED) { + if (restart_required) + RestartHost(); } } void HostProcess::OnPolicyError() { - DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); + if (!context_->network_task_runner()->BelongsToCurrentThread()) { + context_->network_task_runner()->PostTask( + FROM_HERE, base::Bind(&HostProcess::OnPolicyError, this)); + return; + } ShutdownHost(kInvalidHostConfigurationExitCode); } void HostProcess::ApplyHostDomainPolicy() { + if (state_ != HOST_STARTED) + return; + HOST_LOG << "Policy sets host domain: " << host_domain_; if (!host_domain_.empty()) { @@ -1019,6 +1038,9 @@ bool HostProcess::OnHostDomainPolicyUpdate(base::DictionaryValue* policies) { } void HostProcess::ApplyUsernamePolicy() { + if (state_ != HOST_STARTED) + return; + if (host_username_match_required_) { HOST_LOG << "Policy requires host username match."; @@ -1284,6 +1306,15 @@ scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() { oauth_credentials.Pass()); } +void HostProcess::StartHostIfReady() { + DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); + DCHECK_EQ(state_, HOST_INITIALIZING); + + // Start the host if both the config and the policies are loaded. + if (!serialized_config_.empty() && policies_loaded_) + StartHost(); +} + void HostProcess::StartHost() { DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); DCHECK(!host_); @@ -1368,6 +1399,9 @@ void HostProcess::StartHost() { host_->Start(host_owner_email_); CreateAuthenticatorFactory(); + + ApplyHostDomainPolicy(); + ApplyUsernamePolicy(); } void HostProcess::OnAuthFailed() { @@ -1439,7 +1473,6 @@ void HostProcess::ShutdownOnNetworkThread() { shutdown_watchdog_->Arm(); config_watcher_.reset(); - policy_watcher_.reset(); // Complete the rest of shutdown on the main thread. context_->ui_task_runner()->PostTask( @@ -1481,6 +1514,9 @@ int HostProcessMain() { // Ensures runtime specific CPU features are initialized. media::InitializeCPUSpecificMediaFeatures(); + scoped_ptr<net::NetworkChangeNotifier> network_change_notifier( + net::NetworkChangeNotifier::Create()); + // Create the main message loop and start helper threads. base::MessageLoopForUI message_loop; scoped_ptr<ChromotingHostContext> context = @@ -1489,6 +1525,13 @@ int HostProcessMain() { if (!context) return kInitializationFailed; + // BasicURLRequestContext holds references to threads, so it needs to be + // dereferences on UI threads. Store the reference to the URLRequestGetter to + // make sure it's not destroyed on other threads. + // TODO(sergeyu): Consider fixing it in BasicURLRequestContext. + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = + context->url_request_context_getter(); + // Create & start the HostProcess using these threads. // TODO(wez): The HostProcess holds a reference to itself until Shutdown(). // Remove this hack as part of the multi-process refactoring. |