| 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 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 void HostNPScriptObject::DisconnectInternal() { | 885 void HostNPScriptObject::DisconnectInternal() { |
| 872 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 886 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { |
| 873 host_context_->network_task_runner()->PostTask( | 887 host_context_->network_task_runner()->PostTask( |
| 874 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 888 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, |
| 875 base::Unretained(this))); | 889 base::Unretained(this))); |
| 876 return; | 890 return; |
| 877 } | 891 } |
| 878 | 892 |
| 879 switch (state_) { | 893 switch (state_) { |
| 880 case kDisconnected: | 894 case kDisconnected: |
| 881 disconnected_event_.Signal(); | |
| 882 return; | 895 return; |
| 883 | 896 |
| 884 case kStarting: | 897 case kStarting: |
| 898 desktop_environment_.reset(); |
| 885 SetState(kDisconnecting); | 899 SetState(kDisconnecting); |
| 886 SetState(kDisconnected); | 900 SetState(kDisconnected); |
| 887 disconnected_event_.Signal(); | |
| 888 return; | 901 return; |
| 889 | 902 |
| 890 case kDisconnecting: | 903 case kDisconnecting: |
| 891 return; | 904 return; |
| 892 | 905 |
| 893 default: | 906 default: |
| 894 SetState(kDisconnecting); | 907 SetState(kDisconnecting); |
| 895 | 908 |
| 896 if (!host_) { | 909 if (!host_) { |
| 897 OnShutdownFinished(); | 910 OnShutdownFinished(); |
| 898 return; | 911 return; |
| 899 } | 912 } |
| 900 // ChromotingHost::Shutdown() may destroy SignalStrategy | 913 // ChromotingHost::Shutdown() may destroy SignalStrategy |
| 901 // synchronously, but SignalStrategy::Listener handlers are not | 914 // synchronously, but SignalStrategy::Listener handlers are not |
| 902 // allowed to destroy SignalStrategy, so post task to call | 915 // allowed to destroy SignalStrategy, so post task to call |
| 903 // Shutdown() later. | 916 // Shutdown() later. |
| 904 host_context_->network_task_runner()->PostTask( | 917 host_context_->network_task_runner()->PostTask( |
| 905 FROM_HERE, base::Bind( | 918 FROM_HERE, base::Bind( |
| 906 &ChromotingHost::Shutdown, host_, | 919 &ChromotingHost::Shutdown, host_, |
| 907 base::Bind(&HostNPScriptObject::OnShutdownFinished, | 920 base::Bind(&HostNPScriptObject::OnShutdownFinished, |
| 908 base::Unretained(this)))); | 921 base::Unretained(this)))); |
| 909 return; | 922 return; |
| 910 } | 923 } |
| 911 } | 924 } |
| 912 | 925 |
| 913 void HostNPScriptObject::OnShutdownFinished() { | 926 void HostNPScriptObject::OnShutdownFinished() { |
| 914 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); | 927 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); |
| 915 | 928 |
| 916 disconnected_event_.Signal(); | 929 desktop_environment_.reset(); |
| 917 } | 930 } |
| 918 | 931 |
| 919 void HostNPScriptObject::OnPolicyUpdate( | 932 void HostNPScriptObject::OnPolicyUpdate( |
| 920 scoped_ptr<base::DictionaryValue> policies) { | 933 scoped_ptr<base::DictionaryValue> policies) { |
| 921 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { | 934 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { |
| 922 host_context_->network_task_runner()->PostTask( | 935 host_context_->network_task_runner()->PostTask( |
| 923 FROM_HERE, | 936 FROM_HERE, |
| 924 base::Bind(&HostNPScriptObject::OnPolicyUpdate, | 937 base::Bind(&HostNPScriptObject::OnPolicyUpdate, |
| 925 base::Unretained(this), base::Passed(&policies))); | 938 base::Unretained(this), base::Passed(&policies))); |
| 926 return; | 939 return; |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1298 return is_good; | 1311 return is_good; |
| 1299 } | 1312 } |
| 1300 | 1313 |
| 1301 void HostNPScriptObject::SetException(const std::string& exception_string) { | 1314 void HostNPScriptObject::SetException(const std::string& exception_string) { |
| 1302 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 1315 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); |
| 1303 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 1316 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); |
| 1304 LOG(INFO) << exception_string; | 1317 LOG(INFO) << exception_string; |
| 1305 } | 1318 } |
| 1306 | 1319 |
| 1307 } // namespace remoting | 1320 } // namespace remoting |
| OLD | NEW |