diff options
Diffstat (limited to 'remoting')
25 files changed, 497 insertions, 171 deletions
diff --git a/remoting/DEPS b/remoting/DEPS index 8f52b3e..ecd11afa 100644 --- a/remoting/DEPS +++ b/remoting/DEPS @@ -7,6 +7,7 @@ include_rules = [ # unit tests at process start. "-net", "+net/socket", + "+net/url_request", "-remoting", "+remoting/base", diff --git a/remoting/host/DEPS b/remoting/host/DEPS index 77a1aae..2e7b3e6 100644 --- a/remoting/host/DEPS +++ b/remoting/host/DEPS @@ -1,6 +1,8 @@ include_rules = [ "+ash", "+cc/output", + "+content/public/browser", + "+components/policy/core/common", "+extensions/browser/api/messaging", "+jingle/glue", "+net", diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc index 2cf80c5..a5398bb 100644 --- a/remoting/host/basic_desktop_environment.cc +++ b/remoting/host/basic_desktop_environment.cc @@ -8,6 +8,9 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" #include "remoting/host/audio_capturer.h" +#if defined(OS_CHROMEOS) +#include "remoting/host/chromeos/aura_desktop_capturer.h" +#endif #include "remoting/host/client_session_control.h" #include "remoting/host/gnubby_auth_handler.h" #include "remoting/host/input_injector.h" @@ -62,10 +65,14 @@ scoped_ptr<webrtc::DesktopCapturer> BasicDesktopEnvironment::CreateVideoCapturer() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); +#if defined(OS_CHROMEOS) + return scoped_ptr<webrtc::DesktopCapturer>(new AuraDesktopCapturer()); +#else // !defined(OS_CHROMEOS) // The basic desktop environment does not use X DAMAGE, since it is // broken on many systems - see http://crbug.com/73423. return make_scoped_ptr( webrtc::ScreenCapturer::Create(*desktop_capture_options_)); +#endif // !defined(OS_CHROMEOS) } BasicDesktopEnvironment::BasicDesktopEnvironment( diff --git a/remoting/host/chromeos/aura_desktop_capturer.cc b/remoting/host/chromeos/aura_desktop_capturer.cc index d8609fe..386ccf2 100644 --- a/remoting/host/chromeos/aura_desktop_capturer.cc +++ b/remoting/host/chromeos/aura_desktop_capturer.cc @@ -43,7 +43,7 @@ SkiaBitmapDesktopFrame* SkiaBitmapDesktopFrame::Create( scoped_ptr<SkBitmap> bitmap) { webrtc::DesktopSize size(bitmap->width(), bitmap->height()); - DCHECK_EQ(kRGBA_8888_SkColorType, bitmap->info().colorType()) + DCHECK_EQ(kBGRA_8888_SkColorType, bitmap->info().colorType()) << "DesktopFrame objects always hold RGBA data."; uint8_t* bitmap_data = reinterpret_cast<uint8_t*>(bitmap->getPixels()); diff --git a/remoting/host/chromeos/aura_desktop_capturer_unittest.cc b/remoting/host/chromeos/aura_desktop_capturer_unittest.cc index 08139a9..fb41684 100644 --- a/remoting/host/chromeos/aura_desktop_capturer_unittest.cc +++ b/remoting/host/chromeos/aura_desktop_capturer_unittest.cc @@ -48,7 +48,7 @@ class AuraDesktopCapturerTest : public testing::Test, void SimulateFrameCapture() { scoped_ptr<SkBitmap> bitmap(new SkBitmap()); const SkImageInfo& info = - SkImageInfo::Make(3, 4, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + SkImageInfo::Make(3, 4, kBGRA_8888_SkColorType, kPremul_SkAlphaType); bitmap->installPixels(info, const_cast<unsigned char*>(frame_data), 12); scoped_ptr<cc::CopyOutputResult> output = diff --git a/remoting/host/chromoting_host_context.cc b/remoting/host/chromoting_host_context.cc index 754ea8b5..aa73a8c 100644 --- a/remoting/host/chromoting_host_context.cc +++ b/remoting/host/chromoting_host_context.cc @@ -4,64 +4,39 @@ #include "remoting/host/chromoting_host_context.h" -#include <string> - -#include "base/bind.h" +#include "content/public/browser/browser_thread.h" #include "remoting/base/auto_thread.h" #include "remoting/base/url_request_context_getter.h" namespace remoting { ChromotingHostContext::ChromotingHostContext( - AutoThreadTaskRunner* ui_task_runner) - : ui_task_runner_(ui_task_runner) { -#if defined(OS_WIN) - // On Windows the AudioCapturer requires COM, so we run a single-threaded - // apartment, which requires a UI thread. - audio_task_runner_ = - AutoThread::CreateWithLoopAndComInitTypes("ChromotingAudioThread", - ui_task_runner_, - base::MessageLoop::TYPE_UI, - AutoThread::COM_INIT_STA); -#else // !defined(OS_WIN) - audio_task_runner_ = AutoThread::CreateWithType( - "ChromotingAudioThread", ui_task_runner_, base::MessageLoop::TYPE_IO); -#endif // !defined(OS_WIN) - - file_task_runner_ = AutoThread::CreateWithType( - "ChromotingFileThread", ui_task_runner_, base::MessageLoop::TYPE_IO); - input_task_runner_ = AutoThread::CreateWithType( - "ChromotingInputThread", ui_task_runner_, base::MessageLoop::TYPE_IO); - network_task_runner_ = AutoThread::CreateWithType( - "ChromotingNetworkThread", ui_task_runner_, base::MessageLoop::TYPE_IO); - video_capture_task_runner_ = - AutoThread::Create("ChromotingCaptureThread", ui_task_runner_); - video_encode_task_runner_ = AutoThread::Create( - "ChromotingEncodeThread", ui_task_runner_); - - url_request_context_getter_ = new URLRequestContextGetter( - network_task_runner_, file_task_runner_); + scoped_refptr<AutoThreadTaskRunner> ui_task_runner, + scoped_refptr<AutoThreadTaskRunner> audio_task_runner, + scoped_refptr<AutoThreadTaskRunner> file_task_runner, + scoped_refptr<AutoThreadTaskRunner> input_task_runner, + scoped_refptr<AutoThreadTaskRunner> network_task_runner, + scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner, + scoped_refptr<AutoThreadTaskRunner> video_encode_task_runner, + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) + : ui_task_runner_(ui_task_runner), + audio_task_runner_(audio_task_runner), + file_task_runner_(file_task_runner), + input_task_runner_(input_task_runner), + network_task_runner_(network_task_runner), + video_capture_task_runner_(video_capture_task_runner), + video_encode_task_runner_(video_encode_task_runner), + url_request_context_getter_(url_request_context_getter) { } ChromotingHostContext::~ChromotingHostContext() { } -scoped_ptr<ChromotingHostContext> ChromotingHostContext::Create( - scoped_refptr<AutoThreadTaskRunner> ui_task_runner) { - DCHECK(ui_task_runner->BelongsToCurrentThread()); - - scoped_ptr<ChromotingHostContext> context( - new ChromotingHostContext(ui_task_runner.get())); - if (!context->audio_task_runner_.get() || !context->file_task_runner_.get() || - !context->input_task_runner_.get() || - !context->network_task_runner_.get() || - !context->video_capture_task_runner_.get() || - !context->video_encode_task_runner_.get() || - !context->url_request_context_getter_.get()) { - context.reset(); - } - - return context.Pass(); +scoped_ptr<ChromotingHostContext> ChromotingHostContext::Copy() { + return make_scoped_ptr(new ChromotingHostContext( + ui_task_runner_, audio_task_runner_, file_task_runner_, + input_task_runner_, network_task_runner_, video_capture_task_runner_, + video_encode_task_runner_, url_request_context_getter_)); } scoped_refptr<AutoThreadTaskRunner> @@ -104,4 +79,87 @@ ChromotingHostContext::url_request_context_getter() { return url_request_context_getter_; } +scoped_ptr<ChromotingHostContext> ChromotingHostContext::Create( + scoped_refptr<AutoThreadTaskRunner> ui_task_runner) { +#if defined(OS_WIN) + // On Windows the AudioCapturer requires COM, so we run a single-threaded + // apartment, which requires a UI thread. + scoped_refptr<AutoThreadTaskRunner> audio_task_runner = + AutoThread::CreateWithLoopAndComInitTypes( + "ChromotingAudioThread", ui_task_runner, base::MessageLoop::TYPE_UI, + AutoThread::COM_INIT_STA); +#else // !defined(OS_WIN) + scoped_refptr<AutoThreadTaskRunner> audio_task_runner = + AutoThread::CreateWithType("ChromotingAudioThread", ui_task_runner, + base::MessageLoop::TYPE_IO); +#endif // !defined(OS_WIN) + 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); + + return make_scoped_ptr(new ChromotingHostContext( + ui_task_runner, + audio_task_runner, + file_task_runner, + AutoThread::CreateWithType("ChromotingInputThread", ui_task_runner, + base::MessageLoop::TYPE_IO), + network_task_runner, + AutoThread::Create("ChromotingCaptureThread", ui_task_runner), + AutoThread::Create("ChromotingEncodeThread", ui_task_runner), + make_scoped_refptr( + new URLRequestContextGetter(network_task_runner, file_task_runner)))); +} + +#if defined(OS_CHROMEOS) +namespace { +// Retrieves the task_runner from the browser thread with |id|. +scoped_refptr<AutoThreadTaskRunner> WrapBrowserThread( + content::BrowserThread::ID id) { + // AutoThreadTaskRunner is a TaskRunner with the special property that it will + // continue to process tasks until no references remain, at least. The + // QuitClosure we usually pass does the simple thing of stopping the + // underlying TaskRunner. Since we are re-using the ui_task_runner of the + // browser thread, we cannot stop it explicitly. Therefore, base::DoNothing + // is passed in as the quit closure. + // TODO(kelvinp): Fix this (See crbug.com/428187). + return new AutoThreadTaskRunner( + content::BrowserThread::GetMessageLoopProxyForThread(id).get(), + base::Bind(&base::DoNothing)); +} + +} // namespace + +// static +scoped_ptr<ChromotingHostContext> ChromotingHostContext::CreateForChromeOS( + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) { + DCHECK(url_request_context_getter.get()); + + // Use BrowserThread::FILE as the joiner as it is the only browser-thread + // that allows blocking I/O, which is required by thread joining. + // TODO(kelvinp): Fix AutoThread so that it can be joinable on task runners + // that disallow I/O (crbug.com/428466). + scoped_refptr<AutoThreadTaskRunner> file_task_runner = + WrapBrowserThread(content::BrowserThread::FILE); + + scoped_refptr<AutoThreadTaskRunner> ui_task_runner = + WrapBrowserThread(content::BrowserThread::UI); + + return make_scoped_ptr(new ChromotingHostContext( + ui_task_runner, + AutoThread::CreateWithType("ChromotingAudioThread", file_task_runner, + base::MessageLoop::TYPE_IO), + file_task_runner, + AutoThread::CreateWithType("ChromotingInputThread", file_task_runner, + base::MessageLoop::TYPE_IO), + WrapBrowserThread(content::BrowserThread::IO), // network_task_runner + ui_task_runner, // video_capture_task_runner + AutoThread::CreateWithType("ChromotingEncodeThread", file_task_runner, + base::MessageLoop::TYPE_IO), + url_request_context_getter)); +} +#endif // defined(OS_CHROMEOS) + } // namespace remoting diff --git a/remoting/host/chromoting_host_context.h b/remoting/host/chromoting_host_context.h index e4638ff..2dbb34a 100644 --- a/remoting/host/chromoting_host_context.h +++ b/remoting/host/chromoting_host_context.h @@ -21,8 +21,6 @@ class AutoThreadTaskRunner; // process. This class is virtual only for testing purposes (see below). class ChromotingHostContext { public: - ~ChromotingHostContext(); - // Create threads and URLRequestContextGetter for use by a host. // During shutdown the caller should tear-down the ChromotingHostContext and // then continue to run until |ui_task_runner| is no longer referenced. @@ -30,6 +28,27 @@ class ChromotingHostContext { static scoped_ptr<ChromotingHostContext> Create( scoped_refptr<AutoThreadTaskRunner> ui_task_runner); +#if defined(OS_CHROMEOS) + // Attaches task runners to the relevant browser threads for the chromoting + // host. Must be called on the UI thread of the browser process. + // remoting::UrlRequestContextGetter returns BasicURLRequestContext under + // the hood which spawns two new threads per instance. Since + // ChromotingHostContext can be destroyed from any thread, as its owner + // (It2MeHost) is ref-counted, joining the created threads during shutdown + // violates the "Disallow IO" thread restrictions on some task runners (e.g. + // the IO Thread of the browser process). + // Instead, we re-use the |url_request_context_getter| in the browser process. + static scoped_ptr<ChromotingHostContext> CreateForChromeOS( + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter); +#endif // defined(OS_CHROMEOS) + + ~ChromotingHostContext(); + + scoped_ptr<ChromotingHostContext> Copy(); + + // Task runner for the thread that is used for the UI. + scoped_refptr<AutoThreadTaskRunner> ui_task_runner(); + // Task runner for the thread used for audio capture and encoding. scoped_refptr<AutoThreadTaskRunner> audio_task_runner(); @@ -49,9 +68,6 @@ class ChromotingHostContext { // libjingle code may be run. scoped_refptr<AutoThreadTaskRunner> network_task_runner(); - // Task runner for the thread that is used for the UI. - scoped_refptr<AutoThreadTaskRunner> ui_task_runner(); - // Task runner for the thread used by the ScreenRecorder to capture // the screen. scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner(); @@ -62,7 +78,18 @@ class ChromotingHostContext { scoped_refptr<net::URLRequestContextGetter> url_request_context_getter(); private: - ChromotingHostContext(AutoThreadTaskRunner* ui_task_runner); + ChromotingHostContext( + scoped_refptr<AutoThreadTaskRunner> ui_task_runner, + scoped_refptr<AutoThreadTaskRunner> audio_task_runner, + scoped_refptr<AutoThreadTaskRunner> file_task_runner, + scoped_refptr<AutoThreadTaskRunner> input_task_runner, + scoped_refptr<AutoThreadTaskRunner> network_task_runner, + scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner, + scoped_refptr<AutoThreadTaskRunner> video_encode_task_runner, + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter); + + // Caller-supplied UI thread. This is usually the application main thread. + scoped_refptr<AutoThreadTaskRunner> ui_task_runner_; // Thread for audio capture and encoding. scoped_refptr<AutoThreadTaskRunner> audio_task_runner_; @@ -76,9 +103,6 @@ class ChromotingHostContext { // Thread for network operations. scoped_refptr<AutoThreadTaskRunner> network_task_runner_; - // Caller-supplied UI thread. This is usually the application main thread. - scoped_refptr<AutoThreadTaskRunner> ui_task_runner_; - // Thread for screen capture. scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner_; diff --git a/remoting/host/chromoting_host_context_unittest.cc b/remoting/host/chromoting_host_context_unittest.cc index a3a48f1..853ea1c 100644 --- a/remoting/host/chromoting_host_context_unittest.cc +++ b/remoting/host/chromoting_host_context_unittest.cc @@ -18,7 +18,7 @@ TEST(ChromotingHostContextTest, StartAndStop) { scoped_ptr<ChromotingHostContext> context = ChromotingHostContext::Create(new AutoThreadTaskRunner( - message_loop.message_loop_proxy(), run_loop.QuitClosure())); + message_loop.message_loop_proxy(), run_loop.QuitClosure())); EXPECT_TRUE(context); if (!context) diff --git a/remoting/host/continue_window_chromeos.cc b/remoting/host/continue_window_chromeos.cc new file mode 100644 index 0000000..0fe427b --- /dev/null +++ b/remoting/host/continue_window_chromeos.cc @@ -0,0 +1,51 @@ +// Copyright 2014 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/continue_window.h" + +namespace remoting { + +namespace { + +// A place holder implementation for the ContinueWindow on +// ChromeOS. Remote assistance on Chrome OS is currently under a flag so it is +// secure to leave it unimplemented for now. +class ContinueWindowAura : public ContinueWindow { + public: + ContinueWindowAura(); + ~ContinueWindowAura() override; + + protected: + // ContinueWindow interface. + void ShowUi() override; + void HideUi() override; + + private: + DISALLOW_COPY_AND_ASSIGN(ContinueWindowAura); +}; + +ContinueWindowAura::ContinueWindowAura() { +} + +ContinueWindowAura::~ContinueWindowAura() { +} + +void ContinueWindowAura::ShowUi() { + // TODO(kelvinp): Implement this on Chrome OS (See crbug.com/424908). + NOTIMPLEMENTED(); +} + +void ContinueWindowAura::HideUi() { + // TODO(kelvinp): Implement this on Chrome OS (See crbug.com/424908). + NOTIMPLEMENTED(); +} + +} // namespace + +// static +scoped_ptr<HostWindow> HostWindow::CreateContinueWindow() { + return make_scoped_ptr(new ContinueWindowAura()); +} + +} // namespace remoting diff --git a/remoting/host/disconnect_window_chromeos.cc b/remoting/host/disconnect_window_chromeos.cc new file mode 100644 index 0000000..d2f8c01 --- /dev/null +++ b/remoting/host/disconnect_window_chromeos.cc @@ -0,0 +1,54 @@ +// Copyright 2014 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 <string> + +#include "ash/shell.h" +#include "ash/system/tray/system_tray_notifier.h" +#include "remoting/host/client_session_control.h" +#include "remoting/host/host_window.h" + +namespace remoting { + +namespace { + +class DisconnectWindowAura : public HostWindow { + public: + DisconnectWindowAura(); + ~DisconnectWindowAura() override; + + // HostWindow interface. + void Start(const base::WeakPtr<ClientSessionControl>& client_session_control) + override; + + private: + DISALLOW_COPY_AND_ASSIGN(DisconnectWindowAura); +}; + +DisconnectWindowAura::DisconnectWindowAura() { +} + +DisconnectWindowAura::~DisconnectWindowAura() { + ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStop(); +} + +void DisconnectWindowAura::Start( + const base::WeakPtr<ClientSessionControl>& client_session_control) { + // TODO(kelvinp): Clean up the NotifyScreenShareStart interface when we + // completely retire Hangout Remote Desktop v1. + base::string16 helper_name; + ash::Shell::GetInstance()->system_tray_notifier()->NotifyScreenShareStart( + base::Bind(&ClientSessionControl::DisconnectSession, + client_session_control), + helper_name); +} + +} // namespace + +// static +scoped_ptr<HostWindow> HostWindow::CreateDisconnectWindow() { + return make_scoped_ptr(new DisconnectWindowAura()); +} + +} // namespace remoting diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc index b9a17f8..afaaf07 100644 --- a/remoting/host/it2me/it2me_host.cc +++ b/remoting/host/it2me/it2me_host.cc @@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/strings/string_util.h" -#include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" #include "net/socket/client_socket_factory.h" #include "remoting/base/auto_thread.h" @@ -36,18 +35,19 @@ const int kMaxLoginAttempts = 5; } // namespace It2MeHost::It2MeHost( - ChromotingHostContext* host_context, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, + scoped_ptr<ChromotingHostContext> host_context, + scoped_ptr<policy_hack::PolicyWatcher> policy_watcher, base::WeakPtr<It2MeHost::Observer> observer, const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, const std::string& directory_bot_jid) - : host_context_(host_context), - task_runner_(task_runner), + : host_context_(host_context.Pass()), + task_runner_(host_context_->ui_task_runner()), observer_(observer), xmpp_server_config_(xmpp_server_config), directory_bot_jid_(directory_bot_jid), state_(kDisconnected), failed_login_attempts_(0), + policy_watcher_(policy_watcher.Pass()), nat_traversal_enabled_(false), policy_received_(false) { DCHECK(task_runner_->BelongsToCurrentThread()); @@ -67,10 +67,7 @@ void It2MeHost::Connect() { host_context_->ui_task_runner())); // Start monitoring configured policies. - policy_watcher_.reset( - policy_hack::PolicyWatcher::Create(host_context_->network_task_runner())); - policy_watcher_->StartWatching( - base::Bind(&It2MeHost::OnPolicyUpdate, this)); + policy_watcher_->StartWatching(base::Bind(&It2MeHost::OnPolicyUpdate, this)); // Switch to the network thread to start the actual connection. host_context_->network_task_runner()->PostTask( @@ -257,13 +254,16 @@ void It2MeHost::ShutdownOnUiThread() { // Stop listening for policy updates. if (policy_watcher_.get()) { - base::WaitableEvent policy_watcher_stopped_(true, false); - policy_watcher_->StopWatching(&policy_watcher_stopped_); - policy_watcher_stopped_.Wait(); - policy_watcher_.reset(); + policy_watcher_->StopWatching( + base::Bind(&It2MeHost::OnPolicyWatcherShutdown, this)); + return; } } +void It2MeHost::OnPolicyWatcherShutdown() { + policy_watcher_.reset(); +} + void It2MeHost::OnAccessDenied(const std::string& jid) { DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); @@ -311,7 +311,14 @@ void It2MeHost::OnClientDisconnected(const std::string& jid) { } void It2MeHost::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { - DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); + // The policy watcher runs on the |ui_task_runner| on ChromeOS and the + // |network_task_runner| on other platforms. + if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { + host_context_->network_task_runner()->PostTask( + FROM_HERE, + base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies))); + return; + } bool nat_policy; if (policies->GetBoolean(policy_hack::PolicyWatcher::kNatPolicyName, @@ -459,18 +466,28 @@ void It2MeHost::OnReceivedSupportID( SetState(kReceivedAccessCode); } -It2MeHostFactory::It2MeHostFactory() {} +It2MeHostFactory::It2MeHostFactory() : policy_service_(nullptr) { +} It2MeHostFactory::~It2MeHostFactory() {} +void It2MeHostFactory::set_policy_service( + policy::PolicyService* policy_service) { + DCHECK(policy_service); + DCHECK(!policy_service_) << "|policy_service| can only be set once."; + policy_service_ = policy_service; +} + scoped_refptr<It2MeHost> It2MeHostFactory::CreateIt2MeHost( - ChromotingHostContext* context, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, + scoped_ptr<ChromotingHostContext> context, base::WeakPtr<It2MeHost::Observer> observer, const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, const std::string& directory_bot_jid) { - return new It2MeHost( - context, task_runner, observer, xmpp_server_config, directory_bot_jid); + scoped_ptr<policy_hack::PolicyWatcher> policy_watcher = + policy_hack::PolicyWatcher::Create(policy_service_, + context->network_task_runner()); + return new It2MeHost(context.Pass(), policy_watcher.Pass(), observer, + xmpp_server_config, directory_bot_jid); } } // namespace remoting diff --git a/remoting/host/it2me/it2me_host.h b/remoting/host/it2me/it2me_host.h index 349232d..b2eb749 100644 --- a/remoting/host/it2me/it2me_host.h +++ b/remoting/host/it2me/it2me_host.h @@ -16,6 +16,10 @@ namespace base { class DictionaryValue; } +namespace policy { +class PolicyService; +} // namespace policy + namespace remoting { class ChromotingHost; @@ -28,9 +32,7 @@ class RegisterSupportHostRequest; class RsaKeyPair; namespace policy_hack { - class PolicyWatcher; - } // namespace policy_hack // These state values are duplicated in host_session.js. Remember to update @@ -60,8 +62,8 @@ class It2MeHost : public base::RefCountedThreadSafe<It2MeHost>, }; It2MeHost( - ChromotingHostContext* context, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, + scoped_ptr<ChromotingHostContext> context, + scoped_ptr<policy_hack::PolicyWatcher> policy_watcher, base::WeakPtr<It2MeHost::Observer> observer, const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, const std::string& directory_bot_jid); @@ -91,7 +93,7 @@ class It2MeHost : public base::RefCountedThreadSafe<It2MeHost>, ~It2MeHost() override; - ChromotingHostContext* host_context() { return host_context_; } + ChromotingHostContext* host_context() { return host_context_.get(); } scoped_refptr<base::SingleThreadTaskRunner> task_runner() { return task_runner_; } @@ -123,6 +125,10 @@ class It2MeHost : public base::RefCountedThreadSafe<It2MeHost>, // the UI thread. void ShutdownOnUiThread(); + // Called when |policy_watcher_| has stopped listening for changes and it is + // safe to delete it. + void OnPolicyWatcherShutdown(); + // Called when initial policies are read, and when they change. void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); @@ -131,10 +137,7 @@ class It2MeHost : public base::RefCountedThreadSafe<It2MeHost>, void UpdateHostDomainPolicy(const std::string& host_domain); // Caller supplied fields. - - // The creator of the It2MeHost object owns the the host context and is - // responsible for keeping it alive throughout the liftime of the host. - ChromotingHostContext* host_context_; + scoped_ptr<ChromotingHostContext> host_context_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; base::WeakPtr<It2MeHost::Observer> observer_; XmppSignalStrategy::XmppServerConfig xmpp_server_config_; @@ -181,14 +184,21 @@ class It2MeHostFactory { It2MeHostFactory(); virtual ~It2MeHostFactory(); + // |policy_service| is used for creating the policy watcher for new + // instances of It2MeHost on ChromeOS. The caller must ensure that + // |policy_service| is valid throughout the lifetime of the It2MeHostFactory + // and each created It2MeHost object. This is currently possible because + // |policy_service| is a global singleton available from the browser process. + virtual void set_policy_service(policy::PolicyService* policy_service); + virtual scoped_refptr<It2MeHost> CreateIt2MeHost( - ChromotingHostContext* context, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, + scoped_ptr<ChromotingHostContext> context, base::WeakPtr<It2MeHost::Observer> observer, const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, const std::string& directory_bot_jid); private: + policy::PolicyService* policy_service_; DISALLOW_COPY_AND_ASSIGN(It2MeHostFactory); }; diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc index 24ddc1b..93286b3 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.cc +++ b/remoting/host/it2me/it2me_native_messaging_host.cc @@ -15,8 +15,9 @@ #include "base/strings/stringize_macros.h" #include "base/threading/thread.h" #include "base/values.h" +#include "media/base/media.h" #include "net/base/net_util.h" -#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_request_context_getter.h" #include "remoting/base/auth_token_util.h" #include "remoting/base/service_urls.h" #include "remoting/host/chromoting_host_context.h" @@ -35,23 +36,22 @@ const remoting::protocol::NameMapElement<It2MeHostState> kIt2MeHostStates[] = { {kConnected, "CONNECTED"}, {kDisconnecting, "DISCONNECTING"}, {kError, "ERROR"}, - {kInvalidDomainError, "INVALID_DOMAIN_ERROR"}, }; + {kInvalidDomainError, "INVALID_DOMAIN_ERROR"}, +}; } // namespace It2MeNativeMessagingHost::It2MeNativeMessagingHost( - scoped_refptr<AutoThreadTaskRunner> task_runner, + scoped_ptr<ChromotingHostContext> context, scoped_ptr<It2MeHostFactory> factory) : client_(NULL), + host_context_(context.Pass()), factory_(factory.Pass()), weak_factory_(this) { weak_ptr_ = weak_factory_.GetWeakPtr(); - // Initialize the host context to manage the threads for the it2me host. - // The native messaging host, rather than the It2MeHost object, owns and - // maintains the lifetime of the host context. - - host_context_.reset(ChromotingHostContext::Create(task_runner).release()); + // Ensures runtime specific CPU features are initialized. + media::InitializeCPUSpecificMediaFeatures(); const ServiceUrls* service_urls = ServiceUrls::GetInstance(); const bool xmpp_server_valid = @@ -203,8 +203,7 @@ void It2MeNativeMessagingHost::ProcessConnect( #endif // !defined(NDEBUG) // Create the It2Me host and start connecting. - it2me_host_ = factory_->CreateIt2MeHost(host_context_.get(), - host_context_->ui_task_runner(), + it2me_host_ = factory_->CreateIt2MeHost(host_context_->Copy(), weak_ptr_, xmpp_config, directory_bot_jid_); diff --git a/remoting/host/it2me/it2me_native_messaging_host.h b/remoting/host/it2me/it2me_native_messaging_host.h index 1780d73..ba4b6e6 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.h +++ b/remoting/host/it2me/it2me_native_messaging_host.h @@ -10,6 +10,7 @@ #include "base/memory/weak_ptr.h" #include "extensions/browser/api/messaging/native_message_host.h" #include "remoting/base/auto_thread_task_runner.h" +#include "remoting/host/chromoting_host_context.h" #include "remoting/host/it2me/it2me_host.h" namespace base { @@ -23,19 +24,22 @@ namespace remoting { class It2MeNativeMessagingHost : public It2MeHost::Observer, public extensions::NativeMessageHost { public: - It2MeNativeMessagingHost(scoped_refptr<AutoThreadTaskRunner> task_runner, - scoped_ptr<It2MeHostFactory> factory); - ~It2MeNativeMessagingHost() override; + It2MeNativeMessagingHost( + scoped_ptr<ChromotingHostContext> host_context, + scoped_ptr<It2MeHostFactory> host_factory); + ~It2MeNativeMessagingHost(); // extensions::NativeMessageHost implementation. void OnMessage(const std::string& message) override; void Start(Client* client) override; - scoped_refptr<base::SingleThreadTaskRunner> task_runner() const override; + scoped_refptr<base::SingleThreadTaskRunner> task_runner() + const override; // It2MeHost::Observer implementation. - void OnClientAuthenticated(const std::string& client_username) override; + void OnClientAuthenticated(const std::string& client_username) + override; void OnStoreAccessCode(const std::string& access_code, - base::TimeDelta access_code_lifetime) override; + base::TimeDelta access_code_lifetime) override; void OnNatPolicyChanged(bool nat_traversal_enabled) override; void OnStateChanged(It2MeHostState state) override; @@ -56,8 +60,8 @@ class It2MeNativeMessagingHost : public It2MeHost::Observer, void SendMessageToClient(scoped_ptr<base::DictionaryValue> message) const; Client* client_; - scoped_ptr<It2MeHostFactory> factory_; scoped_ptr<ChromotingHostContext> host_context_; + scoped_ptr<It2MeHostFactory> factory_; scoped_refptr<It2MeHost> it2me_host_; // Cached, read-only copies of |it2me_host_| session state. diff --git a/remoting/host/it2me/it2me_native_messaging_host_main.cc b/remoting/host/it2me/it2me_native_messaging_host_main.cc index 7d27d19..cf30a87 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_main.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_main.cc @@ -9,10 +9,10 @@ #include "base/i18n/icu_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "media/base/media.h" #include "net/socket/ssl_server_socket.h" #include "remoting/base/breakpad.h" #include "remoting/base/resources.h" +#include "remoting/host/chromoting_host_context.h" #include "remoting/host/host_exit_codes.h" #include "remoting/host/it2me/it2me_native_messaging_host.h" #include "remoting/host/logging.h" @@ -80,9 +80,6 @@ int StartIt2MeNativeMessagingHost() { // single-threaded. net::EnableSSLServerSockets(); - // Ensures runtime specific CPU features are initialized. - media::InitializeCPUSpecificMediaFeatures(); - #if defined(OS_WIN) // GetStdHandle() returns pseudo-handles for stdin and stdout even if // the hosting executable specifies "Windows" subsystem. However the returned @@ -126,8 +123,7 @@ int StartIt2MeNativeMessagingHost() { new PipeMessagingChannel(read_file.Pass(), write_file.Pass())); scoped_ptr<extensions::NativeMessageHost> host(new It2MeNativeMessagingHost( - task_runner, - factory.Pass())); + ChromotingHostContext::Create(task_runner), factory.Pass())); host->Start(native_messaging_pipe.get()); diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc index 89702b1..18d5c85 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc @@ -19,6 +19,7 @@ #include "remoting/host/chromoting_host_context.h" #include "remoting/host/native_messaging/native_messaging_pipe.h" #include "remoting/host/native_messaging/pipe_messaging_channel.h" +#include "remoting/host/policy_hack/policy_watcher.h" #include "remoting/host/setup/test_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -67,13 +68,13 @@ void VerifyCommonProperties(scoped_ptr<base::DictionaryValue> response, class MockIt2MeHost : public It2MeHost { public: - MockIt2MeHost(ChromotingHostContext* context, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, + MockIt2MeHost(scoped_ptr<ChromotingHostContext> context, + scoped_ptr<policy_hack::PolicyWatcher> policy_watcher, base::WeakPtr<It2MeHost::Observer> observer, const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, const std::string& directory_bot_jid) - : It2MeHost(context, - task_runner, + : It2MeHost(context.Pass(), + policy_watcher.Pass(), observer, xmpp_server_config, directory_bot_jid) {} @@ -148,15 +149,14 @@ void MockIt2MeHost::RunSetState(It2MeHostState state) { class MockIt2MeHostFactory : public It2MeHostFactory { public: - MockIt2MeHostFactory() {} + MockIt2MeHostFactory() : It2MeHostFactory() {} scoped_refptr<It2MeHost> CreateIt2MeHost( - ChromotingHostContext* context, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, + scoped_ptr<ChromotingHostContext> context, base::WeakPtr<It2MeHost::Observer> observer, const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, const std::string& directory_bot_jid) override { - return new MockIt2MeHost( - context, task_runner, observer, xmpp_server_config, directory_bot_jid); + return new MockIt2MeHost(context.Pass(), nullptr, observer, + xmpp_server_config, directory_bot_jid); } private: @@ -429,19 +429,17 @@ void It2MeNativeMessagingHostTest::StartHost() { ASSERT_TRUE(MakePipe(&input_read_file, &input_write_file_)); ASSERT_TRUE(MakePipe(&output_read_file_, &output_write_file)); - // Creating a native messaging host with a mock It2MeHostFactory. - scoped_ptr<It2MeHostFactory> factory(new MockIt2MeHostFactory()); - pipe_.reset(new NativeMessagingPipe()); scoped_ptr<extensions::NativeMessagingChannel> channel( new PipeMessagingChannel(input_read_file.Pass(), output_write_file.Pass())); + // Creating a native messaging host with a mock It2MeHostFactory. scoped_ptr<extensions::NativeMessageHost> it2me_host( new It2MeNativeMessagingHost( - host_task_runner_, - factory.Pass())); + ChromotingHostContext::Create(host_task_runner_), + make_scoped_ptr(new MockIt2MeHostFactory()))); it2me_host->Start(pipe_.get()); pipe_->Start(it2me_host.Pass(), diff --git a/remoting/host/policy_hack/policy_watcher.cc b/remoting/host/policy_hack/policy_watcher.cc index e603cf5..8e30c24 100644 --- a/remoting/host/policy_hack/policy_watcher.cc +++ b/remoting/host/policy_hack/policy_watcher.cc @@ -12,7 +12,6 @@ #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" #include "base/time/time.h" #include "base/values.h" #include "remoting/host/dns_blackhole_checker.h" @@ -165,19 +164,17 @@ void PolicyWatcher::StartWatching(const PolicyCallback& policy_callback) { StartWatchingInternal(); } -void PolicyWatcher::StopWatching(base::WaitableEvent* done) { - if (!OnPolicyWatcherThread()) { - task_runner_->PostTask(FROM_HERE, - base::Bind(&PolicyWatcher::StopWatching, - base::Unretained(this), done)); - return; - } +void PolicyWatcher::StopWatching(const base::Closure& stopped_callback) { + task_runner_->PostTaskAndReply( + FROM_HERE, base::Bind(&PolicyWatcher::StopWatchingOnPolicyWatcherThread, + base::Unretained(this)), + stopped_callback); +} +void PolicyWatcher::StopWatchingOnPolicyWatcherThread() { StopWatchingInternal(); weak_factory_.InvalidateWeakPtrs(); policy_callback_.Reset(); - - done->Signal(); } void PolicyWatcher::ScheduleFallbackReloadTask() { diff --git a/remoting/host/policy_hack/policy_watcher.h b/remoting/host/policy_hack/policy_watcher.h index 0ced8f2..109a110 100644 --- a/remoting/host/policy_hack/policy_watcher.h +++ b/remoting/host/policy_hack/policy_watcher.h @@ -8,6 +8,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/values.h" +#include "components/policy/core/common/policy_service.h" namespace base { class SingleThreadTaskRunner; @@ -38,12 +39,15 @@ class PolicyWatcher { virtual void StartWatching(const PolicyCallback& policy_callback); // Should be called after StartWatching() before the object is deleted. Calls - // just wait for |done| to be signaled before deleting the object. - virtual void StopWatching(base::WaitableEvent* done); - - // Implemented by each platform. This message loop should be an IO message - // loop. - static PolicyWatcher* Create( + // should wait for |stopped_callback| to be called before deleting it. + virtual void StopWatching(const base::Closure& stopped_callback); + + // Implemented by each platform. |task_runner| should be an IO message loop. + // |policy_service| is currently only used on ChromeOS. The caller must + // ensure that |policy_service| remains valid for the lifetime of + // PolicyWatcher. + static scoped_ptr<PolicyWatcher> Create( + policy::PolicyService* policy_service, scoped_refptr<base::SingleThreadTaskRunner> task_runner); // The name of the NAT traversal policy. @@ -107,6 +111,7 @@ class PolicyWatcher { const base::DictionaryValue& Defaults() const; private: + void StopWatchingOnPolicyWatcherThread(); scoped_refptr<base::SingleThreadTaskRunner> task_runner_; PolicyCallback policy_callback_; diff --git a/remoting/host/policy_hack/policy_watcher_chromeos.cc b/remoting/host/policy_hack/policy_watcher_chromeos.cc new file mode 100644 index 0000000..39d1d97 --- /dev/null +++ b/remoting/host/policy_hack/policy_watcher_chromeos.cc @@ -0,0 +1,90 @@ +// Copyright 2014 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/policy_hack/policy_watcher.h" + +#include "components/policy/core/common/policy_service.h" +#include "content/public/browser/browser_thread.h" +#include "remoting/base/auto_thread_task_runner.h" + +using namespace policy; + +namespace remoting { +namespace policy_hack { + +namespace { + +class PolicyWatcherChromeOS : public PolicyWatcher, + public PolicyService::Observer { + public: + PolicyWatcherChromeOS(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + PolicyService* policy_service); + + ~PolicyWatcherChromeOS() override; + + // PolicyService::Observer interface. + void OnPolicyUpdated(const PolicyNamespace& ns, + const PolicyMap& previous, + const PolicyMap& current) override; + + protected: + // PolicyWatcher interface. + void Reload() override; + void StartWatchingInternal() override; + void StopWatchingInternal() override; + + private: + PolicyService* policy_service_; + + DISALLOW_COPY_AND_ASSIGN(PolicyWatcherChromeOS); +}; + +PolicyWatcherChromeOS::PolicyWatcherChromeOS( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + PolicyService* policy_service) + : PolicyWatcher(task_runner), policy_service_(policy_service) { +} + +PolicyWatcherChromeOS::~PolicyWatcherChromeOS() { +} + +void PolicyWatcherChromeOS::OnPolicyUpdated(const PolicyNamespace& ns, + const PolicyMap& previous, + const PolicyMap& current) { + scoped_ptr<base::DictionaryValue> policy_dict(new base::DictionaryValue()); + for (PolicyMap::const_iterator it = current.begin(); it != current.end(); + it++) { + policy_dict->Set(it->first, it->second.value->DeepCopy()); + } + UpdatePolicies(policy_dict.get()); +} + +void PolicyWatcherChromeOS::Reload() { + PolicyNamespace ns(POLICY_DOMAIN_CHROME, std::string()); + const PolicyMap& current = policy_service_->GetPolicies(ns); + OnPolicyUpdated(ns, current, current); +}; + +void PolicyWatcherChromeOS::StartWatchingInternal() { + policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this); + Reload(); +}; + +void PolicyWatcherChromeOS::StopWatchingInternal() { + policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this); +}; + +} // namespace + +scoped_ptr<PolicyWatcher> PolicyWatcher::Create( + policy::PolicyService* policy_service, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + return make_scoped_ptr(new PolicyWatcherChromeOS( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::UI), + policy_service)); +} + +} // namespace policy_hack +} // namespace remoting diff --git a/remoting/host/policy_hack/policy_watcher_linux.cc b/remoting/host/policy_hack/policy_watcher_linux.cc index f4096b8..3ffefea 100644 --- a/remoting/host/policy_hack/policy_watcher_linux.cc +++ b/remoting/host/policy_hack/policy_watcher_linux.cc @@ -244,10 +244,11 @@ class PolicyWatcherLinux : public PolicyWatcher { base::WeakPtrFactory<PolicyWatcherLinux> weak_factory_; }; -PolicyWatcher* PolicyWatcher::Create( +scoped_ptr<PolicyWatcher> PolicyWatcher::Create( + policy::PolicyService* policy_service, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { base::FilePath policy_dir(kPolicyDir); - return new PolicyWatcherLinux(task_runner, policy_dir); + return make_scoped_ptr(new PolicyWatcherLinux(task_runner, policy_dir)); } } // namespace policy_hack diff --git a/remoting/host/policy_hack/policy_watcher_mac.mm b/remoting/host/policy_hack/policy_watcher_mac.mm index 7779db6..23e223b 100644 --- a/remoting/host/policy_hack/policy_watcher_mac.mm +++ b/remoting/host/policy_hack/policy_watcher_mac.mm @@ -82,9 +82,10 @@ class PolicyWatcherMac : public PolicyWatcher { } }; -PolicyWatcher* PolicyWatcher::Create( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - return new PolicyWatcherMac(task_runner); +scoped_ptr<PolicyWatcher> PolicyWatcher::Create( + policy::PolicyService* policy_service, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + return make_scoped_ptr(new PolicyWatcherMac(task_runner)); } } // namespace policy_hack diff --git a/remoting/host/policy_hack/policy_watcher_unittest.cc b/remoting/host/policy_hack/policy_watcher_unittest.cc index 5cae57b..bef254c 100644 --- a/remoting/host/policy_hack/policy_watcher_unittest.cc +++ b/remoting/host/policy_hack/policy_watcher_unittest.cc @@ -99,12 +99,14 @@ class PolicyWatcherTest : public testing::Test { } void StopWatching() { - base::WaitableEvent stop_event(false, false); - policy_watcher_->StopWatching(&stop_event); + EXPECT_CALL(*this, PostPolicyWatcherShutdown()).Times(1); + policy_watcher_->StopWatching(base::Bind( + &PolicyWatcherTest::PostPolicyWatcherShutdown, base::Unretained(this))); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(true, stop_event.IsSignaled()); } + MOCK_METHOD0(PostPolicyWatcherShutdown, void()); + static const char* kHostDomain; static const char* kPortRange; base::MessageLoop message_loop_; diff --git a/remoting/host/policy_hack/policy_watcher_win.cc b/remoting/host/policy_hack/policy_watcher_win.cc index cea8516..6b18c93 100644 --- a/remoting/host/policy_hack/policy_watcher_win.cc +++ b/remoting/host/policy_hack/policy_watcher_win.cc @@ -216,9 +216,10 @@ class PolicyWatcherWin : bool machine_policy_watcher_failed_; }; -PolicyWatcher* PolicyWatcher::Create( +scoped_ptr<PolicyWatcher> PolicyWatcher::Create( + policy::PolicyService* policy_service, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - return new PolicyWatcherWin(task_runner); + return make_scoped_ptr(new PolicyWatcherWin(task_runner)); } } // namespace policy_hack diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 444d5ab..f880803 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -19,7 +19,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "build/build_config.h" #include "crypto/nss_util.h" @@ -260,6 +259,8 @@ class HostProcess void ShutdownOnNetworkThread(); + void OnPolicyWatcherShutdown(); + // Crashes the process in response to a daemon's request. The daemon passes // the location of the code that detected the fatal error resulted in this // request. @@ -524,8 +525,8 @@ void HostProcess::OnConfigUpdated( // already loaded so PolicyWatcher has to be started here. Separate policy // loading from policy verifications and move |policy_watcher_| // initialization to StartOnNetworkThread(). - policy_watcher_.reset( - policy_hack::PolicyWatcher::Create(context_->file_task_runner())); + policy_watcher_ = policy_hack::PolicyWatcher::Create( + nullptr, context_->network_task_runner()); policy_watcher_->StartWatching( base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this))); } else { @@ -1411,24 +1412,25 @@ void HostProcess::ShutdownOnNetworkThread() { state_ = HOST_STOPPED; if (policy_watcher_.get()) { - base::WaitableEvent done_event(true, false); - policy_watcher_->StopWatching(&done_event); - done_event.Wait(); - policy_watcher_.reset(); + policy_watcher_->StopWatching( + base::Bind(&HostProcess::OnPolicyWatcherShutdown, this)); + } else { + OnPolicyWatcherShutdown(); } - - config_watcher_.reset(); - - // Complete the rest of shutdown on the main thread. - context_->ui_task_runner()->PostTask( - FROM_HERE, - base::Bind(&HostProcess::ShutdownOnUiThread, this)); } else { // This method is only called in STOPPING_TO_RESTART and STOPPING states. NOTREACHED(); } } +void HostProcess::OnPolicyWatcherShutdown() { + policy_watcher_.reset(); + + // Complete the rest of shutdown on the main thread. + context_->ui_task_runner()->PostTask( + FROM_HERE, base::Bind(&HostProcess::ShutdownOnUiThread, this)); +} + void HostProcess::OnCrash(const std::string& function_name, const std::string& file_name, const int& line_number) { diff --git a/remoting/remoting_host.gypi b/remoting/remoting_host.gypi index fdc333e..d4e2406 100644 --- a/remoting/remoting_host.gypi +++ b/remoting/remoting_host.gypi @@ -21,9 +21,9 @@ 'enable_it2me_host': 0, 'enable_remoting_host': 0, }], - ['chromeos==1', { + ['chromeos==1 and use_x11==1', { 'enable_me2me_host': 0, - 'enable_it2me_host': 0, + 'enable_it2me_host': 1, }], ], }, @@ -98,6 +98,7 @@ 'host/constants_mac.h', 'host/continue_window.cc', 'host/continue_window.h', + 'host/continue_window_chromeos.cc', 'host/continue_window_linux.cc', 'host/continue_window_mac.mm', 'host/continue_window_win.cc', @@ -124,6 +125,7 @@ 'host/desktop_shape_tracker_mac.cc', 'host/desktop_shape_tracker_win.cc', 'host/desktop_shape_tracker_x11.cc', + 'host/disconnect_window_chromeos.cc', 'host/disconnect_window_linux.cc', 'host/disconnect_window_mac.h', 'host/disconnect_window_mac.mm', @@ -227,6 +229,7 @@ 'host/pin_hash.h', 'host/policy_hack/policy_watcher.cc', 'host/policy_hack/policy_watcher.h', + 'host/policy_hack/policy_watcher_chromeos.cc', 'host/policy_hack/policy_watcher_linux.cc', 'host/policy_hack/policy_watcher_mac.mm', 'host/policy_hack/policy_watcher_win.cc', @@ -319,6 +322,7 @@ ['chromeos==1', { 'dependencies' : [ '../cc/cc.gyp:cc', + '../components/components.gyp:policy_component_common', '../content/content.gyp:content', '../ppapi/ppapi_internal.gyp:ppapi_host', '../skia/skia.gyp:skia', @@ -329,8 +333,7 @@ '../third_party/skia/include/utils', ], 'sources!' : [ - 'host/continue_window.cc', - 'host/continue_window.h', + 'host/policy_hack/policy_watcher_linux.cc', 'host/continue_window_linux.cc', 'host/disconnect_window.cc', 'host/disconnect_window_linux.cc', @@ -340,6 +343,9 @@ 'sources!' : [ 'host/chromeos/aura_desktop_capturer.cc', 'host/chromeos/aura_desktop_capturer.h', + 'host/continue_window_chromeos.cc', + 'host/disconnect_window_chromeos.cc', + 'host/policy_hack/policy_watcher_chromeos.cc', ], }], ['OS=="mac"', { @@ -853,7 +859,7 @@ ], # targets }], # end of OS!="win" and enable_me2me_host==1 - ['OS!="win" and enable_it2me_host==1', { + ['OS!="win" and enable_it2me_host==1 and chromeos==0', { 'targets': [ { 'target_name': 'remoting_it2me_native_messaging_host', |