Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "remoting/host/plugin/host_script_object.h" | 5 #include "remoting/host/plugin/host_script_object.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" | 
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" | 
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" | 
| 11 #include "base/message_loop_proxy.h" | 11 #include "base/message_loop_proxy.h" | 
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" | 
| 13 #include "base/sys_string_conversions.h" | 13 #include "base/sys_string_conversions.h" | 
| 14 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" | 
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" | 
| 16 #include "base/values.h" | 16 #include "base/values.h" | 
| 17 #include "net/base/net_util.h" | 17 #include "net/base/net_util.h" | 
| 18 #include "remoting/base/auto_thread_task_runner.h" | |
| 18 #include "remoting/base/auth_token_util.h" | 19 #include "remoting/base/auth_token_util.h" | 
| 19 #include "remoting/host/chromoting_host.h" | 20 #include "remoting/host/chromoting_host.h" | 
| 20 #include "remoting/host/chromoting_host_context.h" | 21 #include "remoting/host/chromoting_host_context.h" | 
| 21 #include "remoting/host/desktop_environment.h" | 22 #include "remoting/host/desktop_environment.h" | 
| 22 #include "remoting/host/host_config.h" | 23 #include "remoting/host/host_config.h" | 
| 23 #include "remoting/host/host_event_logger.h" | 24 #include "remoting/host/host_event_logger.h" | 
| 24 #include "remoting/host/host_key_pair.h" | 25 #include "remoting/host/host_key_pair.h" | 
| 25 #include "remoting/host/host_secret.h" | 26 #include "remoting/host/host_secret.h" | 
| 26 #include "remoting/host/it2me_host_user_interface.h" | 27 #include "remoting/host/it2me_host_user_interface.h" | 
| 27 #include "remoting/host/network_settings.h" | 28 #include "remoting/host/network_settings.h" | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 daemon_controller_(DaemonController::Create()), | 100 daemon_controller_(DaemonController::Create()), | 
| 100 worker_thread_("RemotingHostPlugin") { | 101 worker_thread_("RemotingHostPlugin") { | 
| 101 worker_thread_.Start(); | 102 worker_thread_.Start(); | 
| 102 } | 103 } | 
| 103 | 104 | 
| 104 HostNPScriptObject::~HostNPScriptObject() { | 105 HostNPScriptObject::~HostNPScriptObject() { | 
| 105 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 106 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 
| 106 | 107 | 
| 107 HostLogHandler::UnregisterLoggingScriptObject(this); | 108 HostLogHandler::UnregisterLoggingScriptObject(this); | 
| 108 | 109 | 
| 110 // Stop the message loop. Any attempt to post a task to | |
| 111 // |context_.ui_task_runner()| will result in a CHECK() after this point. | |
| 112 // TODO(alexeypa): Enable posting messages to |plugin_task_runner_| during | |
| 113 // shutdown to avoid this hack. | |
| 109 plugin_task_runner_->Detach(); | 114 plugin_task_runner_->Detach(); | 
| 110 | 115 | 
| 111 // Stop listening for policy updates. | 116 // Stop listening for policy updates. | 
| 112 if (policy_watcher_.get()) { | 117 if (policy_watcher_.get()) { | 
| 113 base::WaitableEvent policy_watcher_stopped_(true, false); | 118 base::WaitableEvent policy_watcher_stopped_(true, false); | 
| 114 policy_watcher_->StopWatching(&policy_watcher_stopped_); | 119 policy_watcher_->StopWatching(&policy_watcher_stopped_); | 
| 115 policy_watcher_stopped_.Wait(); | 120 policy_watcher_stopped_.Wait(); | 
| 116 policy_watcher_.reset(); | 121 policy_watcher_.reset(); | 
| 117 } | 122 } | 
| 118 | 123 | 
| 119 if (host_context_.get()) { | 124 if (host_context_.get()) { | 
| 120 // Disconnect synchronously. We cannot disconnect asynchronously | 125 // Disconnect synchronously. We cannot disconnect asynchronously | 
| 121 // here because |host_context_| needs to be stopped on the plugin | 126 // here because |host_context_| needs to be stopped on the plugin | 
| 122 // thread, but the plugin thread may not exist after the instance | 127 // thread, but the plugin thread may not exist after the instance | 
| 123 // is destroyed. | 128 // is destroyed. | 
| 124 disconnected_event_.Reset(); | |
| 125 DisconnectInternal(); | 129 DisconnectInternal(); | 
| 126 disconnected_event_.Wait(); | |
| 127 | 130 | 
| 128 // UI needs to be shut down on the UI thread before we destroy the | 131 // UI needs to be shut down on the UI thread before we destroy the | 
| 129 // host context (because it depends on the context object), but | 132 // host context (because it depends on the context object), but | 
| 130 // only after the host has been shut down (becase the UI object is | 133 // only after the host has been shut down (becase the UI object is | 
| 131 // registered as status observer for the host, and we can't | 134 // registered as status observer for the host, and we can't | 
| 132 // unregister it from this thread). | 135 // unregister it from this thread). | 
| 133 it2me_host_user_interface_.reset(); | 136 it2me_host_user_interface_.reset(); | 
| 134 | 137 | 
| 135 // Stops all threads. | 138 host_context_->Stop(); | 
| 
 
Wez
2012/08/30 23:56:43
nit: Add comment "Release the context's TaskRunner
 
alexeypa (please no reviews)
2012/08/31 19:57:36
This is now apparent from the method's name.
 
 | |
| 139 | |
| 140 // |disconnected_event_| is signalled when the last reference to the plugin | |
| 141 // thread is dropped. | |
| 142 disconnected_event_.Wait(); | |
| 143 | |
| 144 // Stop all threads. | |
| 136 host_context_.reset(); | 145 host_context_.reset(); | 
| 137 } | 146 } | 
| 138 | 147 | 
| 139 worker_thread_.Stop(); | 148 worker_thread_.Stop(); | 
| 140 } | 149 } | 
| 141 | 150 | 
| 142 bool HostNPScriptObject::Init() { | 151 bool HostNPScriptObject::Init() { | 
| 143 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 152 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 
| 144 VLOG(2) << "Init"; | 153 VLOG(2) << "Init"; | 
| 145 | 154 | 
| 146 host_context_.reset(new ChromotingHostContext(plugin_task_runner_)); | 155 host_context_.reset(new ChromotingHostContext(new AutoThreadTaskRunner( | 
| 156 plugin_task_runner_, | |
| 157 base::Bind(&base::WaitableEvent::Signal, | |
| 158 base::Unretained(&disconnected_event_))))); | |
| 147 if (!host_context_->Start()) { | 159 if (!host_context_->Start()) { | 
| 148 host_context_.reset(); | 160 host_context_.reset(); | 
| 149 return false; | 161 return false; | 
| 150 } | 162 } | 
| 151 | 163 | 
| 152 policy_watcher_.reset( | 164 policy_watcher_.reset( | 
| 153 policy_hack::PolicyWatcher::Create(host_context_->network_task_runner())); | 165 policy_hack::PolicyWatcher::Create(host_context_->network_task_runner())); | 
| 154 policy_watcher_->StartWatching( | 166 policy_watcher_->StartWatching( | 
| 155 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 167 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 
| 156 base::Unretained(this))); | 168 base::Unretained(this))); | 
| (...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 864 void HostNPScriptObject::DisconnectInternal() { | 876 void HostNPScriptObject::DisconnectInternal() { | 
| 865 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 877 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 
| 866 host_context_->network_task_runner()->PostTask( | 878 host_context_->network_task_runner()->PostTask( | 
| 867 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 879 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 
| 868 base::Unretained(this))); | 880 base::Unretained(this))); | 
| 869 return; | 881 return; | 
| 870 } | 882 } | 
| 871 | 883 | 
| 872 switch (state_) { | 884 switch (state_) { | 
| 873 case kDisconnected: | 885 case kDisconnected: | 
| 874 disconnected_event_.Signal(); | |
| 875 return; | 886 return; | 
| 876 | 887 | 
| 877 case kStarting: | 888 case kStarting: | 
| 889 desktop_environment_.reset(); | |
| 878 SetState(kDisconnecting); | 890 SetState(kDisconnecting); | 
| 879 SetState(kDisconnected); | 891 SetState(kDisconnected); | 
| 880 disconnected_event_.Signal(); | |
| 881 return; | 892 return; | 
| 882 | 893 | 
| 883 case kDisconnecting: | 894 case kDisconnecting: | 
| 884 return; | 895 return; | 
| 885 | 896 | 
| 886 default: | 897 default: | 
| 887 SetState(kDisconnecting); | 898 SetState(kDisconnecting); | 
| 888 | 899 | 
| 889 if (!host_) { | 900 if (!host_) { | 
| 890 OnShutdownFinished(); | 901 OnShutdownFinished(); | 
| 891 return; | 902 return; | 
| 892 } | 903 } | 
| 893 // ChromotingHost::Shutdown() may destroy SignalStrategy | 904 // ChromotingHost::Shutdown() may destroy SignalStrategy | 
| 894 // synchronously, but SignalStrategy::Listener handlers are not | 905 // synchronously, but SignalStrategy::Listener handlers are not | 
| 895 // allowed to destroy SignalStrategy, so post task to call | 906 // allowed to destroy SignalStrategy, so post task to call | 
| 896 // Shutdown() later. | 907 // Shutdown() later. | 
| 897 host_context_->network_task_runner()->PostTask( | 908 host_context_->network_task_runner()->PostTask( | 
| 898 FROM_HERE, base::Bind( | 909 FROM_HERE, base::Bind( | 
| 899 &ChromotingHost::Shutdown, host_, | 910 &ChromotingHost::Shutdown, host_, | 
| 900 base::Bind(&HostNPScriptObject::OnShutdownFinished, | 911 base::Bind(&HostNPScriptObject::OnShutdownFinished, | 
| 901 base::Unretained(this)))); | 912 base::Unretained(this)))); | 
| 902 return; | 913 return; | 
| 903 } | 914 } | 
| 904 } | 915 } | 
| 905 | 916 | 
| 906 void HostNPScriptObject::OnShutdownFinished() { | 917 void HostNPScriptObject::OnShutdownFinished() { | 
| 907 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 918 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 
| 908 | 919 | 
| 909 disconnected_event_.Signal(); | 920 desktop_environment_.reset(); | 
| 910 } | 921 } | 
| 911 | 922 | 
| 912 void HostNPScriptObject::OnPolicyUpdate( | 923 void HostNPScriptObject::OnPolicyUpdate( | 
| 913 scoped_ptr<base::DictionaryValue> policies) { | 924 scoped_ptr<base::DictionaryValue> policies) { | 
| 914 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 925 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 
| 915 host_context_->network_task_runner()->PostTask( | 926 host_context_->network_task_runner()->PostTask( | 
| 916 FROM_HERE, | 927 FROM_HERE, | 
| 917 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 928 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 
| 918 base::Unretained(this), base::Passed(&policies))); | 929 base::Unretained(this), base::Passed(&policies))); | 
| 919 return; | 930 return; | 
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1291 return is_good; | 1302 return is_good; | 
| 1292 } | 1303 } | 
| 1293 | 1304 | 
| 1294 void HostNPScriptObject::SetException(const std::string& exception_string) { | 1305 void HostNPScriptObject::SetException(const std::string& exception_string) { | 
| 1295 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 1306 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 
| 1296 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 1307 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 
| 1297 LOG(INFO) << exception_string; | 1308 LOG(INFO) << exception_string; | 
| 1298 } | 1309 } | 
| 1299 | 1310 | 
| 1300 } // namespace remoting | 1311 } // namespace remoting | 
| OLD | NEW |