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/auth_token_util.h" | 18 #include "remoting/base/auth_token_util.h" | 
| 19 #include "remoting/base/auto_message_loop.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" | 
| 28 #include "remoting/host/pin_hash.h" | 29 #include "remoting/host/pin_hash.h" | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 policy_watcher_->StopWatching(&policy_watcher_stopped_); | 115 policy_watcher_->StopWatching(&policy_watcher_stopped_); | 
| 115 policy_watcher_stopped_.Wait(); | 116 policy_watcher_stopped_.Wait(); | 
| 116 policy_watcher_.reset(); | 117 policy_watcher_.reset(); | 
| 117 } | 118 } | 
| 118 | 119 | 
| 119 if (host_context_.get()) { | 120 if (host_context_.get()) { | 
| 120 // Disconnect synchronously. We cannot disconnect asynchronously | 121 // Disconnect synchronously. We cannot disconnect asynchronously | 
| 121 // here because |host_context_| needs to be stopped on the plugin | 122 // here because |host_context_| needs to be stopped on the plugin | 
| 122 // thread, but the plugin thread may not exist after the instance | 123 // thread, but the plugin thread may not exist after the instance | 
| 123 // is destroyed. | 124 // is destroyed. | 
| 124 disconnected_event_.Reset(); | |
| 125 DisconnectInternal(); | 125 DisconnectInternal(); | 
| 126 disconnected_event_.Wait(); | |
| 127 | 126 | 
| 128 // UI needs to be shut down on the UI thread before we destroy the | 127 // 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 | 128 // host context (because it depends on the context object), but | 
| 130 // only after the host has been shut down (becase the UI object is | 129 // 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 | 130 // registered as status observer for the host, and we can't | 
| 132 // unregister it from this thread). | 131 // unregister it from this thread). | 
| 133 it2me_host_user_interface_.reset(); | 132 it2me_host_user_interface_.reset(); | 
| 134 | 133 | 
| 135 // Stops all threads. | 134 // Stops all threads. | 
| 136 host_context_.reset(); | 135 host_context_.reset(); | 
| 136 | |
| 137 // |disconnected_event_| is signalled when the last reference to the plugin | |
| 138 // thread is dropped. | |
| 139 disconnected_event_.Wait(); | |
| 
 
Wez
2012/08/28 17:34:53
Since is blocked on this event, the plugin thread
 
alexeypa (please no reviews)
2012/08/28 19:18:51
Waiting on the event does more than waiting for th
 
Wez
2012/08/30 18:20:12
As discussed offline, we don't currently have the
 
Wez
2012/08/30 18:25:40
Actually the plugin TaskRunner won't even return f
 
alexeypa (please no reviews)
2012/08/30 22:08:07
I added a comment before "plugin_task_runner_->Det
 
alexeypa (please no reviews)
2012/08/30 22:08:07
PluginThreadTaskRunner returns false during shutdo
 
 | |
| 137 } | 140 } | 
| 138 | 141 | 
| 139 worker_thread_.Stop(); | 142 worker_thread_.Stop(); | 
| 140 } | 143 } | 
| 141 | 144 | 
| 142 bool HostNPScriptObject::Init() { | 145 bool HostNPScriptObject::Init() { | 
| 143 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 146 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 
| 144 VLOG(2) << "Init"; | 147 VLOG(2) << "Init"; | 
| 145 | 148 | 
| 146 host_context_.reset(new ChromotingHostContext(plugin_task_runner_)); | 149 host_context_.reset(new ChromotingHostContext(new AutoMessageLoop( | 
| 150 NULL, plugin_task_runner_, | |
| 151 base::Bind(&base::WaitableEvent::Signal, | |
| 152 base::Unretained(&disconnected_event_))))); | |
| 147 if (!host_context_->Start()) { | 153 if (!host_context_->Start()) { | 
| 148 host_context_.reset(); | 154 host_context_.reset(); | 
| 149 return false; | 155 return false; | 
| 150 } | 156 } | 
| 151 | 157 | 
| 152 policy_watcher_.reset( | 158 policy_watcher_.reset( | 
| 153 policy_hack::PolicyWatcher::Create(host_context_->network_task_runner())); | 159 policy_hack::PolicyWatcher::Create(host_context_->network_task_runner())); | 
| 154 policy_watcher_->StartWatching( | 160 policy_watcher_->StartWatching( | 
| 155 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 161 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 
| 156 base::Unretained(this))); | 162 base::Unretained(this))); | 
| (...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 864 void HostNPScriptObject::DisconnectInternal() { | 870 void HostNPScriptObject::DisconnectInternal() { | 
| 865 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 871 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 
| 866 host_context_->network_task_runner()->PostTask( | 872 host_context_->network_task_runner()->PostTask( | 
| 867 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 873 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 
| 868 base::Unretained(this))); | 874 base::Unretained(this))); | 
| 869 return; | 875 return; | 
| 870 } | 876 } | 
| 871 | 877 | 
| 872 switch (state_) { | 878 switch (state_) { | 
| 873 case kDisconnected: | 879 case kDisconnected: | 
| 874 disconnected_event_.Signal(); | |
| 875 return; | 880 return; | 
| 876 | 881 | 
| 877 case kStarting: | 882 case kStarting: | 
| 883 desktop_environment_.reset(); | |
| 878 SetState(kDisconnecting); | 884 SetState(kDisconnecting); | 
| 879 SetState(kDisconnected); | 885 SetState(kDisconnected); | 
| 880 disconnected_event_.Signal(); | |
| 881 return; | 886 return; | 
| 882 | 887 | 
| 883 case kDisconnecting: | 888 case kDisconnecting: | 
| 884 return; | 889 return; | 
| 885 | 890 | 
| 886 default: | 891 default: | 
| 887 SetState(kDisconnecting); | 892 SetState(kDisconnecting); | 
| 888 | 893 | 
| 889 if (!host_) { | 894 if (!host_) { | 
| 890 OnShutdownFinished(); | 895 OnShutdownFinished(); | 
| 891 return; | 896 return; | 
| 892 } | 897 } | 
| 893 // ChromotingHost::Shutdown() may destroy SignalStrategy | 898 // ChromotingHost::Shutdown() may destroy SignalStrategy | 
| 894 // synchronously, but SignalStrategy::Listener handlers are not | 899 // synchronously, but SignalStrategy::Listener handlers are not | 
| 895 // allowed to destroy SignalStrategy, so post task to call | 900 // allowed to destroy SignalStrategy, so post task to call | 
| 896 // Shutdown() later. | 901 // Shutdown() later. | 
| 897 host_context_->network_task_runner()->PostTask( | 902 host_context_->network_task_runner()->PostTask( | 
| 898 FROM_HERE, base::Bind( | 903 FROM_HERE, base::Bind( | 
| 899 &ChromotingHost::Shutdown, host_, | 904 &ChromotingHost::Shutdown, host_, | 
| 900 base::Bind(&HostNPScriptObject::OnShutdownFinished, | 905 base::Bind(&HostNPScriptObject::OnShutdownFinished, | 
| 901 base::Unretained(this)))); | 906 base::Unretained(this)))); | 
| 902 return; | 907 return; | 
| 903 } | 908 } | 
| 904 } | 909 } | 
| 905 | 910 | 
| 906 void HostNPScriptObject::OnShutdownFinished() { | 911 void HostNPScriptObject::OnShutdownFinished() { | 
| 907 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 912 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 
| 908 | 913 | 
| 909 disconnected_event_.Signal(); | 914 desktop_environment_.reset(); | 
| 
 
Wez
2012/08/28 17:34:53
Is this from a DesktopEnvironment->DesktopEnvironm
 
alexeypa (please no reviews)
2012/08/28 19:18:51
No, it references the main message loop, so it has
 
 | |
| 910 } | 915 } | 
| 911 | 916 | 
| 912 void HostNPScriptObject::OnPolicyUpdate( | 917 void HostNPScriptObject::OnPolicyUpdate( | 
| 913 scoped_ptr<base::DictionaryValue> policies) { | 918 scoped_ptr<base::DictionaryValue> policies) { | 
| 914 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 919 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 
| 915 host_context_->network_task_runner()->PostTask( | 920 host_context_->network_task_runner()->PostTask( | 
| 916 FROM_HERE, | 921 FROM_HERE, | 
| 917 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 922 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 
| 918 base::Unretained(this), base::Passed(&policies))); | 923 base::Unretained(this), base::Passed(&policies))); | 
| 919 return; | 924 return; | 
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1291 return is_good; | 1296 return is_good; | 
| 1292 } | 1297 } | 
| 1293 | 1298 | 
| 1294 void HostNPScriptObject::SetException(const std::string& exception_string) { | 1299 void HostNPScriptObject::SetException(const std::string& exception_string) { | 
| 1295 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 1300 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 
| 1296 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 1301 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 
| 1297 LOG(INFO) << exception_string; | 1302 LOG(INFO) << exception_string; | 
| 1298 } | 1303 } | 
| 1299 | 1304 | 
| 1300 } // namespace remoting | 1305 } // namespace remoting | 
| OLD | NEW |