| 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/threading/platform_thread.h" | 9 #include "base/threading/platform_thread.h" |
| 10 #include "remoting/base/auth_token_util.h" | 10 #include "remoting/base/auth_token_util.h" |
| 11 #include "remoting/base/util.h" |
| 11 #include "remoting/host/chromoting_host.h" | 12 #include "remoting/host/chromoting_host.h" |
| 12 #include "remoting/host/chromoting_host_context.h" | 13 #include "remoting/host/chromoting_host_context.h" |
| 13 #include "remoting/host/desktop_environment.h" | 14 #include "remoting/host/desktop_environment.h" |
| 14 #include "remoting/host/host_config.h" | 15 #include "remoting/host/host_config.h" |
| 15 #include "remoting/host/host_key_pair.h" | 16 #include "remoting/host/host_key_pair.h" |
| 16 #include "remoting/host/in_memory_host_config.h" | 17 #include "remoting/host/in_memory_host_config.h" |
| 17 #include "remoting/host/plugin/host_plugin_utils.h" | 18 #include "remoting/host/plugin/host_plugin_utils.h" |
| 18 #include "remoting/host/register_support_host_request.h" | 19 #include "remoting/host/register_support_host_request.h" |
| 19 #include "remoting/host/support_access_verifier.h" | 20 #include "remoting/host/support_access_verifier.h" |
| 20 | 21 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; | 60 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; |
| 60 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; | 61 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; |
| 61 const char* kAttrNameConnected = "CONNECTED"; | 62 const char* kAttrNameConnected = "CONNECTED"; |
| 62 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; | 63 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; |
| 63 const char* kAttrNameError = "ERROR"; | 64 const char* kAttrNameError = "ERROR"; |
| 64 | 65 |
| 65 const int kMaxLoginAttempts = 5; | 66 const int kMaxLoginAttempts = 5; |
| 66 | 67 |
| 67 } // namespace | 68 } // namespace |
| 68 | 69 |
| 70 // This flag blocks LOGs to the UI if we're already in the middle of logging |
| 71 // to the UI. This prevents a potential infinite loop if we encounter an error |
| 72 // while sending the log message to the UI. |
| 73 static bool g_logging_to_plugin = false; |
| 74 static HostNPScriptObject* g_logging_scriptable_object = NULL; |
| 75 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; |
| 76 |
| 69 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) | 77 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) |
| 70 : plugin_(plugin), | 78 : plugin_(plugin), |
| 71 parent_(parent), | 79 parent_(parent), |
| 72 state_(kDisconnected), | 80 state_(kDisconnected), |
| 73 log_debug_info_func_(NULL), | 81 log_debug_info_func_(NULL), |
| 74 on_state_changed_func_(NULL), | 82 on_state_changed_func_(NULL), |
| 75 np_thread_id_(base::PlatformThread::CurrentId()), | 83 np_thread_id_(base::PlatformThread::CurrentId()), |
| 76 failed_login_attempts_(0), | 84 failed_login_attempts_(0), |
| 77 disconnected_event_(true, false) { | 85 disconnected_event_(true, false) { |
| 78 logger_.reset(new HostPluginLogger(this)); | 86 // Set up log message handler. |
| 79 logger_->VLog(2, "HostNPScriptObject"); | 87 // Note that this approach doesn't quite support having multiple instances |
| 88 // of Chromoting running. In that case, the most recently opened tab will |
| 89 // grab all the debug log messages, and when any Chromoting tab is closed |
| 90 // the logging handler will go away. |
| 91 // Since having multiple Chromoting tabs is not a primary use case, and this |
| 92 // is just debug logging, we're punting improving debug log support for that |
| 93 // case. |
| 94 if (g_logging_old_handler == NULL) |
| 95 g_logging_old_handler = logging::GetLogMessageHandler(); |
| 96 logging::SetLogMessageHandler(&LogToUI); |
| 97 g_logging_scriptable_object = this; |
| 98 |
| 99 VLOG(2) << "HostNPScriptObject"; |
| 80 host_context_.SetUITaskPostFunction(base::Bind( | 100 host_context_.SetUITaskPostFunction(base::Bind( |
| 81 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); | 101 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); |
| 82 } | 102 } |
| 83 | 103 |
| 84 HostNPScriptObject::~HostNPScriptObject() { | 104 HostNPScriptObject::~HostNPScriptObject() { |
| 85 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 105 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 86 | 106 |
| 87 // Shutdown DesktopEnvironment first so that it doesn't try to post | 107 // Shutdown DesktopEnvironment first so that it doesn't try to post |
| 88 // tasks on the UI thread while we are stopping the host. | 108 // tasks on the UI thread while we are stopping the host. |
| 89 desktop_environment_->Shutdown(); | 109 desktop_environment_->Shutdown(); |
| 90 | 110 |
| 111 logging::SetLogMessageHandler(g_logging_old_handler); |
| 112 g_logging_old_handler = NULL; |
| 113 g_logging_scriptable_object = NULL; |
| 114 |
| 91 // Disconnect synchronously. We cannot disconnect asynchronously | 115 // Disconnect synchronously. We cannot disconnect asynchronously |
| 92 // here because |host_context_| needs to be stopped on the plugin | 116 // here because |host_context_| needs to be stopped on the plugin |
| 93 // thread, but the plugin thread may not exist after the instance | 117 // thread, but the plugin thread may not exist after the instance |
| 94 // is destroyed. | 118 // is destroyed. |
| 95 destructing_.Set(); | 119 destructing_.Set(); |
| 96 disconnected_event_.Reset(); | 120 disconnected_event_.Reset(); |
| 97 DisconnectInternal(); | 121 DisconnectInternal(); |
| 98 disconnected_event_.Wait(); | 122 disconnected_event_.Wait(); |
| 99 | 123 |
| 100 // Stop all threads. | 124 // Stop all threads. |
| 101 host_context_.Stop(); | 125 host_context_.Stop(); |
| 102 | 126 |
| 103 if (log_debug_info_func_) { | 127 if (log_debug_info_func_) { |
| 104 g_npnetscape_funcs->releaseobject(log_debug_info_func_); | 128 g_npnetscape_funcs->releaseobject(log_debug_info_func_); |
| 105 } | 129 } |
| 106 if (on_state_changed_func_) { | 130 if (on_state_changed_func_) { |
| 107 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | 131 g_npnetscape_funcs->releaseobject(on_state_changed_func_); |
| 108 } | 132 } |
| 109 } | 133 } |
| 110 | 134 |
| 111 bool HostNPScriptObject::Init() { | 135 bool HostNPScriptObject::Init() { |
| 112 logger_->VLog(2, "Init"); | 136 VLOG(2) << "Init"; |
| 113 // TODO(wez): This starts a bunch of threads, which might fail. | 137 // TODO(wez): This starts a bunch of threads, which might fail. |
| 114 host_context_.Start(); | 138 host_context_.Start(); |
| 115 return true; | 139 return true; |
| 116 } | 140 } |
| 117 | 141 |
| 118 bool HostNPScriptObject::HasMethod(const std::string& method_name) { | 142 bool HostNPScriptObject::HasMethod(const std::string& method_name) { |
| 119 logger_->VLog(2, "HasMethod %s", method_name.c_str()); | 143 VLOG(2) << "HasMethod " << method_name; |
| 120 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 144 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 121 return (method_name == kFuncNameConnect || | 145 return (method_name == kFuncNameConnect || |
| 122 method_name == kFuncNameDisconnect); | 146 method_name == kFuncNameDisconnect); |
| 123 } | 147 } |
| 124 | 148 |
| 125 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, | 149 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, |
| 126 uint32_t argCount, | 150 uint32_t argCount, |
| 127 NPVariant* result) { | 151 NPVariant* result) { |
| 128 logger_->VLog(2, "InvokeDefault"); | 152 VLOG(2) << "InvokeDefault"; |
| 129 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 153 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 130 SetException("exception during default invocation"); | 154 SetException("exception during default invocation"); |
| 131 return false; | 155 return false; |
| 132 } | 156 } |
| 133 | 157 |
| 134 bool HostNPScriptObject::Invoke(const std::string& method_name, | 158 bool HostNPScriptObject::Invoke(const std::string& method_name, |
| 135 const NPVariant* args, | 159 const NPVariant* args, |
| 136 uint32_t argCount, | 160 uint32_t argCount, |
| 137 NPVariant* result) { | 161 NPVariant* result) { |
| 138 logger_->VLog(2, "Invoke %s", method_name.c_str()); | 162 VLOG(2) << "Invoke " << method_name; |
| 139 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 163 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 140 if (method_name == kFuncNameConnect) { | 164 if (method_name == kFuncNameConnect) { |
| 141 return Connect(args, argCount, result); | 165 return Connect(args, argCount, result); |
| 142 } else if (method_name == kFuncNameDisconnect) { | 166 } else if (method_name == kFuncNameDisconnect) { |
| 143 return Disconnect(args, argCount, result); | 167 return Disconnect(args, argCount, result); |
| 144 } else { | 168 } else { |
| 145 SetException("Invoke: unknown method " + method_name); | 169 SetException("Invoke: unknown method " + method_name); |
| 146 return false; | 170 return false; |
| 147 } | 171 } |
| 148 } | 172 } |
| 149 | 173 |
| 150 bool HostNPScriptObject::HasProperty(const std::string& property_name) { | 174 bool HostNPScriptObject::HasProperty(const std::string& property_name) { |
| 151 logger_->VLog(2, "HasProperty %s", property_name.c_str()); | 175 VLOG(2) << "HasProperty " << property_name; |
| 152 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 176 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 153 return (property_name == kAttrNameAccessCode || | 177 return (property_name == kAttrNameAccessCode || |
| 154 property_name == kAttrNameAccessCodeLifetime || | 178 property_name == kAttrNameAccessCodeLifetime || |
| 155 property_name == kAttrNameClient || | 179 property_name == kAttrNameClient || |
| 156 property_name == kAttrNameState || | 180 property_name == kAttrNameState || |
| 157 property_name == kAttrNameLogDebugInfo || | 181 property_name == kAttrNameLogDebugInfo || |
| 158 property_name == kAttrNameOnStateChanged || | 182 property_name == kAttrNameOnStateChanged || |
| 159 property_name == kAttrNameDisconnected || | 183 property_name == kAttrNameDisconnected || |
| 160 property_name == kAttrNameRequestedAccessCode || | 184 property_name == kAttrNameRequestedAccessCode || |
| 161 property_name == kAttrNameReceivedAccessCode || | 185 property_name == kAttrNameReceivedAccessCode || |
| 162 property_name == kAttrNameConnected || | 186 property_name == kAttrNameConnected || |
| 163 property_name == kAttrNameAffirmingConnection || | 187 property_name == kAttrNameAffirmingConnection || |
| 164 property_name == kAttrNameError); | 188 property_name == kAttrNameError); |
| 165 } | 189 } |
| 166 | 190 |
| 167 bool HostNPScriptObject::GetProperty(const std::string& property_name, | 191 bool HostNPScriptObject::GetProperty(const std::string& property_name, |
| 168 NPVariant* result) { | 192 NPVariant* result) { |
| 169 logger_->VLog(2, "GetProperty %s", property_name.c_str()); | 193 VLOG(2) << "GetProperty " << property_name; |
| 170 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 194 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 171 if (!result) { | 195 if (!result) { |
| 172 SetException("GetProperty: NULL result"); | 196 SetException("GetProperty: NULL result"); |
| 173 return false; | 197 return false; |
| 174 } | 198 } |
| 175 | 199 |
| 176 if (property_name == kAttrNameOnStateChanged) { | 200 if (property_name == kAttrNameOnStateChanged) { |
| 177 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result); | 201 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result); |
| 178 return true; | 202 return true; |
| 179 } else if (property_name == kAttrNameLogDebugInfo) { | 203 } else if (property_name == kAttrNameLogDebugInfo) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 210 INT32_TO_NPVARIANT(kError, *result); | 234 INT32_TO_NPVARIANT(kError, *result); |
| 211 return true; | 235 return true; |
| 212 } else { | 236 } else { |
| 213 SetException("GetProperty: unsupported property " + property_name); | 237 SetException("GetProperty: unsupported property " + property_name); |
| 214 return false; | 238 return false; |
| 215 } | 239 } |
| 216 } | 240 } |
| 217 | 241 |
| 218 bool HostNPScriptObject::SetProperty(const std::string& property_name, | 242 bool HostNPScriptObject::SetProperty(const std::string& property_name, |
| 219 const NPVariant* value) { | 243 const NPVariant* value) { |
| 220 logger_->VLog(2, "SetProperty %s", property_name.c_str()); | 244 VLOG(2) << "SetProperty " << property_name; |
| 221 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 245 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 222 | 246 |
| 223 if (property_name == kAttrNameOnStateChanged) { | 247 if (property_name == kAttrNameOnStateChanged) { |
| 224 if (NPVARIANT_IS_OBJECT(*value)) { | 248 if (NPVARIANT_IS_OBJECT(*value)) { |
| 225 if (on_state_changed_func_) { | 249 if (on_state_changed_func_) { |
| 226 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | 250 g_npnetscape_funcs->releaseobject(on_state_changed_func_); |
| 227 } | 251 } |
| 228 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); | 252 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); |
| 229 if (on_state_changed_func_) { | 253 if (on_state_changed_func_) { |
| 230 g_npnetscape_funcs->retainobject(on_state_changed_func_); | 254 g_npnetscape_funcs->retainobject(on_state_changed_func_); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 251 SetException("SetProperty: unexpected type for property " + | 275 SetException("SetProperty: unexpected type for property " + |
| 252 property_name); | 276 property_name); |
| 253 } | 277 } |
| 254 return false; | 278 return false; |
| 255 } | 279 } |
| 256 | 280 |
| 257 return false; | 281 return false; |
| 258 } | 282 } |
| 259 | 283 |
| 260 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { | 284 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { |
| 261 logger_->VLog(2, "RemoveProperty %s", property_name.c_str()); | 285 VLOG(2) << "RemoveProperty " << property_name; |
| 262 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 286 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 263 return false; | 287 return false; |
| 264 } | 288 } |
| 265 | 289 |
| 266 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { | 290 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { |
| 267 logger_->VLog(2, "Enumerate"); | 291 VLOG(2) << "Enumerate"; |
| 268 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 292 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 269 const char* entries[] = { | 293 const char* entries[] = { |
| 270 kAttrNameAccessCode, | 294 kAttrNameAccessCode, |
| 271 kAttrNameState, | 295 kAttrNameState, |
| 272 kAttrNameLogDebugInfo, | 296 kAttrNameLogDebugInfo, |
| 273 kAttrNameOnStateChanged, | 297 kAttrNameOnStateChanged, |
| 274 kFuncNameConnect, | 298 kFuncNameConnect, |
| 275 kFuncNameDisconnect, | 299 kFuncNameDisconnect, |
| 276 kAttrNameDisconnected, | 300 kAttrNameDisconnected, |
| 277 kAttrNameRequestedAccessCode, | 301 kAttrNameRequestedAccessCode, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 | 347 |
| 324 OnStateChanged(kDisconnected); | 348 OnStateChanged(kDisconnected); |
| 325 } | 349 } |
| 326 | 350 |
| 327 // string uid, string auth_token | 351 // string uid, string auth_token |
| 328 bool HostNPScriptObject::Connect(const NPVariant* args, | 352 bool HostNPScriptObject::Connect(const NPVariant* args, |
| 329 uint32_t arg_count, | 353 uint32_t arg_count, |
| 330 NPVariant* result) { | 354 NPVariant* result) { |
| 331 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 355 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 332 | 356 |
| 333 LogDebugInfo("Connecting..."); | 357 LOG(INFO) << "Connecting..."; |
| 334 | 358 |
| 335 if (arg_count != 2) { | 359 if (arg_count != 2) { |
| 336 SetException("connect: bad number of arguments"); | 360 SetException("connect: bad number of arguments"); |
| 337 return false; | 361 return false; |
| 338 } | 362 } |
| 339 | 363 |
| 340 std::string uid = StringFromNPVariant(args[0]); | 364 std::string uid = StringFromNPVariant(args[0]); |
| 341 if (uid.empty()) { | 365 if (uid.empty()) { |
| 342 SetException("connect: bad uid argument"); | 366 SetException("connect: bad uid argument"); |
| 343 return false; | 367 return false; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 host_config_ = host_config; | 425 host_config_ = host_config; |
| 402 register_request_.reset(register_request.release()); | 426 register_request_.reset(register_request.release()); |
| 403 | 427 |
| 404 // Create DesktopEnvironment. | 428 // Create DesktopEnvironment. |
| 405 desktop_environment_.reset(DesktopEnvironment::Create(&host_context_)); | 429 desktop_environment_.reset(DesktopEnvironment::Create(&host_context_)); |
| 406 | 430 |
| 407 // Create the Host. | 431 // Create the Host. |
| 408 // TODO(sergeyu): Use firewall traversal policy settings here. | 432 // TODO(sergeyu): Use firewall traversal policy settings here. |
| 409 host_ = ChromotingHost::Create( | 433 host_ = ChromotingHost::Create( |
| 410 &host_context_, host_config_, desktop_environment_.get(), | 434 &host_context_, host_config_, desktop_environment_.get(), |
| 411 access_verifier.release(), logger_.get(), false); | 435 access_verifier.release(), false); |
| 412 host_->AddStatusObserver(this); | 436 host_->AddStatusObserver(this); |
| 413 host_->AddStatusObserver(register_request_.get()); | 437 host_->AddStatusObserver(register_request_.get()); |
| 414 host_->set_it2me(true); | 438 host_->set_it2me(true); |
| 415 | 439 |
| 416 // Start the Host. | 440 // Start the Host. |
| 417 host_->Start(); | 441 host_->Start(); |
| 418 | 442 |
| 419 OnStateChanged(kRequestedAccessCode); | 443 OnStateChanged(kRequestedAccessCode); |
| 420 return; | 444 return; |
| 421 } | 445 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 return; | 517 return; |
| 494 | 518 |
| 495 if (!host_context_.IsUIThread()) { | 519 if (!host_context_.IsUIThread()) { |
| 496 host_context_.PostTaskToUIThread( | 520 host_context_.PostTaskToUIThread( |
| 497 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, | 521 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, |
| 498 base::Unretained(this), state)); | 522 base::Unretained(this), state)); |
| 499 return; | 523 return; |
| 500 } | 524 } |
| 501 state_ = state; | 525 state_ = state; |
| 502 if (on_state_changed_func_) { | 526 if (on_state_changed_func_) { |
| 503 logger_->VLog(2, "Calling state changed %s", state); | 527 VLOG(2) << "Calling state changed " << state; |
| 504 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); | 528 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); |
| 505 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; | 529 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; |
| 506 } | 530 } |
| 507 } | 531 } |
| 508 | 532 |
| 533 // static |
| 534 bool HostNPScriptObject::LogToUI(int severity, const char* file, int line, |
| 535 size_t message_start, |
| 536 const std::string& str) { |
| 537 // The |g_logging_to_plugin| check is to prevent logging to the scriptable |
| 538 // object if we're already in the middle of logging. |
| 539 // This can occur if we try to log an error while we're in the scriptable |
| 540 // object logging code. |
| 541 if (g_logging_scriptable_object && !g_logging_to_plugin) { |
| 542 g_logging_to_plugin = true; |
| 543 std::string message = remoting::GetTimestampString(); |
| 544 message += (str.c_str() + message_start); |
| 545 g_logging_scriptable_object->LogDebugInfo(message); |
| 546 g_logging_to_plugin = false; |
| 547 } |
| 548 if (g_logging_old_handler) |
| 549 return (g_logging_old_handler)(severity, file, line, message_start, str); |
| 550 return false; |
| 551 } |
| 552 |
| 509 void HostNPScriptObject::LogDebugInfo(const std::string& message) { | 553 void HostNPScriptObject::LogDebugInfo(const std::string& message) { |
| 510 if (destructing_.IsSet()) | 554 if (destructing_.IsSet()) |
| 511 return; | 555 return; |
| 512 | 556 |
| 513 if (!host_context_.IsUIThread()) { | 557 if (!host_context_.IsUIThread()) { |
| 514 host_context_.PostTaskToUIThread( | 558 host_context_.PostTaskToUIThread( |
| 515 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, | 559 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, |
| 516 base::Unretained(this), message)); | 560 base::Unretained(this), message)); |
| 517 return; | 561 return; |
| 518 } | 562 } |
| 563 |
| 519 if (log_debug_info_func_) { | 564 if (log_debug_info_func_) { |
| 520 NPVariant* arg = new NPVariant(); | 565 NPVariant* arg = new NPVariant(); |
| 521 STRINGZ_TO_NPVARIANT(message.c_str(), *arg); | 566 STRINGZ_TO_NPVARIANT(message.c_str(), *arg); |
| 522 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, arg, 1); | 567 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, arg, 1); |
| 523 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; | 568 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; |
| 524 } | 569 } |
| 525 } | 570 } |
| 526 | 571 |
| 527 void HostNPScriptObject::SetException(const std::string& exception_string) { | 572 void HostNPScriptObject::SetException(const std::string& exception_string) { |
| 528 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 573 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 529 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 574 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); |
| 530 LogDebugInfo(exception_string); | 575 LOG(INFO) << exception_string; |
| 531 } | 576 } |
| 532 | 577 |
| 533 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, | 578 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, |
| 534 const NPVariant* args, | 579 const NPVariant* args, |
| 535 uint32_t argCount) { | 580 uint32_t argCount) { |
| 536 NPVariant np_result; | 581 NPVariant np_result; |
| 537 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, | 582 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, |
| 538 argCount, &np_result); | 583 argCount, &np_result); |
| 539 if (is_good) | 584 if (is_good) |
| 540 g_npnetscape_funcs->releasevariantvalue(&np_result); | 585 g_npnetscape_funcs->releasevariantvalue(&np_result); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 556 } | 601 } |
| 557 | 602 |
| 558 // static | 603 // static |
| 559 void HostNPScriptObject::NPTaskSpringboard(void* task) { | 604 void HostNPScriptObject::NPTaskSpringboard(void* task) { |
| 560 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); | 605 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); |
| 561 real_task->Run(); | 606 real_task->Run(); |
| 562 delete real_task; | 607 delete real_task; |
| 563 } | 608 } |
| 564 | 609 |
| 565 } // namespace remoting | 610 } // namespace remoting |
| OLD | NEW |