| 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 = CallJSFunction(on_state_changed_func_, NULL, 0, NULL); | 467 bool is_good = CallJSFunction(on_state_changed_func_, NULL, 0, NULL); |
| 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 = CallJSFunction(log_debug_info_func_, arg, 1, NULL); | 482 bool is_good = CallJSFunction(log_debug_info_func_, arg, 1, NULL); |
| 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 27 matching lines...) Expand all Loading... |
| 518 task); | 518 task); |
| 519 } | 519 } |
| 520 | 520 |
| 521 void HostNPScriptObject::NPTaskSpringboard(void* task) { | 521 void HostNPScriptObject::NPTaskSpringboard(void* task) { |
| 522 Task* real_task = reinterpret_cast<Task*>(task); | 522 Task* real_task = reinterpret_cast<Task*>(task); |
| 523 real_task->Run(); | 523 real_task->Run(); |
| 524 delete real_task; | 524 delete real_task; |
| 525 } | 525 } |
| 526 | 526 |
| 527 } // namespace remoting | 527 } // namespace remoting |
| OLD | NEW |