Chromium Code Reviews| 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/base/util.h" |
| 12 #include "remoting/host/chromoting_host.h" | 12 #include "remoting/host/chromoting_host.h" |
| 13 #include "remoting/host/chromoting_host_context.h" | 13 #include "remoting/host/chromoting_host_context.h" |
| 14 #include "remoting/host/desktop_environment.h" | 14 #include "remoting/host/desktop_environment.h" |
| 15 #include "remoting/host/host_config.h" | 15 #include "remoting/host/host_config.h" |
| 16 #include "remoting/host/host_key_pair.h" | 16 #include "remoting/host/host_key_pair.h" |
| 17 #include "remoting/host/in_memory_host_config.h" | 17 #include "remoting/host/in_memory_host_config.h" |
| 18 #include "remoting/host/plugin/host_plugin_utils.h" | |
| 19 #include "remoting/host/register_support_host_request.h" | 18 #include "remoting/host/register_support_host_request.h" |
| 20 #include "remoting/host/support_access_verifier.h" | 19 #include "remoting/host/support_access_verifier.h" |
| 20 #include "remoting/host/ui_strings.h" | |
| 21 | 21 |
| 22 namespace remoting { | 22 namespace remoting { |
| 23 | 23 |
| 24 // Supported Javascript interface: | 24 // Supported Javascript interface: |
| 25 // readonly attribute string accessCode; | 25 // readonly attribute string accessCode; |
| 26 // readonly attribute int accessCodeLifetime; | 26 // readonly attribute int accessCodeLifetime; |
| 27 // readonly attribute string client; | 27 // readonly attribute string client; |
| 28 // readonly attribute int state; | 28 // readonly attribute int state; |
| 29 // | 29 // |
| 30 // state: { | 30 // state: { |
| 31 // DISCONNECTED, | 31 // DISCONNECTED, |
| 32 // REQUESTED_ACCESS_CODE, | 32 // REQUESTED_ACCESS_CODE, |
| 33 // RECEIVED_ACCESS_CODE, | 33 // RECEIVED_ACCESS_CODE, |
| 34 // CONNECTED, | 34 // CONNECTED, |
| 35 // AFFIRMING_CONNECTION, | 35 // AFFIRMING_CONNECTION, |
| 36 // ERROR, | 36 // ERROR, |
| 37 // } | 37 // } |
| 38 // | 38 // |
| 39 // attribute Function void logDebugInfo(string); | 39 // attribute Function void logDebugInfo(string); |
| 40 // attribute Function void onStateChanged(); | 40 // attribute Function void onStateChanged(); |
| 41 // attribute Function string localize(string,...); | |
|
Wez
2011/08/13 01:35:32
nit: Call this "localizeString"?
Jamie
2011/08/13 02:20:15
Done.
| |
| 41 // | 42 // |
| 42 // // The |auth_service_with_token| parameter should be in the format | 43 // // The |auth_service_with_token| parameter should be in the format |
| 43 // // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". | 44 // // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". |
| 44 // void connect(string uid, string auth_service_with_token); | 45 // void connect(string uid, string auth_service_with_token); |
| 45 // void disconnect(); | 46 // void disconnect(); |
| 46 | 47 |
| 47 namespace { | 48 namespace { |
| 48 | 49 |
| 49 const char* kAttrNameAccessCode = "accessCode"; | 50 const char* kAttrNameAccessCode = "accessCode"; |
| 50 const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime"; | 51 const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime"; |
| 51 const char* kAttrNameClient = "client"; | 52 const char* kAttrNameClient = "client"; |
| 52 const char* kAttrNameState = "state"; | 53 const char* kAttrNameState = "state"; |
| 54 const char* kAttrNameLocalize = "localize"; | |
| 53 const char* kAttrNameLogDebugInfo = "logDebugInfo"; | 55 const char* kAttrNameLogDebugInfo = "logDebugInfo"; |
| 54 const char* kAttrNameOnStateChanged = "onStateChanged"; | 56 const char* kAttrNameOnStateChanged = "onStateChanged"; |
| 55 const char* kFuncNameConnect = "connect"; | 57 const char* kFuncNameConnect = "connect"; |
| 56 const char* kFuncNameDisconnect = "disconnect"; | 58 const char* kFuncNameDisconnect = "disconnect"; |
| 57 | 59 |
| 58 // States. | 60 // States. |
| 59 const char* kAttrNameDisconnected = "DISCONNECTED"; | 61 const char* kAttrNameDisconnected = "DISCONNECTED"; |
| 60 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; | 62 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; |
| 61 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; | 63 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; |
| 62 const char* kAttrNameConnected = "CONNECTED"; | 64 const char* kAttrNameConnected = "CONNECTED"; |
| 63 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; | 65 const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; |
| 64 const char* kAttrNameError = "ERROR"; | 66 const char* kAttrNameError = "ERROR"; |
| 65 | 67 |
| 66 const int kMaxLoginAttempts = 5; | 68 const int kMaxLoginAttempts = 5; |
| 67 | 69 |
| 68 } // namespace | 70 } // namespace |
| 69 | 71 |
| 70 // This flag blocks LOGs to the UI if we're already in the middle of logging | 72 // 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 | 73 // to the UI. This prevents a potential infinite loop if we encounter an error |
| 72 // while sending the log message to the UI. | 74 // while sending the log message to the UI. |
| 73 static bool g_logging_to_plugin = false; | 75 static bool g_logging_to_plugin = false; |
| 74 static HostNPScriptObject* g_logging_scriptable_object = NULL; | 76 static HostNPScriptObject* g_logging_scriptable_object = NULL; |
| 75 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; | 77 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; |
| 76 | 78 |
| 77 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) | 79 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) |
| 78 : plugin_(plugin), | 80 : plugin_(plugin), |
| 79 parent_(parent), | 81 parent_(parent), |
| 80 state_(kDisconnected), | 82 state_(kDisconnected), |
| 81 log_debug_info_func_(NULL), | |
| 82 on_state_changed_func_(NULL), | |
| 83 np_thread_id_(base::PlatformThread::CurrentId()), | 83 np_thread_id_(base::PlatformThread::CurrentId()), |
| 84 failed_login_attempts_(0), | 84 failed_login_attempts_(0), |
| 85 disconnected_event_(true, false) { | 85 disconnected_event_(true, false) { |
| 86 // Set up log message handler. | 86 // Set up log message handler. |
| 87 // Note that this approach doesn't quite support having multiple instances | 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 | 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 | 89 // grab all the debug log messages, and when any Chromoting tab is closed |
| 90 // the logging handler will go away. | 90 // the logging handler will go away. |
| 91 // Since having multiple Chromoting tabs is not a primary use case, and this | 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 | 92 // is just debug logging, we're punting improving debug log support for that |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 116 // here because |host_context_| needs to be stopped on the plugin | 116 // here because |host_context_| needs to be stopped on the plugin |
| 117 // thread, but the plugin thread may not exist after the instance | 117 // thread, but the plugin thread may not exist after the instance |
| 118 // is destroyed. | 118 // is destroyed. |
| 119 destructing_.Set(); | 119 destructing_.Set(); |
| 120 disconnected_event_.Reset(); | 120 disconnected_event_.Reset(); |
| 121 DisconnectInternal(); | 121 DisconnectInternal(); |
| 122 disconnected_event_.Wait(); | 122 disconnected_event_.Wait(); |
| 123 | 123 |
| 124 // Stop all threads. | 124 // Stop all threads. |
| 125 host_context_.Stop(); | 125 host_context_.Stop(); |
| 126 | |
| 127 if (log_debug_info_func_) { | |
| 128 g_npnetscape_funcs->releaseobject(log_debug_info_func_); | |
| 129 } | |
| 130 if (on_state_changed_func_) { | |
| 131 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | |
| 132 } | |
| 133 } | 126 } |
| 134 | 127 |
| 135 bool HostNPScriptObject::Init() { | 128 bool HostNPScriptObject::Init() { |
| 136 VLOG(2) << "Init"; | 129 VLOG(2) << "Init"; |
| 137 // TODO(wez): This starts a bunch of threads, which might fail. | 130 // TODO(wez): This starts a bunch of threads, which might fail. |
| 138 host_context_.Start(); | 131 host_context_.Start(); |
| 139 return true; | 132 return true; |
| 140 } | 133 } |
| 141 | 134 |
| 142 bool HostNPScriptObject::HasMethod(const std::string& method_name) { | 135 bool HostNPScriptObject::HasMethod(const std::string& method_name) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 171 } | 164 } |
| 172 } | 165 } |
| 173 | 166 |
| 174 bool HostNPScriptObject::HasProperty(const std::string& property_name) { | 167 bool HostNPScriptObject::HasProperty(const std::string& property_name) { |
| 175 VLOG(2) << "HasProperty " << property_name; | 168 VLOG(2) << "HasProperty " << property_name; |
| 176 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 169 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 177 return (property_name == kAttrNameAccessCode || | 170 return (property_name == kAttrNameAccessCode || |
| 178 property_name == kAttrNameAccessCodeLifetime || | 171 property_name == kAttrNameAccessCodeLifetime || |
| 179 property_name == kAttrNameClient || | 172 property_name == kAttrNameClient || |
| 180 property_name == kAttrNameState || | 173 property_name == kAttrNameState || |
| 174 property_name == kAttrNameLocalize || | |
| 181 property_name == kAttrNameLogDebugInfo || | 175 property_name == kAttrNameLogDebugInfo || |
| 182 property_name == kAttrNameOnStateChanged || | 176 property_name == kAttrNameOnStateChanged || |
| 183 property_name == kAttrNameDisconnected || | 177 property_name == kAttrNameDisconnected || |
| 184 property_name == kAttrNameRequestedAccessCode || | 178 property_name == kAttrNameRequestedAccessCode || |
| 185 property_name == kAttrNameReceivedAccessCode || | 179 property_name == kAttrNameReceivedAccessCode || |
| 186 property_name == kAttrNameConnected || | 180 property_name == kAttrNameConnected || |
| 187 property_name == kAttrNameAffirmingConnection || | 181 property_name == kAttrNameAffirmingConnection || |
| 188 property_name == kAttrNameError); | 182 property_name == kAttrNameError); |
| 189 } | 183 } |
| 190 | 184 |
| 191 bool HostNPScriptObject::GetProperty(const std::string& property_name, | 185 bool HostNPScriptObject::GetProperty(const std::string& property_name, |
| 192 NPVariant* result) { | 186 NPVariant* result) { |
| 193 VLOG(2) << "GetProperty " << property_name; | 187 VLOG(2) << "GetProperty " << property_name; |
| 194 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 188 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 195 if (!result) { | 189 if (!result) { |
| 196 SetException("GetProperty: NULL result"); | 190 SetException("GetProperty: NULL result"); |
| 197 return false; | 191 return false; |
| 198 } | 192 } |
| 199 | 193 |
| 200 if (property_name == kAttrNameOnStateChanged) { | 194 if (property_name == kAttrNameOnStateChanged) { |
| 201 OBJECT_TO_NPVARIANT(on_state_changed_func_, *result); | 195 OBJECT_TO_NPVARIANT(on_state_changed_func_.get(), *result); |
| 196 return true; | |
| 197 } else if (property_name == kAttrNameLocalize) { | |
| 198 OBJECT_TO_NPVARIANT(localize_func_.get(), *result); | |
| 202 return true; | 199 return true; |
| 203 } else if (property_name == kAttrNameLogDebugInfo) { | 200 } else if (property_name == kAttrNameLogDebugInfo) { |
| 204 OBJECT_TO_NPVARIANT(log_debug_info_func_, *result); | 201 OBJECT_TO_NPVARIANT(log_debug_info_func_.get(), *result); |
| 205 return true; | 202 return true; |
| 206 } else if (property_name == kAttrNameState) { | 203 } else if (property_name == kAttrNameState) { |
| 207 INT32_TO_NPVARIANT(state_, *result); | 204 INT32_TO_NPVARIANT(state_, *result); |
| 208 return true; | 205 return true; |
| 209 } else if (property_name == kAttrNameAccessCode) { | 206 } else if (property_name == kAttrNameAccessCode) { |
| 210 *result = NPVariantFromString(access_code_); | 207 *result = NPVariantFromString(access_code_); |
| 211 return true; | 208 return true; |
| 212 } else if (property_name == kAttrNameAccessCodeLifetime) { | 209 } else if (property_name == kAttrNameAccessCodeLifetime) { |
| 213 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); | 210 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); |
| 214 return true; | 211 return true; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 239 } | 236 } |
| 240 } | 237 } |
| 241 | 238 |
| 242 bool HostNPScriptObject::SetProperty(const std::string& property_name, | 239 bool HostNPScriptObject::SetProperty(const std::string& property_name, |
| 243 const NPVariant* value) { | 240 const NPVariant* value) { |
| 244 VLOG(2) << "SetProperty " << property_name; | 241 VLOG(2) << "SetProperty " << property_name; |
| 245 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 242 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 246 | 243 |
| 247 if (property_name == kAttrNameOnStateChanged) { | 244 if (property_name == kAttrNameOnStateChanged) { |
| 248 if (NPVARIANT_IS_OBJECT(*value)) { | 245 if (NPVARIANT_IS_OBJECT(*value)) { |
| 249 if (on_state_changed_func_) { | 246 on_state_changed_func_.replace(NPVARIANT_TO_OBJECT(*value)); |
| 250 g_npnetscape_funcs->releaseobject(on_state_changed_func_); | |
| 251 } | |
| 252 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value); | |
| 253 if (on_state_changed_func_) { | |
| 254 g_npnetscape_funcs->retainobject(on_state_changed_func_); | |
| 255 } | |
| 256 return true; | 247 return true; |
| 257 } else { | 248 } else { |
| 258 SetException("SetProperty: unexpected type for property " + | 249 SetException("SetProperty: unexpected type for property " + |
| 250 property_name); | |
| 251 } | |
| 252 return false; | |
| 253 } | |
| 254 | |
| 255 if (property_name == kAttrNameLocalize) { | |
| 256 if (NPVARIANT_IS_OBJECT(*value)) { | |
| 257 localize_func_.replace(NPVARIANT_TO_OBJECT(*value)); | |
| 258 // Localize static strings. The disconnect window text can't be localized | |
| 259 // until the user name is known. | |
| 260 std::string direction; | |
| 261 Localize("@@bidi_dir", NULL, &direction); | |
| 262 remoting::ui_strings::direction = | |
| 263 direction == "rtl" ? remoting::ui_strings::RTL | |
| 264 : remoting::ui_strings::LTR; | |
| 265 Localize("productName", NULL, &remoting::ui_strings::productName); | |
| 266 Localize("disconnectButton", NULL, | |
| 267 &remoting::ui_strings::disconnectButtonText); | |
| 268 Localize( | |
| 269 #if defined(OS_WIN) | |
| 270 "disconnectButtonShortcutWindows", | |
| 271 #elif defined(OS_MAC) | |
| 272 "disconnectButtonShortcutMacOSX", | |
| 273 #else | |
| 274 "disconnectButtonShortcutLinux", | |
| 275 #endif | |
| 276 NULL, &remoting::ui_strings::disconnectButtonShortcut); | |
| 277 Localize("continuePrompt", NULL, &remoting::ui_strings::continuePrompt); | |
| 278 Localize("continueButton", NULL, | |
| 279 &remoting::ui_strings::continueButtonText); | |
| 280 Localize("stopSharingButton", | |
| 281 NULL, &remoting::ui_strings::stopSharingButtonText); | |
|
Wez
2011/08/13 01:35:32
Move these into a LocalizeStrings() function, rath
Jamie
2011/08/13 02:20:15
Done.
| |
| 282 return true; | |
| 283 } else { | |
| 284 SetException("SetProperty: unexpected type for property " + | |
| 259 property_name); | 285 property_name); |
| 260 } | 286 } |
| 261 return false; | 287 return false; |
| 262 } | 288 } |
| 263 | 289 |
| 264 if (property_name == kAttrNameLogDebugInfo) { | 290 if (property_name == kAttrNameLogDebugInfo) { |
| 265 if (NPVARIANT_IS_OBJECT(*value)) { | 291 if (NPVARIANT_IS_OBJECT(*value)) { |
| 266 if (log_debug_info_func_) { | 292 log_debug_info_func_.replace(NPVARIANT_TO_OBJECT(*value)); |
| 267 g_npnetscape_funcs->releaseobject(log_debug_info_func_); | |
| 268 } | |
| 269 log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value); | |
| 270 if (log_debug_info_func_) { | |
| 271 g_npnetscape_funcs->retainobject(log_debug_info_func_); | |
| 272 } | |
| 273 return true; | 293 return true; |
| 274 } else { | 294 } else { |
| 275 SetException("SetProperty: unexpected type for property " + | 295 SetException("SetProperty: unexpected type for property " + |
| 276 property_name); | 296 property_name); |
| 277 } | 297 } |
| 278 return false; | 298 return false; |
| 279 } | 299 } |
| 280 | 300 |
| 281 return false; | 301 return false; |
| 282 } | 302 } |
| 283 | 303 |
| 284 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { | 304 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) { |
| 285 VLOG(2) << "RemoveProperty " << property_name; | 305 VLOG(2) << "RemoveProperty " << property_name; |
| 286 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 306 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 287 return false; | 307 return false; |
| 288 } | 308 } |
| 289 | 309 |
| 290 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { | 310 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { |
| 291 VLOG(2) << "Enumerate"; | 311 VLOG(2) << "Enumerate"; |
| 292 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 312 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 293 const char* entries[] = { | 313 const char* entries[] = { |
| 294 kAttrNameAccessCode, | 314 kAttrNameAccessCode, |
| 295 kAttrNameState, | 315 kAttrNameState, |
| 316 kAttrNameLocalize, | |
| 296 kAttrNameLogDebugInfo, | 317 kAttrNameLogDebugInfo, |
| 297 kAttrNameOnStateChanged, | 318 kAttrNameOnStateChanged, |
| 298 kFuncNameConnect, | 319 kFuncNameConnect, |
| 299 kFuncNameDisconnect, | 320 kFuncNameDisconnect, |
| 300 kAttrNameDisconnected, | 321 kAttrNameDisconnected, |
| 301 kAttrNameRequestedAccessCode, | 322 kAttrNameRequestedAccessCode, |
| 302 kAttrNameReceivedAccessCode, | 323 kAttrNameReceivedAccessCode, |
| 303 kAttrNameConnected, | 324 kAttrNameConnected, |
| 304 kAttrNameAffirmingConnection, | 325 kAttrNameAffirmingConnection, |
| 305 kAttrNameError | 326 kAttrNameError |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 326 } | 347 } |
| 327 | 348 |
| 328 void HostNPScriptObject::OnClientAuthenticated( | 349 void HostNPScriptObject::OnClientAuthenticated( |
| 329 remoting::protocol::ConnectionToClient* client) { | 350 remoting::protocol::ConnectionToClient* client) { |
| 330 DCHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_); | 351 DCHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_); |
| 331 client_username_ = client->session()->jid(); | 352 client_username_ = client->session()->jid(); |
| 332 size_t pos = client_username_.find('/'); | 353 size_t pos = client_username_.find('/'); |
| 333 if (pos != std::string::npos) | 354 if (pos != std::string::npos) |
| 334 client_username_.replace(pos, std::string::npos, ""); | 355 client_username_.replace(pos, std::string::npos, ""); |
| 335 LOG(INFO) << "Client " << client_username_ << " connected."; | 356 LOG(INFO) << "Client " << client_username_ << " connected."; |
| 357 // Localize the 'your desktop is shared' string now that we have the username. | |
| 358 Localize("messageShared", client_username_.c_str(), | |
| 359 &remoting::ui_strings::disconnectMessage); | |
| 336 OnStateChanged(kConnected); | 360 OnStateChanged(kConnected); |
| 337 } | 361 } |
| 338 | 362 |
| 339 void HostNPScriptObject::OnClientDisconnected( | 363 void HostNPScriptObject::OnClientDisconnected( |
| 340 remoting::protocol::ConnectionToClient* client) { | 364 remoting::protocol::ConnectionToClient* client) { |
| 341 client_username_.clear(); | 365 client_username_.clear(); |
| 342 OnStateChanged(kDisconnected); | 366 OnStateChanged(kDisconnected); |
| 343 } | 367 } |
| 344 | 368 |
| 345 void HostNPScriptObject::OnShutdown() { | 369 void HostNPScriptObject::OnShutdown() { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 516 if (destructing_.IsSet()) | 540 if (destructing_.IsSet()) |
| 517 return; | 541 return; |
| 518 | 542 |
| 519 if (!host_context_.IsUIThread()) { | 543 if (!host_context_.IsUIThread()) { |
| 520 host_context_.PostTaskToUIThread( | 544 host_context_.PostTaskToUIThread( |
| 521 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, | 545 FROM_HERE, base::Bind(&HostNPScriptObject::OnStateChanged, |
| 522 base::Unretained(this), state)); | 546 base::Unretained(this), state)); |
| 523 return; | 547 return; |
| 524 } | 548 } |
| 525 state_ = state; | 549 state_ = state; |
| 526 if (on_state_changed_func_) { | 550 if (on_state_changed_func_.get()) { |
| 527 VLOG(2) << "Calling state changed " << state; | 551 VLOG(2) << "Calling state changed " << state; |
| 528 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0); | 552 bool is_good = InvokeAndIgnoreResult(on_state_changed_func_.get(), NULL, 0); |
| 529 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; | 553 LOG_IF(ERROR, !is_good) << "OnStateChanged failed"; |
| 530 } | 554 } |
| 531 } | 555 } |
| 532 | 556 |
| 533 // static | 557 // static |
| 534 bool HostNPScriptObject::LogToUI(int severity, const char* file, int line, | 558 bool HostNPScriptObject::LogToUI(int severity, const char* file, int line, |
| 535 size_t message_start, | 559 size_t message_start, |
| 536 const std::string& str) { | 560 const std::string& str) { |
| 537 // The |g_logging_to_plugin| check is to prevent logging to the scriptable | 561 // The |g_logging_to_plugin| check is to prevent logging to the scriptable |
| 538 // object if we're already in the middle of logging. | 562 // object if we're already in the middle of logging. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 554 if (destructing_.IsSet()) | 578 if (destructing_.IsSet()) |
| 555 return; | 579 return; |
| 556 | 580 |
| 557 if (!host_context_.IsUIThread()) { | 581 if (!host_context_.IsUIThread()) { |
| 558 host_context_.PostTaskToUIThread( | 582 host_context_.PostTaskToUIThread( |
| 559 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, | 583 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo, |
| 560 base::Unretained(this), message)); | 584 base::Unretained(this), message)); |
| 561 return; | 585 return; |
| 562 } | 586 } |
| 563 | 587 |
| 564 if (log_debug_info_func_) { | 588 if (log_debug_info_func_.get()) { |
| 565 NPVariant log_message; | 589 NPVariant log_message; |
| 566 STRINGZ_TO_NPVARIANT(message.c_str(), log_message); | 590 STRINGZ_TO_NPVARIANT(message.c_str(), log_message); |
| 567 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_, | 591 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_.get(), |
| 568 &log_message, 1); | 592 &log_message, 1); |
| 569 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; | 593 LOG_IF(ERROR, !is_good) << "LogDebugInfo failed"; |
| 570 } | 594 } |
| 571 } | 595 } |
| 572 | 596 |
| 573 void HostNPScriptObject::SetException(const std::string& exception_string) { | 597 void HostNPScriptObject::SetException(const std::string& exception_string) { |
| 574 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 598 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
| 575 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); | 599 g_npnetscape_funcs->setexception(parent_, exception_string.c_str()); |
| 576 LOG(INFO) << exception_string; | 600 LOG(INFO) << exception_string; |
| 577 } | 601 } |
| 578 | 602 |
| 603 bool HostNPScriptObject::Localize(const char* tag, const char* parameter, | |
|
Wez
2011/08/13 01:35:32
nit: |parameter| isn't very descriptive; is there
Jamie
2011/08/13 02:20:15
Hmmm... Now that you mention it, that's probably t
| |
| 604 std::string* result) { | |
| 605 NPVariant args[2]; | |
| 606 STRINGZ_TO_NPVARIANT(tag, args[0]); | |
| 607 if (parameter) { | |
| 608 STRINGZ_TO_NPVARIANT(parameter, args[1]); | |
| 609 } | |
| 610 NPVariant np_result; | |
| 611 bool is_good = g_npnetscape_funcs->invokeDefault( | |
| 612 plugin_, localize_func_.get(), &args[0], parameter ? 2 : 1, &np_result); | |
|
Wez
2011/08/13 01:35:32
nit: Maybe pre-calculate arg_count rather than use
Jamie
2011/08/13 02:20:15
Done.
| |
| 613 if (!is_good) { | |
| 614 LOG(ERROR) << "Localization failed for " << tag; | |
|
Wez
2011/08/13 01:35:32
nit: localize() failed? This really means that th
Jamie
2011/08/13 02:20:15
I don't really know in what circumstances this mig
| |
| 615 return false; | |
| 616 } | |
| 617 std::string translation = StringFromNPVariant(np_result); | |
| 618 g_npnetscape_funcs->releasevariantvalue(&np_result); | |
| 619 if (translation.empty()) { | |
| 620 LOG(ERROR) << "Missing translation for " << tag; | |
| 621 return false; | |
| 622 } | |
| 623 *result = translation; | |
| 624 return true; | |
| 625 } | |
| 626 | |
| 579 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, | 627 bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func, |
| 580 const NPVariant* args, | 628 const NPVariant* args, |
| 581 uint32_t argCount) { | 629 uint32_t argCount) { |
| 582 NPVariant np_result; | 630 NPVariant np_result; |
| 583 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, | 631 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, |
| 584 argCount, &np_result); | 632 argCount, &np_result); |
| 585 if (is_good) | 633 if (is_good) |
| 586 g_npnetscape_funcs->releasevariantvalue(&np_result); | 634 g_npnetscape_funcs->releasevariantvalue(&np_result); |
| 587 return is_good; | 635 return is_good; |
| 588 } | 636 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 602 } | 650 } |
| 603 | 651 |
| 604 // static | 652 // static |
| 605 void HostNPScriptObject::NPTaskSpringboard(void* task) { | 653 void HostNPScriptObject::NPTaskSpringboard(void* task) { |
| 606 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); | 654 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); |
| 607 real_task->Run(); | 655 real_task->Run(); |
| 608 delete real_task; | 656 delete real_task; |
| 609 } | 657 } |
| 610 | 658 |
| 611 } // namespace remoting | 659 } // namespace remoting |
| OLD | NEW |