Chromium Code Reviews| Index: remoting/host/remoting_me2me_host.cc |
| diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc |
| index b08a7dafe2afbb7a15910413c8998c63630215f2..1847a731132fabd5884dee6116fbdd8e2f310c98 100644 |
| --- a/remoting/host/remoting_me2me_host.cc |
| +++ b/remoting/host/remoting_me2me_host.cc |
| @@ -12,9 +12,9 @@ |
| #include "base/command_line.h" |
| #include "base/file_path.h" |
| #include "base/file_util.h" |
| -#include "base/files/file_path_watcher.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/memory/weak_ptr.h" |
| #include "base/message_loop.h" |
| #include "base/scoped_native_library.h" |
| #include "base/string_util.h" |
| @@ -34,14 +34,16 @@ |
| #include "remoting/host/branding.h" |
| #include "remoting/host/chromoting_host.h" |
| #include "remoting/host/chromoting_host_context.h" |
| -#include "remoting/host/composite_host_config.h" |
| +#include "remoting/host/chromoting_messages.h" |
| #include "remoting/host/constants.h" |
| +#include "remoting/host/daemon_config_watcher.h" |
| #include "remoting/host/desktop_environment.h" |
| #include "remoting/host/event_executor.h" |
| #include "remoting/host/heartbeat_sender.h" |
| #include "remoting/host/host_config.h" |
| #include "remoting/host/host_event_logger.h" |
| #include "remoting/host/host_user_interface.h" |
| +#include "remoting/host/json_host_config.h" |
| #include "remoting/host/log_to_server.h" |
| #include "remoting/host/network_settings.h" |
| #include "remoting/host/policy_hack/policy_watcher.h" |
| @@ -52,10 +54,6 @@ |
| #include "remoting/jingle_glue/xmpp_signal_strategy.h" |
| #include "remoting/protocol/me2me_host_authenticator_factory.h" |
| -#if defined(OS_POSIX) |
| -#include "remoting/host/posix/sighup_listener.h" |
| -#endif // defined(OS_POSIX) |
| - |
| #if defined(OS_MACOSX) |
| #include "base/mac/scoped_cftyperef.h" |
| #include "base/mac/scoped_nsautorelease_pool.h" |
| @@ -76,16 +74,8 @@ namespace { |
| // This is used for tagging system event logs. |
| const char kApplicationName[] = "chromoting"; |
| -// The command line switch specifying the name of the Chromoting IPC channel. |
| -const char kDaemonIpcSwitchName[] = "chromoting-ipc"; |
| - |
| -// These are used for parsing the config-file locations from the command line, |
| -// and for defining the default locations if the switches are not present. |
| -const char kAuthConfigSwitchName[] = "auth-config"; |
| -const char kHostConfigSwitchName[] = "host-config"; |
| - |
| -const FilePath::CharType kDefaultHostConfigFile[] = |
| - FILE_PATH_LITERAL("host.json"); |
| +// The command line switch specifying the name of the daemon IPC endpoint. |
| +const char kDaemonIpcSwitchName[] = "daemon-pipe"; |
| const int kMinPortNumber = 12400; |
| const int kMaxPortNumber = 12409; |
| @@ -104,10 +94,12 @@ namespace remoting { |
| class HostProcess |
| : public HeartbeatSender::Listener, |
| - public IPC::Listener { |
| + public IPC::Listener, |
| + public DaemonConfigWatcher::Delegate { |
| public: |
| HostProcess(scoped_ptr<ChromotingHostContext> context) |
| : context_(context.Pass()), |
| + config_(FilePath()), |
| #ifdef OFFICIAL_BUILD |
| oauth_use_official_client_id_(true), |
| #else |
| @@ -116,18 +108,16 @@ class HostProcess |
| allow_nat_traversal_(true), |
| restarting_(false), |
| shutting_down_(false), |
| - exit_code_(kSuccessExitCode) |
| + exit_code_(kSuccessExitCode), |
| #if defined(OS_MACOSX) |
| - , curtain_(base::Bind(&HostProcess::OnDisconnectRequested, |
| + curtain_(base::Bind(&HostProcess::OnDisconnectRequested, |
| base::Unretained(this)), |
| base::Bind(&HostProcess::OnDisconnectRequested, |
| base::Unretained(this))) |
| #endif |
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) |
| { |
| network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
| - config_updated_timer_.reset(new base::DelayTimer<HostProcess>( |
| - FROM_HERE, base::TimeDelta::FromSeconds(2), this, |
| - &HostProcess::ConfigUpdatedDelayed)); |
| } |
| bool InitWithCommandLine(const CommandLine* cmd_line) { |
| @@ -146,85 +136,75 @@ class HostProcess |
| context_->network_task_runner())); |
| } |
| +#if !defined(REMOTING_MULTI_PROCESS) |
| FilePath default_config_dir = remoting::GetConfigDir(); |
| - if (cmd_line->HasSwitch(kAuthConfigSwitchName)) { |
| - FilePath path = cmd_line->GetSwitchValuePath(kAuthConfigSwitchName); |
| - config_.AddConfigPath(path); |
| - } |
| - |
| host_config_path_ = default_config_dir.Append(kDefaultHostConfigFile); |
| if (cmd_line->HasSwitch(kHostConfigSwitchName)) { |
| host_config_path_ = cmd_line->GetSwitchValuePath(kHostConfigSwitchName); |
| } |
| - config_.AddConfigPath(host_config_path_); |
| +#endif // !defined(REMOTING_MULTI_PROCESS) |
| return true; |
| } |
| - void ConfigUpdated() { |
| + virtual void OnConfigUpdated(const std::string& config) OVERRIDE { |
| DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| - // Call ConfigUpdatedDelayed after a short delay, so that this object won't |
| - // try to read the updated configuration file before it has been |
| - // completely written. |
| - // If the writer moves the new configuration file into place atomically, |
| - // this delay may not be necessary. |
| - config_updated_timer_->Reset(); |
| - } |
| - |
| - void ConfigUpdatedDelayed() { |
| - DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| + LOG(INFO) << "Processing new host configuration."; |
| - if (LoadConfig()) { |
| - // PostTask to create new authenticator factory in case PIN has changed. |
| + if (!config_.SetSerializedData(config)) { |
| + LOG(ERROR) << "Invalid configuration."; |
| context_->network_task_runner()->PostTask( |
| FROM_HERE, |
| - base::Bind(&HostProcess::CreateAuthenticatorFactory, |
| - base::Unretained(this))); |
| - } else { |
| - LOG(ERROR) << "Invalid configuration."; |
| + base::Bind(&HostProcess::Shutdown, base::Unretained(this), |
| + kInvalidHostConfigurationExitCode)); |
|
Wez
2012/08/24 22:20:38
nit: Just call OnConfigWatcherError()?
alexeypa (please no reviews)
2012/08/27 23:16:41
Done.
|
| + return; |
| } |
| - } |
| -#if defined(OS_WIN) |
| - class ConfigChangedDelegate : public base::files::FilePathWatcher::Delegate { |
| - public: |
| - ConfigChangedDelegate( |
| - scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| - const base::Closure& callback) |
| - : task_runner_(task_runner), |
| - callback_(callback) { |
| + if (!ApplyConfig()) { |
| + LOG(ERROR) << "Failed to apply the configuration."; |
| + context_->network_task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HostProcess::Shutdown, base::Unretained(this), |
| + kInvalidHostConfigurationExitCode)); |
|
Wez
2012/08/24 22:20:38
nit: Just invoke OnConfigWatcherError()?
alexeypa (please no reviews)
2012/08/27 23:16:41
Done.
|
| + return; |
| } |
| - void OnFilePathChanged(const FilePath& path) OVERRIDE { |
| - task_runner_->PostTask(FROM_HERE, callback_); |
| - } |
| + // Start watching the policy (and eventually start the host) if this is |
| + // the first configuration update. Otherwise, post a task to create new |
| + // authenticator factory in case PIN has changed. |
| + if (policy_watcher_.get() == NULL) { |
| +#if defined(OS_MACOSX) || defined(OS_WIN) |
| + host_user_interface_.reset(new HostUserInterface(context_.get())); |
| +#endif |
| - void OnFilePathError(const FilePath& path) OVERRIDE { |
| + StartWatchingPolicy(); |
| + } else { |
| + // PostTask to create new authenticator factory in case PIN has changed. |
| + context_->network_task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HostProcess::CreateAuthenticatorFactory, |
| + base::Unretained(this))); |
| } |
| + } |
| - private: |
| - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| - base::Closure callback_; |
| + virtual void OnConfigWatcherError() OVERRIDE { |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| - DISALLOW_COPY_AND_ASSIGN(ConfigChangedDelegate); |
| - }; |
| -#endif // defined(OS_WIN) |
| + context_->network_task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HostProcess::Shutdown, base::Unretained(this), |
| + kInvalidHostConfigurationExitCode)); |
| + } |
| - void ListenForConfigChanges() { |
| -#if defined(OS_POSIX) |
| - remoting::RegisterHupSignalHandler( |
| - base::Bind(&HostProcess::ConfigUpdatedDelayed, base::Unretained(this))); |
| -#elif defined(OS_WIN) |
| - scoped_refptr<base::files::FilePathWatcher::Delegate> delegate( |
| - new ConfigChangedDelegate( |
| - context_->ui_task_runner(), |
| - base::Bind(&HostProcess::ConfigUpdated, base::Unretained(this)))); |
| - config_watcher_.reset(new base::files::FilePathWatcher()); |
| - if (!config_watcher_->Watch(host_config_path_, delegate)) { |
| - LOG(ERROR) << "Couldn't watch file " << host_config_path_.value(); |
| - } |
| -#endif // defined (OS_WIN) |
| + void StartWatchingConfigChanges() { |
| +#if !defined(REMOTING_MULTI_PROCESS) |
| + // Start watching the host configuration file. |
| + config_watcher_.reset(new DaemonConfigWatcher(context_->ui_task_runner(), |
| + context_->file_task_runner(), |
| + weak_factory_.GetWeakPtr())); |
| + config_watcher_->Watch(host_config_path_); |
| +#endif // !defined(REMOTING_MULTI_PROCESS) |
| } |
| void CreateAuthenticatorFactory() { |
| @@ -238,14 +218,25 @@ class HostProcess |
| // IPC::Listener implementation. |
| virtual bool OnMessageReceived(const IPC::Message& message) { |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| + |
| +#if defined(REMOTING_MULTI_PROCESS) |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(HostProcess, message) |
| + IPC_MESSAGE_HANDLER(ChromotingDaemonNetworkMsg_Configuration, |
| + OnConfigUpdated) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +#else // !defined(REMOTING_MULTI_PROCESS) |
| return false; |
| +#endif // !defined(REMOTING_MULTI_PROCESS) |
| } |
| void StartHostProcess() { |
| DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| - if (!InitWithCommandLine(CommandLine::ForCurrentProcess()) || |
| - !LoadConfig()) { |
| + if (!InitWithCommandLine(CommandLine::ForCurrentProcess())) { |
| context_->network_task_runner()->PostTask( |
| FROM_HERE, |
| base::Bind(&HostProcess::Shutdown, base::Unretained(this), |
| @@ -253,23 +244,21 @@ class HostProcess |
| return; |
| } |
| -#if defined(OS_MACOSX) || defined(OS_WIN) |
| - host_user_interface_.reset(new HostUserInterface(context_.get())); |
| -#endif |
| - |
| - StartWatchingPolicy(); |
| - |
| -#if defined(OS_MACOSX) || defined(OS_WIN) |
| - context_->file_task_runner()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&HostProcess::ListenForConfigChanges, |
| - base::Unretained(this))); |
| -#endif |
| + StartWatchingConfigChanges(); |
| } |
| void ShutdownHostProcess() { |
| DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| + weak_factory_.InvalidateWeakPtrs(); |
| + |
| +#if !defined(REMOTING_MULTI_PROCESS) |
| + if (config_watcher_.get()) { |
| + DaemonConfigWatcher* config_watcher = config_watcher_.get(); |
| + config_watcher->Stop(config_watcher_.Pass()); |
| + } |
| +#endif // !defined(REMOTING_MULTI_PROCESS) |
| + |
| daemon_channel_.reset(); |
| #if defined(OS_MACOSX) || defined(OS_WIN) |
| @@ -305,19 +294,10 @@ class HostProcess |
| base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this))); |
| } |
| - // Read host config, returning true if successful. |
| - bool LoadConfig() { |
| + // Applies the host config, returning true if successful. |
| + bool ApplyConfig() { |
| DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| - // TODO(sergeyu): There is a potential race condition: this function is |
| - // called on the main thread while the class members it mutates are used on |
| - // the network thread. Fix it. http://crbug.com/140986 . |
| - |
| - if (!config_.Read()) { |
| - LOG(ERROR) << "Failed to read config file."; |
| - return false; |
| - } |
| - |
| if (!config_.GetString(kHostIdConfigPath, &host_id_)) { |
| LOG(ERROR) << "host_id is not defined in the config."; |
| return false; |
| @@ -622,8 +602,11 @@ class HostProcess |
| scoped_ptr<IPC::ChannelProxy> daemon_channel_; |
| scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; |
| + JsonHostConfig config_; |
| +#if !defined(REMOTING_MULTI_PROCESS) |
| FilePath host_config_path_; |
| - CompositeHostConfig config_; |
| + scoped_ptr<DaemonConfigWatcher> config_watcher_; |
| +#endif // !defined(REMOTING_MULTI_PROCESS) |
| std::string host_id_; |
| HostKeyPair key_pair_; |
| @@ -637,8 +620,6 @@ class HostProcess |
| scoped_ptr<policy_hack::PolicyWatcher> policy_watcher_; |
| bool allow_nat_traversal_; |
| - scoped_ptr<base::files::FilePathWatcher> config_watcher_; |
| - scoped_ptr<base::DelayTimer<HostProcess> > config_updated_timer_; |
| bool restarting_; |
| bool shutting_down_; |
| @@ -661,6 +642,9 @@ class HostProcess |
| #if defined(OS_MACOSX) |
| remoting::CurtainMode curtain_; |
| #endif |
| + |
| + // WeakPtr used to avoid tasks accessing |this| after it is deleted. |
| + base::WeakPtrFactory<HostProcess> weak_factory_; |
| }; |
| } // namespace remoting |