| 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 // Release the context's TaskRunner references for the threads, so they can |
| 139 // exit when no objects need them. |
| 140 host_context_->ReleaseTaskRunners(); |
| 141 |
| 142 // |disconnected_event_| is signalled when the last reference to the plugin |
| 143 // thread is dropped. |
| 144 disconnected_event_.Wait(); |
| 145 |
| 146 // Stop all threads. |
| 136 host_context_.reset(); | 147 host_context_.reset(); |
| 137 } | 148 } |
| 138 | 149 |
| 139 worker_thread_.Stop(); | 150 worker_thread_.Stop(); |
| 140 } | 151 } |
| 141 | 152 |
| 142 bool HostNPScriptObject::Init() { | 153 bool HostNPScriptObject::Init() { |
| 143 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 154 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); |
| 144 VLOG(2) << "Init"; | 155 VLOG(2) << "Init"; |
| 145 | 156 |
| 146 host_context_.reset(new ChromotingHostContext(plugin_task_runner_)); | 157 host_context_.reset(new ChromotingHostContext(new AutoThreadTaskRunner( |
| 158 plugin_task_runner_, |
| 159 base::Bind(&base::WaitableEvent::Signal, |
| 160 base::Unretained(&disconnected_event_))))); |
| 147 if (!host_context_->Start()) { | 161 if (!host_context_->Start()) { |
| 148 host_context_.reset(); | 162 host_context_.reset(); |
| 149 return false; | 163 return false; |
| 150 } | 164 } |
| 151 | 165 |
| 152 policy_watcher_.reset( | 166 policy_watcher_.reset( |
| 153 policy_hack::PolicyWatcher::Create(host_context_->network_task_runner())); | 167 policy_hack::PolicyWatcher::Create(host_context_->network_task_runner())); |
| 154 policy_watcher_->StartWatching( | 168 policy_watcher_->StartWatching( |
| 155 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 169 base::Bind(&HostNPScriptObject::OnPolicyUpdate, |
| 156 base::Unretained(this))); | 170 base::Unretained(this))); |
| (...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 void HostNPScriptObject::DisconnectInternal() { | 878 void HostNPScriptObject::DisconnectInternal() { |
| 865 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 879 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { |
| 866 host_context_->network_task_runner()->PostTask( | 880 host_context_->network_task_runner()->PostTask( |
| 867 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 881 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, |
| 868 base::Unretained(this))); | 882 base::Unretained(this))); |
| 869 return; | 883 return; |
| 870 } | 884 } |
| 871 | 885 |
| 872 switch (state_) { | 886 switch (state_) { |
| 873 case kDisconnected: | 887 case kDisconnected: |
| 874 disconnected_event_.Signal(); | |
| 875 return; | 888 return; |
| 876 | 889 |
| 877 case kStarting: | 890 case kStarting: |
| 891 desktop_environment_.reset(); |
| 878 SetState(kDisconnecting); | 892 SetState(kDisconnecting); |
| 879 SetState(kDisconnected); | 893 SetState(kDisconnected); |
| 880 disconnected_event_.Signal(); | |
| 881 return; | 894 return; |
| 882 | 895 |
| 883 case kDisconnecting: | 896 case kDisconnecting: |
| 884 return; | 897 return; |
| 885 | 898 |
| 886 default: | 899 default: |
| 887 SetState(kDisconnecting); | 900 SetState(kDisconnecting); |
| 888 | 901 |
| 889 if (!host_) { | 902 if (!host_) { |
| 890 OnShutdownFinished(); | 903 OnShutdownFinished(); |
| 891 return; | 904 return; |
| 892 } | 905 } |
| 893 // ChromotingHost::Shutdown() may destroy SignalStrategy | 906 // ChromotingHost::Shutdown() may destroy SignalStrategy |
| 894 // synchronously, but SignalStrategy::Listener handlers are not | 907 // synchronously, but SignalStrategy::Listener handlers are not |
| 895 // allowed to destroy SignalStrategy, so post task to call | 908 // allowed to destroy SignalStrategy, so post task to call |
| 896 // Shutdown() later. | 909 // Shutdown() later. |
| 897 host_context_->network_task_runner()->PostTask( | 910 host_context_->network_task_runner()->PostTask( |
| 898 FROM_HERE, base::Bind( | 911 FROM_HERE, base::Bind( |
| 899 &ChromotingHost::Shutdown, host_, | 912 &ChromotingHost::Shutdown, host_, |
| 900 base::Bind(&HostNPScriptObject::OnShutdownFinished, | 913 base::Bind(&HostNPScriptObject::OnShutdownFinished, |
| 901 base::Unretained(this)))); | 914 base::Unretained(this)))); |
| 902 return; | 915 return; |
| 903 } | 916 } |
| 904 } | 917 } |
| 905 | 918 |
| 906 void HostNPScriptObject::OnShutdownFinished() { | 919 void HostNPScriptObject::OnShutdownFinished() { |
| 907 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 920 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 908 | 921 |
| 909 disconnected_event_.Signal(); | 922 desktop_environment_.reset(); |
| 910 } | 923 } |
| 911 | 924 |
| 912 void HostNPScriptObject::OnPolicyUpdate( | 925 void HostNPScriptObject::OnPolicyUpdate( |
| 913 scoped_ptr<base::DictionaryValue> policies) { | 926 scoped_ptr<base::DictionaryValue> policies) { |
| 914 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 927 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { |
| 915 host_context_->network_task_runner()->PostTask( | 928 host_context_->network_task_runner()->PostTask( |
| 916 FROM_HERE, | 929 FROM_HERE, |
| 917 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 930 base::Bind(&HostNPScriptObject::OnPolicyUpdate, |
| 918 base::Unretained(this), base::Passed(&policies))); | 931 base::Unretained(this), base::Passed(&policies))); |
| 919 return; | 932 return; |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 return is_good; | 1304 return is_good; |
| 1292 } | 1305 } |
| 1293 | 1306 |
| 1294 void HostNPScriptObject::SetException(const std::string& exception_string) { | 1307 void HostNPScriptObject::SetException(const std::string& exception_string) { |
| 1295 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 1308 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); |
| 1296 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 1309 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); |
| 1297 LOG(INFO) << exception_string; | 1310 LOG(INFO) << exception_string; |
| 1298 } | 1311 } |
| 1299 | 1312 |
| 1300 } // namespace remoting | 1313 } // namespace remoting |
| OLD | NEW |