OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/task.h" | 9 #include "base/task.h" |
10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 | 64 |
65 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) | 65 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) |
66 : plugin_(plugin), | 66 : plugin_(plugin), |
67 parent_(parent), | 67 parent_(parent), |
68 state_(kDisconnected), | 68 state_(kDisconnected), |
69 log_debug_info_func_(NULL), | 69 log_debug_info_func_(NULL), |
70 on_state_changed_func_(NULL), | 70 on_state_changed_func_(NULL), |
71 np_thread_id_(base::PlatformThread::CurrentId()), | 71 np_thread_id_(base::PlatformThread::CurrentId()), |
72 failed_login_attempts_(0), | 72 failed_login_attempts_(0), |
73 disconnected_event_(true, false) { | 73 disconnected_event_(true, false) { |
74 VLOG(2) << "HostNPScriptObject"; | 74 logger_.reset(new HostPluginLogger(this)); |
| 75 logger_->VLog(2, "HostNPScriptObject"); |
75 host_context_.SetUITaskPostFunction(base::Bind( | 76 host_context_.SetUITaskPostFunction(base::Bind( |
76 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); | 77 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); |
77 } | 78 } |
78 | 79 |
79 HostNPScriptObject::~HostNPScriptObject() { | 80 HostNPScriptObject::~HostNPScriptObject() { |
80 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 81 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
81 | 82 |
82 // Disconnect synchronously. We cannot disconnect asynchronously | 83 // Disconnect synchronously. We cannot disconnect asynchronously |
83 // here because |host_context_| needs to be stopped on the plugin | 84 // here because |host_context_| needs to be stopped on the plugin |
84 // thread, but the plugin thread may not exist after the instance | 85 // thread, but the plugin thread may not exist after the instance |
85 // is destroyed. | 86 // is destroyed. |
86 destructing_.Set(); | 87 destructing_.Set(); |
87 disconnected_event_.Reset(); | 88 disconnected_event_.Reset(); |
88 DisconnectInternal(); | 89 DisconnectInternal(); |
89 disconnected_event_.Wait(); | 90 disconnected_event_.Wait(); |
90 | 91 |
91 host_context_.Stop(); | 92 host_context_.Stop(); |
92 if (log_debug_info_func_) { | 93 if (log_debug_info_func_) { |
93 g_npnetscape_funcs->releaseobject(log_debug_info_func_); | 94 g_npnetscape_funcs->releaseobject(log_debug_info_func_); |
94 } | 95 } |
95 if (on_state_changed_func_) { | 96 if (on_state_changed_func_) { |
96 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | 97 g_npnetscape_funcs->releaseobject(on_state_changed_func_); |
97 } | 98 } |
98 } | 99 } |
99 | 100 |
100 bool HostNPScriptObject::Init() { | 101 bool HostNPScriptObject::Init() { |
101 VLOG(2) << "Init"; | 102 logger_->VLog(2, "Init"); |
102 // TODO(wez): This starts a bunch of threads, which might fail. | 103 // TODO(wez): This starts a bunch of threads, which might fail. |
103 host_context_.Start(); | 104 host_context_.Start(); |
104 return true; | 105 return true; |
105 } | 106 } |
106 | 107 |
107 bool HostNPScriptObject::HasMethod(const std::string& method_name) { | 108 bool HostNPScriptObject::HasMethod(const std::string& method_name) { |
108 VLOG(2) << "HasMethod " << method_name; | 109 logger_->VLog(2, "HasMethod %s", method_name.c_str()); |
109 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 110 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
110 return (method_name == kFuncNameConnect || | 111 return (method_name == kFuncNameConnect || |
111 method_name == kFuncNameDisconnect); | 112 method_name == kFuncNameDisconnect); |
112 } | 113 } |
113 | 114 |
114 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, | 115 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, |
115 uint32_t argCount, | 116 uint32_t argCount, |
116 NPVariant* result) { | 117 NPVariant* result) { |
117 VLOG(2) << "InvokeDefault"; | 118 logger_->VLog(2, "InvokeDefault"); |
118 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 119 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
119 SetException("exception during default invocation"); | 120 SetException("exception during default invocation"); |
120 return false; | 121 return false; |
121 } | 122 } |
122 | 123 |
123 bool HostNPScriptObject::Invoke(const std::string& method_name, | 124 bool HostNPScriptObject::Invoke(const std::string& method_name, |
124 const NPVariant* args, | 125 const NPVariant* args, |
125 uint32_t argCount, | 126 uint32_t argCount, |
126 NPVariant* result) { | 127 NPVariant* result) { |
127 VLOG(2) << "Invoke " << method_name; | 128 logger_->VLog(2, "Invoke %s", method_name.c_str()); |
128 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 129 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
129 if (method_name == kFuncNameConnect) { | 130 if (method_name == kFuncNameConnect) { |
130 return Connect(args, argCount, result); | 131 return Connect(args, argCount, result); |
131 } else if (method_name == kFuncNameDisconnect) { | 132 } else if (method_name == kFuncNameDisconnect) { |
132 return Disconnect(args, argCount, result); | 133 return Disconnect(args, argCount, result); |
133 } else { | 134 } else { |
134 SetException("Invoke: unknown method " + method_name); | 135 SetException("Invoke: unknown method " + method_name); |
135 return false; | 136 return false; |
136 } | 137 } |
137 } | 138 } |
138 | 139 |
139 bool HostNPScriptObject::HasProperty(const std::string& property_name) { | 140 bool HostNPScriptObject::HasProperty(const std::string& property_name) { |
140 VLOG(2) << "HasProperty " << property_name; | 141 logger_->VLog(2, "HasProperty %s", property_name.c_str()); |
141 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 142 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
142 return (property_name == kAttrNameAccessCode || | 143 return (property_name == kAttrNameAccessCode || |
143 property_name == kAttrNameState || | 144 property_name == kAttrNameState || |
144 property_name == kAttrNameLogDebugInfo || | 145 property_name == kAttrNameLogDebugInfo || |
145 property_name == kAttrNameOnStateChanged || | 146 property_name == kAttrNameOnStateChanged || |
146 property_name == kAttrNameDisconnected || | 147 property_name == kAttrNameDisconnected || |
147 property_name == kAttrNameRequestedAccessCode || | 148 property_name == kAttrNameRequestedAccessCode || |
148 property_name == kAttrNameReceivedAccessCode || | 149 property_name == kAttrNameReceivedAccessCode || |
149 property_name == kAttrNameConnected || | 150 property_name == kAttrNameConnected || |
150 property_name == kAttrNameAffirmingConnection || | 151 property_name == kAttrNameAffirmingConnection || |
151 property_name == kAttrNameError); | 152 property_name == kAttrNameError); |
152 } | 153 } |
153 | 154 |
154 bool HostNPScriptObject::GetProperty(const std::string& property_name, | 155 bool HostNPScriptObject::GetProperty(const std::string& property_name, |
155 NPVariant* result) { | 156 NPVariant* result) { |
156 VLOG(2) << "GetProperty " << property_name; | 157 logger_->VLog(2, "GetProperty %s", property_name.c_str()); |
157 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 158 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
158 if (!result) { | 159 if (!result) { |
159 SetException("GetProperty: NULL result"); | 160 SetException("GetProperty: NULL result"); |
160 return false; | 161 return false; |
161 } | 162 } |
162 | 163 |
163 if (property_name == kAttrNameOnStateChanged) { | 164 if (property_name == kAttrNameOnStateChanged) { |
164 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result); | 165 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result); |
165 return true; | 166 return true; |
166 } else if (property_name == kAttrNameLogDebugInfo) { | 167 } else if (property_name == kAttrNameLogDebugInfo) { |
(...skipping 24 matching lines...) Expand all Loading... |
191 INT32_TO_NPVARIANT(kError, *result); | 192 INT32_TO_NPVARIANT(kError, *result); |
192 return true; | 193 return true; |
193 } else { | 194 } else { |
194 SetException("GetProperty: unsupported property " + property_name); | 195 SetException("GetProperty: unsupported property " + property_name); |
195 return false; | 196 return false; |
196 } | 197 } |
197 } | 198 } |
198 | 199 |
199 bool HostNPScriptObject::SetProperty(const std::string& property_name, | 200 bool HostNPScriptObject::SetProperty(const std::string& property_name, |
200 const NPVariant* value) { | 201 const NPVariant* value) { |
201 VLOG(2) << "SetProperty " << property_name; | 202 logger_->VLog(2, "SetProperty %s", property_name.c_str()); |
202 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 203 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
203 | 204 |
204 if (property_name == kAttrNameOnStateChanged) { | 205 if (property_name == kAttrNameOnStateChanged) { |
205 if (NPVARIANT_IS_OBJECT(*value)) { | 206 if (NPVARIANT_IS_OBJECT(*value)) { |
206 if (on_state_changed_func_) { | 207 if (on_state_changed_func_) { |
207 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | 208 g_npnetscape_funcs->releaseobject(on_state_changed_func_); |
208 } | 209 } |
209 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); | 210 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); |
210 if (on_state_changed_func_) { | 211 if (on_state_changed_func_) { |
211 g_npnetscape_funcs->retainobject(on_state_changed_func_); | 212 g_npnetscape_funcs->retainobject(on_state_changed_func_); |
(...skipping 20 matching lines...) Expand all Loading... |
232 SetException("SetProperty: unexpected type for property " + | 233 SetException("SetProperty: unexpected type for property " + |
233 property_name); | 234 property_name); |
234 } | 235 } |
235 return false; | 236 return false; |
236 } | 237 } |
237 | 238 |
238 return false; | 239 return false; |
239 } | 240 } |
240 | 241 |
241 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { | 242 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { |
242 VLOG(2) << "RemoveProperty " << property_name; | 243 logger_->VLog(2, "RemoveProperty %s", property_name.c_str()); |
243 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 244 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
244 return false; | 245 return false; |
245 } | 246 } |
246 | 247 |
247 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { | 248 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { |
248 VLOG(2) << "Enumerate"; | 249 logger_->VLog(2, "Enumerate"); |
249 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 250 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
250 const char* entries[] = { | 251 const char* entries[] = { |
251 kAttrNameAccessCode, | 252 kAttrNameAccessCode, |
252 kAttrNameState, | 253 kAttrNameState, |
253 kAttrNameLogDebugInfo, | 254 kAttrNameLogDebugInfo, |
254 kAttrNameOnStateChanged, | 255 kAttrNameOnStateChanged, |
255 kFuncNameConnect, | 256 kFuncNameConnect, |
256 kFuncNameDisconnect, | 257 kFuncNameDisconnect, |
257 kAttrNameDisconnected, | 258 kAttrNameDisconnected, |
258 kAttrNameRequestedAccessCode, | 259 kAttrNameRequestedAccessCode, |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 base::Bind(&HostNPScriptObject::OnReceivedSupportID, | 363 base::Bind(&HostNPScriptObject::OnReceivedSupportID, |
363 base::Unretained(this), | 364 base::Unretained(this), |
364 access_verifier.get()))) { | 365 access_verifier.get()))) { |
365 OnStateChanged(kDisconnected); | 366 OnStateChanged(kDisconnected); |
366 return; | 367 return; |
367 } | 368 } |
368 | 369 |
369 // Create the Host. | 370 // Create the Host. |
370 scoped_refptr<ChromotingHost> host = | 371 scoped_refptr<ChromotingHost> host = |
371 ChromotingHost::Create(&host_context_, host_config, | 372 ChromotingHost::Create(&host_context_, host_config, |
372 access_verifier.release()); | 373 access_verifier.release(), logger_.get()); |
373 host->AddStatusObserver(this); | 374 host->AddStatusObserver(this); |
374 host->AddStatusObserver(register_request.get()); | 375 host->AddStatusObserver(register_request.get()); |
375 host->set_it2me(true); | 376 host->set_it2me(true); |
376 | 377 |
377 // Nothing went wrong, so lets save the host, config and request. | 378 // Nothing went wrong, so lets save the host, config and request. |
378 host_ = host; | 379 host_ = host; |
379 host_config_ = host_config; | 380 host_config_ = host_config; |
380 register_request_.reset(register_request.release()); | 381 register_request_.reset(register_request.release()); |
381 | 382 |
382 // Start the Host. | 383 // Start the Host. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 } | 456 } |
456 | 457 |
457 if (!host_context_.IsUIThread()) { | 458 if (!host_context_.IsUIThread()) { |
458 host_context_.PostToUIThread( | 459 host_context_.PostToUIThread( |
459 FROM_HERE, | 460 FROM_HERE, |
460 NewRunnableMethod(this, &HostNPScriptObject::OnStateChanged, state)); | 461 NewRunnableMethod(this, &HostNPScriptObject::OnStateChanged, state)); |
461 return; | 462 return; |
462 } | 463 } |
463 state_ = state; | 464 state_ = state; |
464 if (on_state_changed_func_) { | 465 if (on_state_changed_func_) { |
465 VLOG(2) << "Calling state changed " << state; | 466 logger_->VLog(2, "Calling state changed %s", state); |
466 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); | 467 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); |
467 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; | 468 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; |
468 } | 469 } |
469 } | 470 } |
470 | 471 |
471 void HostNPScriptObject::LogDebugInfo(const std::string& message) { | 472 void HostNPScriptObject::LogDebugInfo(const std::string& message) { |
472 if (!host_context_.IsUIThread()) { | 473 if (!host_context_.IsUIThread()) { |
473 host_context_.PostToUIThread( | 474 host_context_.PostToUIThread( |
474 FROM_HERE, | 475 FROM_HERE, |
475 NewRunnableMethod(this, &HostNPScriptObject::LogDebugInfo, message)); | 476 NewRunnableMethod(this, &HostNPScriptObject::LogDebugInfo, message)); |
476 return; | 477 return; |
477 } | 478 } |
478 if (log_debug_info_func_) { | 479 if (log_debug_info_func_) { |
479 NPVariant* arg = new NPVariant(); | 480 NPVariant* arg = new NPVariant(); |
480 LOG(INFO) << "Logging: " << message; | |
481 STRINGZ_TO_NPVARIANT(message.c_str(), *arg); | 481 STRINGZ_TO_NPVARIANT(message.c_str(), *arg); |
482 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, arg, 1); | 482 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, arg, 1); |
483 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; | 483 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; |
484 } | 484 } |
485 } | 485 } |
486 | 486 |
487 void HostNPScriptObject::SetException(const std::string& exception_string) { | 487 void HostNPScriptObject::SetException(const std::string& exception_string) { |
488 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 488 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
489 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 489 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); |
490 LogDebugInfo(exception_string); | 490 LogDebugInfo(exception_string); |
(...skipping 22 matching lines...) Expand all Loading... |
513 task); | 513 task); |
514 } | 514 } |
515 | 515 |
516 void HostNPScriptObject::NPTaskSpringboard(void* task) { | 516 void HostNPScriptObject::NPTaskSpringboard(void* task) { |
517 Task* real_task = reinterpret_cast<Task*>(task); | 517 Task* real_task = reinterpret_cast<Task*>(task); |
518 real_task->Run(); | 518 real_task->Run(); |
519 delete real_task; | 519 delete real_task; |
520 } | 520 } |
521 | 521 |
522 } // namespace remoting | 522 } // namespace remoting |
OLD | NEW |