Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / host / it2me / it2me_native_messaging_host_main.cc
blob50b43482833be0d64653601a687678d14119e414
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 "net/socket/ssl_server_socket.h"
13 #include "remoting/base/breakpad.h"
14 #include "remoting/host/chromoting_host_context.h"
15 #include "remoting/host/host_exit_codes.h"
16 #include "remoting/host/it2me/it2me_native_messaging_host.h"
17 #include "remoting/host/logging.h"
18 #include "remoting/host/native_messaging/native_messaging_pipe.h"
19 #include "remoting/host/native_messaging/pipe_messaging_channel.h"
20 #include "remoting/host/resources.h"
21 #include "remoting/host/usage_stats_consent.h"
23 #if defined(OS_LINUX)
24 #include <gtk/gtk.h>
25 #include <X11/Xlib.h>
26 #endif // defined(OS_LINUX)
28 #if defined(OS_MACOSX)
29 #include "base/mac/scoped_nsautorelease_pool.h"
30 #endif // defined(OS_MACOSX)
32 #if defined(OS_WIN)
33 #include <commctrl.h>
34 #endif // defined(OS_WIN)
36 namespace remoting {
38 // Creates a It2MeNativeMessagingHost instance, attaches it to stdin/stdout and
39 // runs the message loop until It2MeNativeMessagingHost signals shutdown.
40 int StartIt2MeNativeMessagingHost() {
41 #if defined(OS_MACOSX)
42 // Needed so we don't leak objects when threads are created.
43 base::mac::ScopedNSAutoreleasePool pool;
44 #endif // defined(OS_MACOSX)
46 #if defined(REMOTING_ENABLE_BREAKPAD)
47 // Initialize Breakpad as early as possible. On Mac the command-line needs to
48 // be initialized first, so that the preference for crash-reporting can be
49 // looked up in the config file.
50 if (IsUsageStatsAllowed()) {
51 InitializeCrashReporting();
53 #endif // defined(REMOTING_ENABLE_BREAKPAD)
55 #if defined(OS_WIN)
56 // Register and initialize common controls.
57 INITCOMMONCONTROLSEX info;
58 info.dwSize = sizeof(info);
59 info.dwICC = ICC_STANDARD_CLASSES;
60 InitCommonControlsEx(&info);
61 #endif // defined(OS_WIN)
63 // Required to find the ICU data file, used by some file_util routines.
64 base::i18n::InitializeICU();
66 remoting::LoadResources("");
68 // Cannot use TOOLKIT_GTK because it is not defined when aura is enabled.
69 #if defined(OS_LINUX)
70 // Required in order for us to run multiple X11 threads.
71 XInitThreads();
73 // Required for any calls into GTK functions, such as the Disconnect and
74 // Continue windows. Calling with nullptr arguments because we don't have
75 // any command line arguments for gtk to consume.
76 gtk_init(nullptr, nullptr);
77 #endif // OS_LINUX
79 // Enable support for SSL server sockets, which must be done while still
80 // single-threaded.
81 net::EnableSSLServerSockets();
83 #if defined(OS_WIN)
84 // GetStdHandle() returns pseudo-handles for stdin and stdout even if
85 // the hosting executable specifies "Windows" subsystem. However the returned
86 // handles are invalid in that case unless standard input and output are
87 // redirected to a pipe or file.
88 base::File read_file(GetStdHandle(STD_INPUT_HANDLE));
89 base::File write_file(GetStdHandle(STD_OUTPUT_HANDLE));
91 // After the native messaging channel starts the native messaging reader
92 // will keep doing blocking read operations on the input named pipe.
93 // If any other thread tries to perform any operation on STDIN, it will also
94 // block because the input named pipe is synchronous (non-overlapped).
95 // It is pretty common for a DLL to query the device info (GetFileType) of
96 // the STD* handles at startup. So any LoadLibrary request can potentially
97 // be blocked. To prevent that from happening we close STDIN and STDOUT
98 // handles as soon as we retrieve the corresponding file handles.
99 SetStdHandle(STD_INPUT_HANDLE, nullptr);
100 SetStdHandle(STD_OUTPUT_HANDLE, nullptr);
101 #elif defined(OS_POSIX)
102 // The files are automatically closed.
103 base::File read_file(STDIN_FILENO);
104 base::File write_file(STDOUT_FILENO);
105 #else
106 #error Not implemented.
107 #endif
109 base::MessageLoopForUI message_loop;
110 base::RunLoop run_loop;
112 scoped_ptr<It2MeHostFactory> factory(new It2MeHostFactory());
114 scoped_ptr<NativeMessagingPipe> native_messaging_pipe(
115 new NativeMessagingPipe());
117 // Set up the native messaging channel.
118 scoped_ptr<extensions::NativeMessagingChannel> channel(
119 new PipeMessagingChannel(read_file.Pass(), write_file.Pass()));
121 scoped_ptr<ChromotingHostContext> context =
122 ChromotingHostContext::Create(new remoting::AutoThreadTaskRunner(
123 message_loop.task_runner(), run_loop.QuitClosure()));
124 scoped_ptr<extensions::NativeMessageHost> host(
125 new It2MeNativeMessagingHost(context.Pass(), factory.Pass()));
127 host->Start(native_messaging_pipe.get());
129 native_messaging_pipe->Start(host.Pass(), channel.Pass());
131 // Run the loop until channel is alive.
132 run_loop.Run();
134 return kSuccessExitCode;
137 int It2MeNativeMessagingHostMain(int argc, char** argv) {
138 // This object instance is required by Chrome code (such as MessageLoop).
139 base::AtExitManager exit_manager;
141 base::CommandLine::Init(argc, argv);
142 remoting::InitHostLogging();
144 return StartIt2MeNativeMessagingHost();
147 } // namespace remoting