Skia roll f73c237291b:8d84c995319
[chromium-blink-merge.git] / remoting / host / it2me / it2me_native_messaging_host_main.cc
blobbec6b3901f534c0f65f4c80d4a1c7da748f85323
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/host/it2me/it2me_native_messaging_host_main.h"
7 #include "base/at_exit.h"
8 #include "base/command_line.h"
9 #include "base/i18n/icu_util.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "media/base/media.h"
13 #include "net/socket/ssl_server_socket.h"
14 #include "remoting/base/breakpad.h"
15 #include "remoting/base/resources.h"
16 #include "remoting/host/host_exit_codes.h"
17 #include "remoting/host/it2me/it2me_native_messaging_host.h"
18 #include "remoting/host/logging.h"
19 #include "remoting/host/usage_stats_consent.h"
21 #if defined(OS_LINUX)
22 #include <gtk/gtk.h>
23 #endif // defined(OS_LINUX)
25 #if defined(OS_MACOSX)
26 #include "base/mac/scoped_nsautorelease_pool.h"
27 #endif // defined(OS_MACOSX)
29 #if defined(OS_WIN)
30 #include <commctrl.h>
31 #endif // defined(OS_WIN)
33 namespace remoting {
35 // Creates a It2MeNativeMessagingHost instance, attaches it to stdin/stdout and
36 // runs the message loop until It2MeNativeMessagingHost signals shutdown.
37 int StartIt2MeNativeMessagingHost() {
38 #if defined(OS_MACOSX)
39 // Needed so we don't leak objects when threads are created.
40 base::mac::ScopedNSAutoreleasePool pool;
41 #endif // defined(OS_MACOSX)
43 #if defined(REMOTING_ENABLE_BREAKPAD)
44 // Initialize Breakpad as early as possible. On Mac the command-line needs to
45 // be initialized first, so that the preference for crash-reporting can be
46 // looked up in the config file.
47 if (IsUsageStatsAllowed()) {
48 InitializeCrashReporting();
50 #endif // defined(REMOTING_ENABLE_BREAKPAD)
52 #if defined(OS_WIN)
53 // Register and initialize common controls.
54 INITCOMMONCONTROLSEX info;
55 info.dwSize = sizeof(info);
56 info.dwICC = ICC_STANDARD_CLASSES;
57 InitCommonControlsEx(&info);
58 #endif // defined(OS_WIN)
60 // Required to find the ICU data file, used by some file_util routines.
61 base::i18n::InitializeICU();
63 remoting::LoadResources("");
65 // Cannot use TOOLKIT_GTK because it is not defined when aura is enabled.
66 #if defined(OS_LINUX)
67 // Required for any calls into GTK functions, such as the Disconnect and
68 // Continue windows. Calling with NULL arguments because we don't have
69 // any command line arguments for gtk to consume.
70 gtk_init(NULL, NULL);
71 #endif // OS_LINUX
73 // Enable support for SSL server sockets, which must be done while still
74 // single-threaded.
75 net::EnableSSLServerSockets();
77 // Ensures runtime specific CPU features are initialized.
78 media::InitializeCPUSpecificMediaFeatures();
80 #if defined(OS_WIN)
81 // GetStdHandle() returns pseudo-handles for stdin and stdout even if
82 // the hosting executable specifies "Windows" subsystem. However the returned
83 // handles are invalid in that case unless standard input and output are
84 // redirected to a pipe or file.
85 base::File read_file(GetStdHandle(STD_INPUT_HANDLE));
86 base::File write_file(GetStdHandle(STD_OUTPUT_HANDLE));
88 // After the native messaging channel starts the native messaging reader
89 // will keep doing blocking read operations on the input named pipe.
90 // If any other thread tries to perform any operation on STDIN, it will also
91 // block because the input named pipe is synchronous (non-overlapped).
92 // It is pretty common for a DLL to query the device info (GetFileType) of
93 // the STD* handles at startup. So any LoadLibrary request can potentially
94 // be blocked. To prevent that from happening we close STDIN and STDOUT
95 // handles as soon as we retrieve the corresponding file handles.
96 SetStdHandle(STD_INPUT_HANDLE, NULL);
97 SetStdHandle(STD_OUTPUT_HANDLE, NULL);
98 #elif defined(OS_POSIX)
99 // The files are automatically closed.
100 base::File read_file(STDIN_FILENO);
101 base::File write_file(STDOUT_FILENO);
102 #else
103 #error Not implemented.
104 #endif
106 base::MessageLoopForUI message_loop;
107 base::RunLoop run_loop;
109 scoped_refptr<AutoThreadTaskRunner> task_runner =
110 new remoting::AutoThreadTaskRunner(message_loop.message_loop_proxy(),
111 run_loop.QuitClosure());
113 scoped_ptr<It2MeHostFactory> factory(new It2MeHostFactory());
115 // Set up the native messaging channel.
116 scoped_ptr<NativeMessagingChannel> channel(
117 new NativeMessagingChannel(read_file.Pass(), write_file.Pass()));
119 scoped_ptr<It2MeNativeMessagingHost> host(
120 new It2MeNativeMessagingHost(
121 task_runner, channel.Pass(), factory.Pass()));
122 host->Start(run_loop.QuitClosure());
124 // Run the loop until channel is alive.
125 run_loop.Run();
127 return kSuccessExitCode;
130 int It2MeNativeMessagingHostMain(int argc, char** argv) {
131 // This object instance is required by Chrome code (such as MessageLoop).
132 base::AtExitManager exit_manager;
134 base::CommandLine::Init(argc, argv);
135 remoting::InitHostLogging();
137 return StartIt2MeNativeMessagingHost();
140 } // namespace remoting