Home | History | Annotate | Download | only in setup
      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.
      4 
      5 #include "base/at_exit.h"
      6 #include "base/command_line.h"
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/run_loop.h"
      9 #include "base/strings/string_number_conversions.h"
     10 #include "net/url_request/url_fetcher.h"
     11 #include "remoting/host/host_exit_codes.h"
     12 #include "remoting/host/logging.h"
     13 #include "remoting/host/pairing_registry_delegate.h"
     14 #include "remoting/host/setup/me2me_native_messaging_host.h"
     15 
     16 namespace {
     17 
     18 const char kParentWindowSwitchName[] = "parent-window";
     19 
     20 }  // namespace
     21 
     22 namespace remoting {
     23 
     24 int Me2MeNativeMessagingHostMain() {
     25 #if defined(OS_WIN)
     26   // GetStdHandle() returns pseudo-handles for stdin and stdout even if
     27   // the hosting executable specifies "Windows" subsystem. However the returned
     28   // handles are invalid in that case unless standard input and output are
     29   // redirected to a pipe or file.
     30   base::PlatformFile read_file = GetStdHandle(STD_INPUT_HANDLE);
     31   base::PlatformFile write_file = GetStdHandle(STD_OUTPUT_HANDLE);
     32 #elif defined(OS_POSIX)
     33   base::PlatformFile read_file = STDIN_FILENO;
     34   base::PlatformFile write_file = STDOUT_FILENO;
     35 #else
     36 #error Not implemented.
     37 #endif
     38 
     39   // Mac OS X requires that the main thread be a UI message loop in order to
     40   // receive distributed notifications from the System Preferences pane. An
     41   // IO thread is needed for the pairing registry and URL context getter.
     42   base::Thread io_thread("io_thread");
     43   io_thread.StartWithOptions(
     44       base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
     45 
     46   base::MessageLoopForUI message_loop;
     47   base::RunLoop run_loop;
     48 
     49   scoped_refptr<DaemonController> daemon_controller =
     50       DaemonController::Create();
     51 
     52   // Pass handle of the native view to the controller so that the UAC prompts
     53   // are focused properly.
     54   const CommandLine* command_line = CommandLine::ForCurrentProcess();
     55   if (command_line->HasSwitch(kParentWindowSwitchName)) {
     56     std::string native_view =
     57         command_line->GetSwitchValueASCII(kParentWindowSwitchName);
     58     int64 native_view_handle = 0;
     59     if (base::StringToInt64(native_view, &native_view_handle)) {
     60       daemon_controller->SetWindow(reinterpret_cast<void*>(native_view_handle));
     61     } else {
     62       LOG(WARNING) << "Invalid parameter value --" << kParentWindowSwitchName
     63                    << "=" << native_view;
     64     }
     65   }
     66 
     67   // OAuth client (for credential requests).
     68   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter(
     69       new URLRequestContextGetter(io_thread.message_loop_proxy()));
     70   scoped_ptr<OAuthClient> oauth_client(
     71       new OAuthClient(url_request_context_getter));
     72 
     73   net::URLFetcher::SetIgnoreCertificateRequests(true);
     74 
     75   // Create the pairing registry and native messaging host.
     76   scoped_refptr<protocol::PairingRegistry> pairing_registry =
     77       CreatePairingRegistry(io_thread.message_loop_proxy());
     78 
     79   // Set up the native messaging channel.
     80   scoped_ptr<NativeMessagingChannel> channel(
     81       new NativeMessagingChannel(read_file, write_file));
     82 
     83   scoped_ptr<Me2MeNativeMessagingHost> host(
     84       new Me2MeNativeMessagingHost(channel.Pass(),
     85                               daemon_controller,
     86                               pairing_registry,
     87                               oauth_client.Pass()));
     88   host->Start(run_loop.QuitClosure());
     89 
     90   // Run the loop until channel is alive.
     91   run_loop.Run();
     92   return kSuccessExitCode;
     93 }
     94 
     95 }  // namespace remoting
     96 
     97 int main(int argc, char** argv) {
     98   // This object instance is required by Chrome code (such as MessageLoop).
     99   base::AtExitManager exit_manager;
    100 
    101   CommandLine::Init(argc, argv);
    102   remoting::InitHostLogging();
    103 
    104   return remoting::Me2MeNativeMessagingHostMain();
    105 }
    106