Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: remoting/host/plugin/host_script_object.cc

Issue 7635012: Host process i18n and Linux implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698