summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkelvinp <kelvinp@chromium.org>2014-10-29 21:51:10 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-30 04:51:36 +0000
commit54dde6f02d121ff745e66b57205583087ff720ec (patch)
tree53403070b7678dbf7a648f85269ef35fc0392150
parentbe340fc4f1e630896b571128b4a593d1e8df6eca (diff)
downloadchromium_src-54dde6f02d121ff745e66b57205583087ff720ec.zip
chromium_src-54dde6f02d121ff745e66b57205583087ff720ec.tar.gz
chromium_src-54dde6f02d121ff745e66b57205583087ff720ec.tar.bz2
Remote assistance on Chrome OS Part IV - It2MeHost
This CL links the it2me host to the Chrome binary on ChromeOS behind a flag. The following changes are made to the it2me host so that it can be run in the browser process. 1. Initializes SSL server sockets and specific CPU media features on ChromeOS startup. 2. Fixes a crash in it2me shutdown by making It2meHost owns the ChromotingHostContext. 3. Replace the blocking shutdown wait on PolicyWatcher with a callback. Implements policy_watcher on ChromeOS using policy services. 4. Re-use existing threads, url request context getters and policy service on ChromeOS. 5. Fixed a incorrect DCHECK regarding the color format of the frames captured on ChromeOS. BUG=334087 Review URL: https://codereview.chromium.org/639233002 Cr-Commit-Position: refs/heads/master@{#302034}
-rw-r--r--chrome/browser/chromeos/chrome_browser_main_chromeos.cc5
-rw-r--r--chrome/browser/extensions/api/DEPS2
-rw-r--r--chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc40
-rw-r--r--chrome/chrome_browser_extensions.gypi4
-rw-r--r--remoting/DEPS1
-rw-r--r--remoting/host/DEPS2
-rw-r--r--remoting/host/basic_desktop_environment.cc7
-rw-r--r--remoting/host/chromeos/aura_desktop_capturer.cc2
-rw-r--r--remoting/host/chromeos/aura_desktop_capturer_unittest.cc2
-rw-r--r--remoting/host/chromoting_host_context.cc152
-rw-r--r--remoting/host/chromoting_host_context.h42
-rw-r--r--remoting/host/chromoting_host_context_unittest.cc2
-rw-r--r--remoting/host/continue_window_chromeos.cc51
-rw-r--r--remoting/host/disconnect_window_chromeos.cc54
-rw-r--r--remoting/host/it2me/it2me_host.cc55
-rw-r--r--remoting/host/it2me/it2me_host.h32
-rw-r--r--remoting/host/it2me/it2me_native_messaging_host.cc19
-rw-r--r--remoting/host/it2me/it2me_native_messaging_host.h18
-rw-r--r--remoting/host/it2me/it2me_native_messaging_host_main.cc8
-rw-r--r--remoting/host/it2me/it2me_native_messaging_host_unittest.cc26
-rw-r--r--remoting/host/policy_hack/policy_watcher.cc17
-rw-r--r--remoting/host/policy_hack/policy_watcher.h17
-rw-r--r--remoting/host/policy_hack/policy_watcher_chromeos.cc90
-rw-r--r--remoting/host/policy_hack/policy_watcher_linux.cc5
-rw-r--r--remoting/host/policy_hack/policy_watcher_mac.mm7
-rw-r--r--remoting/host/policy_hack/policy_watcher_unittest.cc8
-rw-r--r--remoting/host/policy_hack/policy_watcher_win.cc5
-rw-r--r--remoting/host/remoting_me2me_host.cc30
-rw-r--r--remoting/remoting_host.gypi14
29 files changed, 540 insertions, 177 deletions
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 85b1ba6..e469bbb 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -114,6 +114,7 @@
#include "content/public/common/main_function_params.h"
#include "media/audio/sounds/sounds_manager.h"
#include "net/base/network_change_notifier.h"
+#include "net/socket/ssl_server_socket.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/touch/touch_device.h"
@@ -312,6 +313,10 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
dbus_services_.reset(new internal::DBusServices(parameters()));
+ // Enable support for SSL server sockets, which must be done while still
+ // single-threaded. This is required for remote assistance host on Chrome OS.
+ net::EnableSSLServerSockets();
+
ChromeBrowserMainPartsLinux::PostMainMessageLoopStart();
}
diff --git a/chrome/browser/extensions/api/DEPS b/chrome/browser/extensions/api/DEPS
index 7b1dbb3..c043985 100644
--- a/chrome/browser/extensions/api/DEPS
+++ b/chrome/browser/extensions/api/DEPS
@@ -2,4 +2,6 @@ include_rules = [
"+apps",
"+chrome/browser/apps",
"+device/hid",
+ # Enable remote assistance on Chrome OS
+ "+remoting/host",
]
diff --git a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
index 799a5b6..8dfb32c 100644
--- a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
@@ -16,9 +16,15 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/values.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/api/messaging/native_messaging_test_util.h"
+#include "components/policy/core/common/policy_service.h"
#include "extensions/common/constants.h"
+#include "extensions/common/switches.h"
#include "extensions/common/url_pattern.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "remoting/host/chromoting_host_context.h"
+#include "remoting/host/it2me/it2me_native_messaging_host.h"
#include "ui/gfx/native_widget_types.h"
#include "url/gurl.h"
@@ -26,10 +32,9 @@ namespace extensions {
namespace {
-// A simple NativeMesageHost that echoes the received message. It is currently
-// used for testing.
-// TODO(kelvinp): Replace this class once Remote Assistance in process host
-// is implemented.
+// A simple NativeMessageHost that mimics the implementation of
+// chrome/test/data/native_messaging/native_hosts/echo.py. It is currently
+// used for testing by ExtensionApiTest::NativeMessagingBasic.
const char* const kEchoHostOrigins[] = {
// ScopedTestNativeMessagingHost::kExtensionId
@@ -90,25 +95,46 @@ struct BuiltInHost {
scoped_ptr<NativeMessageHost>(*create_function)();
};
+scoped_ptr<NativeMessageHost> CreateIt2MeHost() {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableRemoteAssistance)) {
+ scoped_ptr<remoting::It2MeHostFactory> host_factory(
+ new remoting::It2MeHostFactory());
+ host_factory->set_policy_service(g_browser_process->policy_service());
+ scoped_ptr<remoting::ChromotingHostContext> context =
+ remoting::ChromotingHostContext::CreateForChromeOS(
+ make_scoped_refptr(g_browser_process->system_request_context()));
+ scoped_ptr<NativeMessageHost> host(new remoting::It2MeNativeMessagingHost(
+ context.Pass(), host_factory.Pass()));
+ return host.Pass();
+ }
+ return nullptr;
+}
+
// If you modify the list of allowed_origins, don't forget to update
// remoting/host/it2me/com.google.chrome.remote_assistance.json.jinja2
// to keep the two lists in sync.
// TODO(kelvinp): Load the native messaging manifest as a resource file into
-// chrome and fetch the list of allowed_origins from the manifest.
-/*const char* const kRemotingIt2MeOrigins[] = {
+// chrome and fetch the list of allowed_origins from the manifest (see
+// crbug/424743).
+const char* const kRemotingIt2MeOrigins[] = {
"chrome-extension://ljacajndfccfgnfohlgkdphmbnpkjflk/",
"chrome-extension://gbchcmhmhahfdphkhkmpfmihenigjmpp/",
"chrome-extension://kgngmbheleoaphbjbaiobfdepmghbfah/",
"chrome-extension://odkaodonbgfohohmklejpjiejmcipmib/",
"chrome-extension://dokpleeekgeeiehdhmdkeimnkmoifgdd/",
"chrome-extension://ajoainacpilcemgiakehflpbkbfipojk/",
- "chrome-extension://hmboipgjngjoiaeicfdifdoeacilalgc/"};*/
+ "chrome-extension://hmboipgjngjoiaeicfdifdoeacilalgc/"};
static const BuiltInHost kBuiltInHost[] = {
{"com.google.chrome.test.echo", // ScopedTestNativeMessagingHost::kHostName
kEchoHostOrigins,
arraysize(kEchoHostOrigins),
&EchoHost::Create},
+ {"com.google.chrome.remote_assistance",
+ kRemotingIt2MeOrigins,
+ arraysize(kRemotingIt2MeOrigins),
+ &CreateIt2MeHost},
};
bool MatchesSecurityOrigin(const BuiltInHost& host,
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 13f9d10..1025de3 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -961,6 +961,10 @@
'../build/linux/system.gyp:dbus',
'../chromeos/ime/input_method.gyp:gencode',
'../third_party/libevent/libevent.gyp:libevent',
+ '../remoting/remoting.gyp:remoting_it2me_host_static',
+ ],
+ 'include_dirs': [
+ '../third_party/libjingle/source',
],
'sources': [
'<@(chrome_browser_extensions_chromeos_sources)',
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..aca9d71 100644
--- a/remoting/remoting_host.gypi
+++ b/remoting/remoting_host.gypi
@@ -23,7 +23,7 @@
}],
['chromeos==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',