| 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/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
| 10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
| 11 #include "remoting/base/auth_token_util.h" | 11 #include "remoting/base/auth_token_util.h" |
| 12 #include "remoting/base/util.h" | 12 #include "remoting/base/util.h" |
| 13 #include "remoting/host/chromoting_host.h" | 13 #include "remoting/host/chromoting_host.h" |
| 14 #include "remoting/host/chromoting_host_context.h" | 14 #include "remoting/host/chromoting_host_context.h" |
| 15 #include "remoting/host/desktop_environment.h" | 15 #include "remoting/host/desktop_environment.h" |
| 16 #include "remoting/host/host_config.h" | 16 #include "remoting/host/host_config.h" |
| 17 #include "remoting/host/host_key_pair.h" | 17 #include "remoting/host/host_key_pair.h" |
| 18 #include "remoting/host/in_memory_host_config.h" | 18 #include "remoting/host/in_memory_host_config.h" |
| 19 #include "remoting/host/plugin/host_plugin_utils.h" | |
| 20 #include "remoting/host/plugin/policy_hack/nat_policy.h" | 19 #include "remoting/host/plugin/policy_hack/nat_policy.h" |
| 21 #include "remoting/host/register_support_host_request.h" | 20 #include "remoting/host/register_support_host_request.h" |
| 22 #include "remoting/host/support_access_verifier.h" | 21 #include "remoting/host/support_access_verifier.h" |
| 22 #include "remoting/host/ui_strings.h" |
| 23 | 23 |
| 24 namespace remoting { | 24 namespace remoting { |
| 25 | 25 |
| 26 // Supported Javascript interface: | 26 // Supported Javascript interface: |
| 27 // readonly attribute string accessCode; | 27 // readonly attribute string accessCode; |
| 28 // readonly attribute int accessCodeLifetime; | 28 // readonly attribute int accessCodeLifetime; |
| 29 // readonly attribute string client; | 29 // readonly attribute string client; |
| 30 // readonly attribute int state; | 30 // readonly attribute int state; |
| 31 // | 31 // |
| 32 // state: { | 32 // state: { |
| 33 // DISCONNECTED, | 33 // DISCONNECTED, |
| 34 // REQUESTED_ACCESS_CODE, | 34 // REQUESTED_ACCESS_CODE, |
| 35 // RECEIVED_ACCESS_CODE, | 35 // RECEIVED_ACCESS_CODE, |
| 36 // CONNECTED, | 36 // CONNECTED, |
| 37 // AFFIRMING_CONNECTION, | 37 // AFFIRMING_CONNECTION, |
| 38 // ERROR, | 38 // ERROR, |
| 39 // } | 39 // } |
| 40 // | 40 // |
| 41 // attribute Function void logDebugInfo(string); | 41 // attribute Function void logDebugInfo(string); |
| 42 // attribute Function void onStateChanged(); | 42 // attribute Function void onStateChanged(); |
| 43 // attribute Function string localizeString(string,...); |
| 43 // | 44 // |
| 44 // // The |auth_service_with_token| parameter should be in the format | 45 // // The |auth_service_with_token| parameter should be in the format |
| 45 // // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". | 46 // // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". |
| 46 // void connect(string uid, string auth_service_with_token); | 47 // void connect(string uid, string auth_service_with_token); |
| 47 // void disconnect(); | 48 // void disconnect(); |
| 48 | 49 |
| 49 namespace { | 50 namespace { |
| 50 | 51 |
| 51 const char* kAttrNameAccessCode = "accessCode"; | 52 const char* kAttrNameAccessCode = "accessCode"; |
| 52 const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime"; | 53 const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime"; |
| 53 const char* kAttrNameClient = "client"; | 54 const char* kAttrNameClient = "client"; |
| 54 const char* kAttrNameState = "state"; | 55 const char* kAttrNameState = "state"; |
| 56 const char* kAttrNameLocalizeString = "localizeString"; |
| 55 const char* kAttrNameLogDebugInfo = "logDebugInfo"; | 57 const char* kAttrNameLogDebugInfo = "logDebugInfo"; |
| 56 const char* kAttrNameOnStateChanged = "onStateChanged"; | 58 const char* kAttrNameOnStateChanged = "onStateChanged"; |
| 57 const char* kFuncNameConnect = "connect"; | 59 const char* kFuncNameConnect = "connect"; |
| 58 const char* kFuncNameDisconnect = "disconnect"; | 60 const char* kFuncNameDisconnect = "disconnect"; |
| 59 | 61 |
| 60 // States. | 62 // States. |
| 61 const char* kAttrNameDisconnected = "DISCONNECTED"; | 63 const char* kAttrNameDisconnected = "DISCONNECTED"; |
| 62 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; | 64 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; |
| 63 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; | 65 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; |
| 64 const char* kAttrNameConnected = "CONNECTED"; | 66 const char* kAttrNameConnected = "CONNECTED"; |
| 65 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; | 67 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; |
| 66 const char* kAttrNameError = "ERROR"; | 68 const char* kAttrNameError = "ERROR"; |
| 67 | 69 |
| 68 const int kMaxLoginAttempts = 5; | 70 const int kMaxLoginAttempts = 5; |
| 69 | 71 |
| 70 } // namespace | 72 } // namespace |
| 71 | 73 |
| 72 // This flag blocks LOGs to the UI if we're already in the middle of logging | 74 // This flag blocks LOGs to the UI if we're already in the middle of logging |
| 73 // to the UI. This prevents a potential infinite loop if we encounter an error | 75 // to the UI. This prevents a potential infinite loop if we encounter an error |
| 74 // while sending the log message to the UI. | 76 // while sending the log message to the UI. |
| 75 static bool g_logging_to_plugin = false; | 77 static bool g_logging_to_plugin = false; |
| 76 static HostNPScriptObject* g_logging_scriptable_object = NULL; | 78 static HostNPScriptObject* g_logging_scriptable_object = NULL; |
| 77 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; | 79 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; |
| 78 | 80 |
| 79 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) | 81 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) |
| 80 : plugin_(plugin), | 82 : plugin_(plugin), |
| 81 parent_(parent), | 83 parent_(parent), |
| 82 state_(kDisconnected), | 84 state_(kDisconnected), |
| 83 log_debug_info_func_(NULL), | |
| 84 on_state_changed_func_(NULL), | |
| 85 np_thread_id_(base::PlatformThread::CurrentId()), | 85 np_thread_id_(base::PlatformThread::CurrentId()), |
| 86 failed_login_attempts_(0), | 86 failed_login_attempts_(0), |
| 87 disconnected_event_(true, false), | 87 disconnected_event_(true, false), |
| 88 nat_traversal_enabled_(false), | 88 nat_traversal_enabled_(false), |
| 89 policy_received_(false) { | 89 policy_received_(false) { |
| 90 // Set up log message handler. | 90 // Set up log message handler. |
| 91 // Note that this approach doesn't quite support having multiple instances | 91 // Note that this approach doesn't quite support having multiple instances |
| 92 // of Chromoting running. In that case, the most recently opened tab will | 92 // of Chromoting running. In that case, the most recently opened tab will |
| 93 // grab all the debug log messages, and when any Chromoting tab is closed | 93 // grab all the debug log messages, and when any Chromoting tab is closed |
| 94 // the logging handler will go away. | 94 // the logging handler will go away. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 // here because |host_context_| needs to be stopped on the plugin | 128 // here because |host_context_| needs to be stopped on the plugin |
| 129 // thread, but the plugin thread may not exist after the instance | 129 // thread, but the plugin thread may not exist after the instance |
| 130 // is destroyed. | 130 // is destroyed. |
| 131 destructing_.Set(); | 131 destructing_.Set(); |
| 132 disconnected_event_.Reset(); | 132 disconnected_event_.Reset(); |
| 133 DisconnectInternal(); | 133 DisconnectInternal(); |
| 134 disconnected_event_.Wait(); | 134 disconnected_event_.Wait(); |
| 135 | 135 |
| 136 // Stop all threads. | 136 // Stop all threads. |
| 137 host_context_.Stop(); | 137 host_context_.Stop(); |
| 138 | |
| 139 if (log_debug_info_func_) { | |
| 140 g_npnetscape_funcs->releaseobject(log_debug_info_func_); | |
| 141 } | |
| 142 if (on_state_changed_func_) { | |
| 143 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | |
| 144 } | |
| 145 } | 138 } |
| 146 | 139 |
| 147 bool HostNPScriptObject::Init() { | 140 bool HostNPScriptObject::Init() { |
| 148 VLOG(2) << "Init"; | 141 VLOG(2) << "Init"; |
| 149 // TODO(wez): This starts a bunch of threads, which might fail. | 142 // TODO(wez): This starts a bunch of threads, which might fail. |
| 150 host_context_.Start(); | 143 host_context_.Start(); |
| 151 nat_policy_.reset( | 144 nat_policy_.reset( |
| 152 policy_hack::NatPolicy::Create(host_context_.network_message_loop())); | 145 policy_hack::NatPolicy::Create(host_context_.network_message_loop())); |
| 153 nat_policy_->StartWatching( | 146 nat_policy_->StartWatching( |
| 154 base::Bind(&HostNPScriptObject::OnNatPolicyUpdate, | 147 base::Bind(&HostNPScriptObject::OnNatPolicyUpdate, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 } | 181 } |
| 189 } | 182 } |
| 190 | 183 |
| 191 bool HostNPScriptObject::HasProperty(const std::string& property_name) { | 184 bool HostNPScriptObject::HasProperty(const std::string& property_name) { |
| 192 VLOG(2) << "HasProperty " << property_name; | 185 VLOG(2) << "HasProperty " << property_name; |
| 193 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 186 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 194 return (property_name == kAttrNameAccessCode || | 187 return (property_name == kAttrNameAccessCode || |
| 195 property_name == kAttrNameAccessCodeLifetime || | 188 property_name == kAttrNameAccessCodeLifetime || |
| 196 property_name == kAttrNameClient || | 189 property_name == kAttrNameClient || |
| 197 property_name == kAttrNameState || | 190 property_name == kAttrNameState || |
| 191 property_name == kAttrNameLocalizeString || |
| 198 property_name == kAttrNameLogDebugInfo || | 192 property_name == kAttrNameLogDebugInfo || |
| 199 property_name == kAttrNameOnStateChanged || | 193 property_name == kAttrNameOnStateChanged || |
| 200 property_name == kAttrNameDisconnected || | 194 property_name == kAttrNameDisconnected || |
| 201 property_name == kAttrNameRequestedAccessCode || | 195 property_name == kAttrNameRequestedAccessCode || |
| 202 property_name == kAttrNameReceivedAccessCode || | 196 property_name == kAttrNameReceivedAccessCode || |
| 203 property_name == kAttrNameConnected || | 197 property_name == kAttrNameConnected || |
| 204 property_name == kAttrNameAffirmingConnection || | 198 property_name == kAttrNameAffirmingConnection || |
| 205 property_name == kAttrNameError); | 199 property_name == kAttrNameError); |
| 206 } | 200 } |
| 207 | 201 |
| 208 bool HostNPScriptObject::GetProperty(const std::string& property_name, | 202 bool HostNPScriptObject::GetProperty(const std::string& property_name, |
| 209 NPVariant* result) { | 203 NPVariant* result) { |
| 210 VLOG(2) << "GetProperty " << property_name; | 204 VLOG(2) << "GetProperty " << property_name; |
| 211 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 205 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 212 if (!result) { | 206 if (!result) { |
| 213 SetException("GetProperty: NULL result"); | 207 SetException("GetProperty: NULL result"); |
| 214 return false; | 208 return false; |
| 215 } | 209 } |
| 216 | 210 |
| 217 if (property_name == kAttrNameOnStateChanged) { | 211 if (property_name == kAttrNameOnStateChanged) { |
| 218 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result); | 212 OBJECT_TO_NPVARIANT(on_state_changed_func_.get(), *result); |
| 213 return true; |
| 214 } else if (property_name == kAttrNameLocalizeString) { |
| 215 OBJECT_TO_NPVARIANT(localize_func_.get(), *result); |
| 219 return true; | 216 return true; |
| 220 } else if (property_name == kAttrNameLogDebugInfo) { | 217 } else if (property_name == kAttrNameLogDebugInfo) { |
| 221 OBJECT_TO_NPVARIANT(log_debug_info_func_, *result); | 218 OBJECT_TO_NPVARIANT(log_debug_info_func_.get(), *result); |
| 222 return true; | 219 return true; |
| 223 } else if (property_name == kAttrNameState) { | 220 } else if (property_name == kAttrNameState) { |
| 224 INT32_TO_NPVARIANT(state_, *result); | 221 INT32_TO_NPVARIANT(state_, *result); |
| 225 return true; | 222 return true; |
| 226 } else if (property_name == kAttrNameAccessCode) { | 223 } else if (property_name == kAttrNameAccessCode) { |
| 227 *result = NPVariantFromString(access_code_); | 224 *result = NPVariantFromString(access_code_); |
| 228 return true; | 225 return true; |
| 229 } else if (property_name == kAttrNameAccessCodeLifetime) { | 226 } else if (property_name == kAttrNameAccessCodeLifetime) { |
| 230 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); | 227 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); |
| 231 return true; | 228 return true; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 256 } | 253 } |
| 257 } | 254 } |
| 258 | 255 |
| 259 bool HostNPScriptObject::SetProperty(const std::string& property_name, | 256 bool HostNPScriptObject::SetProperty(const std::string& property_name, |
| 260 const NPVariant* value) { | 257 const NPVariant* value) { |
| 261 VLOG(2) << "SetProperty " << property_name; | 258 VLOG(2) << "SetProperty " << property_name; |
| 262 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 259 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 263 | 260 |
| 264 if (property_name == kAttrNameOnStateChanged) { | 261 if (property_name == kAttrNameOnStateChanged) { |
| 265 if (NPVARIANT_IS_OBJECT(*value)) { | 262 if (NPVARIANT_IS_OBJECT(*value)) { |
| 266 if (on_state_changed_func_) { | |
| 267 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | |
| 268 } | |
| 269 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); | 263 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); |
| 270 if (on_state_changed_func_) { | |
| 271 g_npnetscape_funcs->retainobject(on_state_changed_func_); | |
| 272 } | |
| 273 return true; | 264 return true; |
| 274 } else { | 265 } else { |
| 275 SetException("SetProperty: unexpected type for property " + | 266 SetException("SetProperty: unexpected type for property " + |
| 267 property_name); |
| 268 } |
| 269 return false; |
| 270 } |
| 271 |
| 272 if (property_name == kAttrNameLocalizeString) { |
| 273 if (NPVARIANT_IS_OBJECT(*value)) { |
| 274 localize_func_ = NPVARIANT_TO_OBJECT(*value); |
| 275 return true; |
| 276 } else { |
| 277 SetException("SetProperty: unexpected type for property " + |
| 276 property_name); | 278 property_name); |
| 277 } | 279 } |
| 278 return false; | 280 return false; |
| 279 } | 281 } |
| 280 | 282 |
| 281 if (property_name == kAttrNameLogDebugInfo) { | 283 if (property_name == kAttrNameLogDebugInfo) { |
| 282 if (NPVARIANT_IS_OBJECT(*value)) { | 284 if (NPVARIANT_IS_OBJECT(*value)) { |
| 283 if (log_debug_info_func_) { | |
| 284 g_npnetscape_funcs->releaseobject(log_debug_info_func_); | |
| 285 } | |
| 286 log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value); | 285 log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value); |
| 287 if (log_debug_info_func_) { | |
| 288 g_npnetscape_funcs->retainobject(log_debug_info_func_); | |
| 289 } | |
| 290 return true; | 286 return true; |
| 291 } else { | 287 } else { |
| 292 SetException("SetProperty: unexpected type for property " + | 288 SetException("SetProperty: unexpected type for property " + |
| 293 property_name); | 289 property_name); |
| 294 } | 290 } |
| 295 return false; | 291 return false; |
| 296 } | 292 } |
| 297 | 293 |
| 298 return false; | 294 return false; |
| 299 } | 295 } |
| 300 | 296 |
| 301 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { | 297 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { |
| 302 VLOG(2) << "RemoveProperty " << property_name; | 298 VLOG(2) << "RemoveProperty " << property_name; |
| 303 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 299 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 304 return false; | 300 return false; |
| 305 } | 301 } |
| 306 | 302 |
| 307 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { | 303 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { |
| 308 VLOG(2) << "Enumerate"; | 304 VLOG(2) << "Enumerate"; |
| 309 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 305 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 310 const char* entries[] = { | 306 const char* entries[] = { |
| 311 kAttrNameAccessCode, | 307 kAttrNameAccessCode, |
| 312 kAttrNameState, | 308 kAttrNameState, |
| 309 kAttrNameLocalizeString, |
| 313 kAttrNameLogDebugInfo, | 310 kAttrNameLogDebugInfo, |
| 314 kAttrNameOnStateChanged, | 311 kAttrNameOnStateChanged, |
| 315 kFuncNameConnect, | 312 kFuncNameConnect, |
| 316 kFuncNameDisconnect, | 313 kFuncNameDisconnect, |
| 317 kAttrNameDisconnected, | 314 kAttrNameDisconnected, |
| 318 kAttrNameRequestedAccessCode, | 315 kAttrNameRequestedAccessCode, |
| 319 kAttrNameReceivedAccessCode, | 316 kAttrNameReceivedAccessCode, |
| 320 kAttrNameConnected, | 317 kAttrNameConnected, |
| 321 kAttrNameAffirmingConnection, | 318 kAttrNameAffirmingConnection, |
| 322 kAttrNameError | 319 kAttrNameError |
| (...skipping 20 matching lines...) Expand all Loading... |
| 343 } | 340 } |
| 344 | 341 |
| 345 void HostNPScriptObject::OnClientAuthenticated( | 342 void HostNPScriptObject::OnClientAuthenticated( |
| 346 remoting::protocol::ConnectionToClient* client) { | 343 remoting::protocol::ConnectionToClient* client) { |
| 347 DCHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_); | 344 DCHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_); |
| 348 client_username_ = client->session()->jid(); | 345 client_username_ = client->session()->jid(); |
| 349 size_t pos = client_username_.find('/'); | 346 size_t pos = client_username_.find('/'); |
| 350 if (pos != std::string::npos) | 347 if (pos != std::string::npos) |
| 351 client_username_.replace(pos, std::string::npos, ""); | 348 client_username_.replace(pos, std::string::npos, ""); |
| 352 LOG(INFO) << "Client " << client_username_ << " connected."; | 349 LOG(INFO) << "Client " << client_username_ << " connected."; |
| 350 LocalizeStrings(); |
| 353 OnStateChanged(kConnected); | 351 OnStateChanged(kConnected); |
| 354 } | 352 } |
| 355 | 353 |
| 356 void HostNPScriptObject::OnClientDisconnected( | 354 void HostNPScriptObject::OnClientDisconnected( |
| 357 remoting::protocol::ConnectionToClient* client) { | 355 remoting::protocol::ConnectionToClient* client) { |
| 358 client_username_.clear(); | 356 client_username_.clear(); |
| 359 OnStateChanged(kDisconnected); | 357 OnStateChanged(kDisconnected); |
| 360 } | 358 } |
| 361 | 359 |
| 362 void HostNPScriptObject::OnShutdown() { | 360 void HostNPScriptObject::OnShutdown() { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 if (destructing_.IsSet()) | 580 if (destructing_.IsSet()) |
| 583 return; | 581 return; |
| 584 | 582 |
| 585 if (!host_context_.IsUIThread()) { | 583 if (!host_context_.IsUIThread()) { |
| 586 host_context_.PostTaskToUIThread( | 584 host_context_.PostTaskToUIThread( |
| 587 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, | 585 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, |
| 588 base::Unretained(this), state)); | 586 base::Unretained(this), state)); |
| 589 return; | 587 return; |
| 590 } | 588 } |
| 591 state_ = state; | 589 state_ = state; |
| 592 if (on_state_changed_func_) { | 590 if (on_state_changed_func_.get()) { |
| 593 VLOG(2) << "Calling state changed " << state; | 591 VLOG(2) << "Calling state changed " << state; |
| 594 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); | 592 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_.get(), NULL, 0); |
| 595 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; | 593 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; |
| 596 } | 594 } |
| 597 } | 595 } |
| 598 | 596 |
| 599 // static | 597 // static |
| 600 bool HostNPScriptObject::LogToUI(int severity, const char* file, int line, | 598 bool HostNPScriptObject::LogToUI(int severity, const char* file, int line, |
| 601 size_t message_start, | 599 size_t message_start, |
| 602 const std::string& str) { | 600 const std::string& str) { |
| 603 // The |g_logging_to_plugin| check is to prevent logging to the scriptable | 601 // The |g_logging_to_plugin| check is to prevent logging to the scriptable |
| 604 // object if we're already in the middle of logging. | 602 // object if we're already in the middle of logging. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 620 if (destructing_.IsSet()) | 618 if (destructing_.IsSet()) |
| 621 return; | 619 return; |
| 622 | 620 |
| 623 if (!host_context_.IsUIThread()) { | 621 if (!host_context_.IsUIThread()) { |
| 624 host_context_.PostTaskToUIThread( | 622 host_context_.PostTaskToUIThread( |
| 625 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, | 623 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, |
| 626 base::Unretained(this), message)); | 624 base::Unretained(this), message)); |
| 627 return; | 625 return; |
| 628 } | 626 } |
| 629 | 627 |
| 630 if (log_debug_info_func_) { | 628 if (log_debug_info_func_.get()) { |
| 631 NPVariant log_message; | 629 NPVariant log_message; |
| 632 STRINGZ_TO_NPVARIANT(message.c_str(), log_message); | 630 STRINGZ_TO_NPVARIANT(message.c_str(), log_message); |
| 633 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, | 631 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_.get(), |
| 634 &log_message, 1); | 632 &log_message, 1); |
| 635 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; | 633 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; |
| 636 } | 634 } |
| 637 } | 635 } |
| 638 | 636 |
| 639 void HostNPScriptObject::SetException(const std::string& exception_string) { | 637 void HostNPScriptObject::SetException(const std::string& exception_string) { |
| 640 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 638 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 641 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 639 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); |
| 642 LOG(INFO) << exception_string; | 640 LOG(INFO) << exception_string; |
| 643 } | 641 } |
| 644 | 642 |
| 643 void HostNPScriptObject::LocalizeStrings() { |
| 644 UiStrings* ui_strings = host_->ui_strings(); |
| 645 std::string direction; |
| 646 LocalizeString("@@bidi_dir", NULL, &direction); |
| 647 ui_strings->direction = |
| 648 direction == "rtl" ? remoting::UiStrings::RTL |
| 649 : remoting::UiStrings::LTR; |
| 650 LocalizeString("productName", NULL, &ui_strings->product_name); |
| 651 LocalizeString("disconnectButton", NULL, &ui_strings->disconnect_button_text); |
| 652 LocalizeString( |
| 653 #if defined(OS_WIN) |
| 654 "disconnectButtonPlusShortcutWindows", |
| 655 #elif defined(OS_MAC) |
| 656 "disconnectButtonPlusShortcutMacOSX", |
| 657 #else |
| 658 "disconnectButtonPlusShortcutLinux", |
| 659 #endif |
| 660 NULL, &ui_strings->disconnect_button_text_plus_shortcut); |
| 661 LocalizeString("continuePrompt", NULL, &ui_strings->continue_prompt); |
| 662 LocalizeString("continueButton", NULL, &ui_strings->continue_button_text); |
| 663 LocalizeString("stopSharingButton", NULL, |
| 664 &ui_strings->stop_sharing_button_text); |
| 665 LocalizeString("messageShared", client_username_.c_str(), |
| 666 &ui_strings->disconnect_message); |
| 667 } |
| 668 |
| 669 bool HostNPScriptObject::LocalizeString(const char* tag, |
| 670 const char* substitution, |
| 671 std::string* result) { |
| 672 NPVariant args[2]; |
| 673 STRINGZ_TO_NPVARIANT(tag, args[0]); |
| 674 int arg_count = 1; |
| 675 if (substitution) { |
| 676 STRINGZ_TO_NPVARIANT(substitution, args[1]); |
| 677 ++arg_count; |
| 678 } |
| 679 NPVariant np_result; |
| 680 bool is_good = g_npnetscape_funcs->invokeDefault( |
| 681 plugin_, localize_func_.get(), &args[0], arg_count, &np_result); |
| 682 if (!is_good) { |
| 683 LOG(ERROR) << "Localization failed for " << tag; |
| 684 return false; |
| 685 } |
| 686 std::string translation = StringFromNPVariant(np_result); |
| 687 g_npnetscape_funcs->releasevariantvalue(&np_result); |
| 688 if (translation.empty()) { |
| 689 LOG(ERROR) << "Missing translation for " << tag; |
| 690 return false; |
| 691 } |
| 692 *result = translation; |
| 693 return true; |
| 694 } |
| 695 |
| 645 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, | 696 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, |
| 646 const NPVariant* args, | 697 const NPVariant* args, |
| 647 uint32_t argCount) { | 698 uint32_t argCount) { |
| 648 NPVariant np_result; | 699 NPVariant np_result; |
| 649 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, | 700 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, |
| 650 argCount, &np_result); | 701 argCount, &np_result); |
| 651 if (is_good) | 702 if (is_good) |
| 652 g_npnetscape_funcs->releasevariantvalue(&np_result); | 703 g_npnetscape_funcs->releasevariantvalue(&np_result); |
| 653 return is_good; | 704 return is_good; |
| 654 } | 705 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 668 } | 719 } |
| 669 | 720 |
| 670 // static | 721 // static |
| 671 void HostNPScriptObject::NPTaskSpringboard(void* task) { | 722 void HostNPScriptObject::NPTaskSpringboard(void* task) { |
| 672 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); | 723 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); |
| 673 real_task->Run(); | 724 real_task->Run(); |
| 674 delete real_task; | 725 delete real_task; |
| 675 } | 726 } |
| 676 | 727 |
| 677 } // namespace remoting | 728 } // namespace remoting |
| OLD | NEW |