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"
24 #endif // defined(OS_LINUX)
26 #if defined(OS_MACOSX)
27 #include "base/mac/scoped_nsautorelease_pool.h"
28 #endif // defined(OS_MACOSX)
32 #endif // defined(OS_WIN)
36 // Creates a It2MeNativeMessagingHost instance, attaches it to stdin/stdout and
37 // runs the message loop until It2MeNativeMessagingHost signals shutdown.
38 int StartIt2MeNativeMessagingHost() {
39 #if defined(OS_MACOSX)
40 // Needed so we don't leak objects when threads are created.
41 base::mac::ScopedNSAutoreleasePool pool
;
42 #endif // defined(OS_MACOSX)
44 #if defined(REMOTING_ENABLE_BREAKPAD)
45 // Initialize Breakpad as early as possible. On Mac the command-line needs to
46 // be initialized first, so that the preference for crash-reporting can be
47 // looked up in the config file.
48 if (IsUsageStatsAllowed()) {
49 InitializeCrashReporting();
51 #endif // defined(REMOTING_ENABLE_BREAKPAD)
54 // Register and initialize common controls.
55 INITCOMMONCONTROLSEX info
;
56 info
.dwSize
= sizeof(info
);
57 info
.dwICC
= ICC_STANDARD_CLASSES
;
58 InitCommonControlsEx(&info
);
59 #endif // defined(OS_WIN)
61 // Required to find the ICU data file, used by some file_util routines.
62 base::i18n::InitializeICU();
64 remoting::LoadResources("");
66 // Cannot use TOOLKIT_GTK because it is not defined when aura is enabled.
68 // Required in order for us to run multiple X11 threads.
71 // Required for any calls into GTK functions, such as the Disconnect and
72 // Continue windows. Calling with NULL arguments because we don't have
73 // any command line arguments for gtk to consume.
77 // Enable support for SSL server sockets, which must be done while still
79 net::EnableSSLServerSockets();
81 // Ensures runtime specific CPU features are initialized.
82 media::InitializeCPUSpecificMediaFeatures();
85 // GetStdHandle() returns pseudo-handles for stdin and stdout even if
86 // the hosting executable specifies "Windows" subsystem. However the returned
87 // handles are invalid in that case unless standard input and output are
88 // redirected to a pipe or file.
89 base::File
read_file(GetStdHandle(STD_INPUT_HANDLE
));
90 base::File
write_file(GetStdHandle(STD_OUTPUT_HANDLE
));
92 // After the native messaging channel starts the native messaging reader
93 // will keep doing blocking read operations on the input named pipe.
94 // If any other thread tries to perform any operation on STDIN, it will also
95 // block because the input named pipe is synchronous (non-overlapped).
96 // It is pretty common for a DLL to query the device info (GetFileType) of
97 // the STD* handles at startup. So any LoadLibrary request can potentially
98 // be blocked. To prevent that from happening we close STDIN and STDOUT
99 // handles as soon as we retrieve the corresponding file handles.
100 SetStdHandle(STD_INPUT_HANDLE
, NULL
);
101 SetStdHandle(STD_OUTPUT_HANDLE
, NULL
);
102 #elif defined(OS_POSIX)
103 // The files are automatically closed.
104 base::File
read_file(STDIN_FILENO
);
105 base::File
write_file(STDOUT_FILENO
);
107 #error Not implemented.
110 base::MessageLoopForUI message_loop
;
111 base::RunLoop run_loop
;
113 scoped_refptr
<AutoThreadTaskRunner
> task_runner
=
114 new remoting::AutoThreadTaskRunner(message_loop
.message_loop_proxy(),
115 run_loop
.QuitClosure());
117 scoped_ptr
<It2MeHostFactory
> factory(new It2MeHostFactory());
119 // Set up the native messaging channel.
120 scoped_ptr
<NativeMessagingChannel
> channel(
121 new NativeMessagingChannel(read_file
.Pass(), write_file
.Pass()));
123 scoped_ptr
<It2MeNativeMessagingHost
> host(
124 new It2MeNativeMessagingHost(
125 task_runner
, channel
.Pass(), factory
.Pass()));
126 host
->Start(run_loop
.QuitClosure());
128 // Run the loop until channel is alive.
131 return kSuccessExitCode
;
134 int It2MeNativeMessagingHostMain(int argc
, char** argv
) {
135 // This object instance is required by Chrome code (such as MessageLoop).
136 base::AtExitManager exit_manager
;
138 base::CommandLine::Init(argc
, argv
);
139 remoting::InitHostLogging();
141 return StartIt2MeNativeMessagingHost();
144 } // namespace remoting