Index: chrome/service/service_process.cc |
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc |
index 60229d6c9509c25a3e63c7db947e4810defdb686..fbd9c8d544fea6d091dd02c916f21beda64d09b6 100644 |
--- a/chrome/service/service_process.cc |
+++ b/chrome/service/service_process.cc |
@@ -16,16 +16,17 @@ |
#include "net/base/network_change_notifier.h" |
#if defined(ENABLE_REMOTING) |
+#include "remoting/base/constants.h" |
#include "remoting/base/encoder_zlib.h" |
#include "remoting/host/chromoting_host.h" |
#include "remoting/host/chromoting_host_context.h" |
-#include "remoting/host/host_config.h" |
+#include "remoting/host/json_host_config.h" |
#if defined(OS_WIN) |
#include "remoting/host/capturer_gdi.h" |
#include "remoting/host/event_executor_win.h" |
#elif defined(OS_LINUX) |
-#include "remoting/host/capturer_linux.h" |
+#include "remoting/host/capturer_fake.h" |
#include "remoting/host/event_executor_linux.h" |
#elif defined(OS_MACOSX) |
#include "remoting/host/capturer_mac.h" |
@@ -35,12 +36,15 @@ |
ServiceProcess* g_service_process = NULL; |
-ServiceProcess::ServiceProcess() : shutdown_event_(true, false) { |
+ServiceProcess::ServiceProcess() |
+ : shutdown_event_(true, false), |
+ main_message_loop_(NULL) { |
DCHECK(!g_service_process); |
g_service_process = this; |
} |
-bool ServiceProcess::Initialize() { |
+bool ServiceProcess::Initialize(MessageLoop* message_loop) { |
+ main_message_loop_ = message_loop; |
network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
base::Thread::Options options; |
options.message_loop_type = MessageLoop::TYPE_IO; |
@@ -74,9 +78,16 @@ bool ServiceProcess::Initialize() { |
} |
bool ServiceProcess::Teardown() { |
- service_prefs_->WritePrefs(); |
- service_prefs_.reset(); |
+ if (service_prefs_.get()) { |
+ service_prefs_->WritePrefs(); |
+ service_prefs_.reset(); |
+ } |
cloud_print_proxy_.reset(); |
+ |
+#if defined(ENABLE_REMOTING) |
+ ShutdownChromotingHost(); |
+#endif |
+ |
ipc_server_.reset(); |
// Signal this event before shutting down the service process. That way all |
// background threads can cleanup. |
@@ -86,6 +97,7 @@ bool ServiceProcess::Teardown() { |
// The NetworkChangeNotifier must be destroyed after all other threads that |
// might use it have been shut down. |
network_change_notifier_.reset(); |
+ |
return true; |
} |
@@ -98,19 +110,29 @@ CloudPrintProxy* ServiceProcess::GetCloudPrintProxy() { |
} |
#if defined(ENABLE_REMOTING) |
-remoting::ChromotingHost* ServiceProcess::CreateChromotingHost( |
- remoting::ChromotingHostContext* context, |
- remoting::MutableHostConfig* config) { |
+bool ServiceProcess::StartChromotingHost() { |
+ // We have already started. |
+ if (chromoting_context_.get()) |
+ return true; |
+ |
+ // Load chromoting config from the disk. |
+ LoadChromotingConfig(); |
+ |
+ // Start the chromoting context first. |
+ chromoting_context_.reset(new remoting::ChromotingHostContext()); |
+ chromoting_context_->Start(); |
+ |
+ // Create capturer, encoder and executor. The ownership will be transfered |
+ // to the chromoting host. |
scoped_ptr<remoting::Capturer> capturer; |
scoped_ptr<remoting::Encoder> encoder; |
scoped_ptr<remoting::EventExecutor> executor; |
- // Select the capturer and encoder from |config|. |
#if defined(OS_WIN) |
capturer.reset(new remoting::CapturerGdi()); |
executor.reset(new remoting::EventExecutorWin()); |
#elif defined(OS_LINUX) |
- capturer.reset(new remoting::CapturerLinux()); |
+ capturer.reset(new remoting::CapturerFake()); |
executor.reset(new remoting::EventExecutorLinux()); |
#elif defined(OS_MACOSX) |
capturer.reset(new remoting::CapturerMac()); |
@@ -118,8 +140,81 @@ remoting::ChromotingHost* ServiceProcess::CreateChromotingHost( |
#endif |
encoder.reset(new remoting::EncoderZlib()); |
- return new remoting::ChromotingHost(context, config, capturer.release(), |
- encoder.release(), executor.release()); |
+ // Create a chromoting host object. |
+ chromoting_host_ = new remoting::ChromotingHost(chromoting_context_.get(), |
+ chromoting_config_, |
+ capturer.release(), |
+ encoder.release(), |
+ executor.release()); |
+ |
+ // Then start the chromoting host. |
+ // When ChromotingHost is shutdown because of failure or a request that |
+ // we made OnChromotingShutdown() is calls. |
+ chromoting_host_->Start( |
+ NewRunnableMethod(this, &ServiceProcess::OnChromotingHostShutdown)); |
+ return true; |
+} |
+ |
+bool ServiceProcess::ShutdownChromotingHost() { |
+ // Chromoting host doesn't exist so return true. |
+ if (!chromoting_host_) |
+ return true; |
+ |
+ // Shutdown the chromoting host asynchronously. This will signal the host to |
+ // shutdown, we'll actually wait for all threads to stop when we destroy |
+ // the chromoting context. |
+ chromoting_host_->Shutdown(); |
+ chromoting_host_ = NULL; |
+ return true; |
+} |
+ |
+// A util function to update the login information to host config. |
+static void SaveChromotingConfigFunc(remoting::JsonHostConfig* config, |
+ const std::string& login, |
+ const std::string& token, |
+ const std::string& host_id, |
+ const std::string& host_name, |
+ const std::string& private_key) { |
+ config->SetString(remoting::kXmppLoginConfigPath, login); |
+ config->SetString(remoting::kXmppAuthTokenConfigPath, token); |
+ config->SetString(remoting::kHostIdConfigPath, host_id); |
+ config->SetString(remoting::kHostNameConfigPath, host_name); |
+ config->SetString(remoting::kPrivateKeyConfigPath, private_key); |
+} |
+ |
+void ServiceProcess::SaveChromotingConfig(const std::string& login, |
+ const std::string& token, |
+ const std::string& host_id, |
+ const std::string& host_name, |
+ const std::string& private_key) { |
+ // First we need to load the config first. |
+ LoadChromotingConfig(); |
+ |
+ // And then do the update. |
+ chromoting_config_->Update( |
+ NewRunnableFunction(&SaveChromotingConfigFunc, chromoting_config_.get(), |
+ login, token, host_id, host_name, private_key)); |
+} |
+ |
+void ServiceProcess::LoadChromotingConfig() { |
+ // TODO(hclam): We really should be doing this on IO thread so we are not |
+ // blocked on file IOs. |
+ if (chromoting_config_) |
+ return; |
+ |
+ FilePath user_data_dir; |
+ PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
+ FilePath chromoting_config_path = |
+ user_data_dir.Append(FILE_PATH_LITERAL(".ChromotingConfig.json")); |
+ chromoting_config_ = new remoting::JsonHostConfig( |
+ chromoting_config_path, file_thread_->message_loop_proxy()); |
+ if (!chromoting_config_->Read()) { |
+ LOG(INFO) << "Failed to read chromoting config file."; |
+ } |
+} |
+ |
+void ServiceProcess::OnChromotingHostShutdown() { |
+ // TODO(hclam): Implement. |
} |
#endif |
@@ -127,3 +222,7 @@ ServiceProcess::~ServiceProcess() { |
Teardown(); |
g_service_process = NULL; |
} |
+ |
+// Disable refcounting for runnable method because it is really not needed |
+// when we post tasks on the main message loop. |
+DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcess); |