blob: 7b48a746c6254902b7e495c1917ce5c7ce3dce5b [file] [log] [blame]
// Copyright 2013 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 "base/at_exit.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "net/url_request/url_fetcher.h"
#include "remoting/host/host_exit_codes.h"
#include "remoting/host/logging.h"
#include "remoting/host/pairing_registry_delegate.h"
#include "remoting/host/setup/me2me_native_messaging_host.h"
namespace {
const char kParentWindowSwitchName[] = "parent-window";
} // namespace
namespace remoting {
int Me2MeNativeMessagingHostMain() {
#if defined(OS_WIN)
// GetStdHandle() returns pseudo-handles for stdin and stdout even if
// the hosting executable specifies "Windows" subsystem. However the returned
// handles are invalid in that case unless standard input and output are
// redirected to a pipe or file.
base::PlatformFile read_file = GetStdHandle(STD_INPUT_HANDLE);
base::PlatformFile write_file = GetStdHandle(STD_OUTPUT_HANDLE);
#elif defined(OS_POSIX)
base::PlatformFile read_file = STDIN_FILENO;
base::PlatformFile write_file = STDOUT_FILENO;
#else
#error Not implemented.
#endif
// Mac OS X requires that the main thread be a UI message loop in order to
// receive distributed notifications from the System Preferences pane. An
// IO thread is needed for the pairing registry and URL context getter.
base::Thread io_thread("io_thread");
io_thread.StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
base::MessageLoopForUI message_loop;
base::RunLoop run_loop;
scoped_refptr<DaemonController> daemon_controller =
DaemonController::Create();
// Pass handle of the native view to the controller so that the UAC prompts
// are focused properly.
const CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(kParentWindowSwitchName)) {
std::string native_view =
command_line->GetSwitchValueASCII(kParentWindowSwitchName);
int64 native_view_handle = 0;
if (base::StringToInt64(native_view, &native_view_handle)) {
daemon_controller->SetWindow(reinterpret_cast<void*>(native_view_handle));
} else {
LOG(WARNING) << "Invalid parameter value --" << kParentWindowSwitchName
<< "=" << native_view;
}
}
// OAuth client (for credential requests).
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter(
new URLRequestContextGetter(io_thread.message_loop_proxy()));
scoped_ptr<OAuthClient> oauth_client(
new OAuthClient(url_request_context_getter));
net::URLFetcher::SetIgnoreCertificateRequests(true);
// Create the pairing registry and native messaging host.
scoped_refptr<protocol::PairingRegistry> pairing_registry =
CreatePairingRegistry(io_thread.message_loop_proxy());
// Set up the native messaging channel.
scoped_ptr<NativeMessagingChannel> channel(
new NativeMessagingChannel(read_file, write_file));
scoped_ptr<Me2MeNativeMessagingHost> host(
new Me2MeNativeMessagingHost(channel.Pass(),
daemon_controller,
pairing_registry,
oauth_client.Pass()));
host->Start(run_loop.QuitClosure());
// Run the loop until channel is alive.
run_loop.Run();
return kSuccessExitCode;
}
} // namespace remoting
int main(int argc, char** argv) {
// This object instance is required by Chrome code (such as MessageLoop).
base::AtExitManager exit_manager;
CommandLine::Init(argc, argv);
remoting::InitHostLogging();
return remoting::Me2MeNativeMessagingHostMain();
}