| Index: remoting/host/plugin/host_script_object.cc
|
| diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc
|
| index 9f2ba4d730182299e1dc68a08ec866159985201f..8b100c499d7d0cb5bf37449fba15eed77676b807 100644
|
| --- a/remoting/host/plugin/host_script_object.cc
|
| +++ b/remoting/host/plugin/host_script_object.cc
|
| @@ -16,10 +16,10 @@
|
| #include "remoting/host/host_config.h"
|
| #include "remoting/host/host_key_pair.h"
|
| #include "remoting/host/in_memory_host_config.h"
|
| -#include "remoting/host/plugin/host_plugin_utils.h"
|
| #include "remoting/host/plugin/policy_hack/nat_policy.h"
|
| #include "remoting/host/register_support_host_request.h"
|
| #include "remoting/host/support_access_verifier.h"
|
| +#include "remoting/host/ui_strings.h"
|
|
|
| namespace remoting {
|
|
|
| @@ -40,6 +40,7 @@ namespace remoting {
|
| //
|
| // attribute Function void logDebugInfo(string);
|
| // attribute Function void onStateChanged();
|
| +// attribute Function string localizeString(string,...);
|
| //
|
| // // The |auth_service_with_token| parameter should be in the format
|
| // // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd".
|
| @@ -52,6 +53,7 @@ const char* kAttrNameAccessCode = "accessCode";
|
| const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime";
|
| const char* kAttrNameClient = "client";
|
| const char* kAttrNameState = "state";
|
| +const char* kAttrNameLocalizeString = "localizeString";
|
| const char* kAttrNameLogDebugInfo = "logDebugInfo";
|
| const char* kAttrNameOnStateChanged = "onStateChanged";
|
| const char* kFuncNameConnect = "connect";
|
| @@ -80,8 +82,6 @@ HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent)
|
| : plugin_(plugin),
|
| parent_(parent),
|
| state_(kDisconnected),
|
| - log_debug_info_func_(NULL),
|
| - on_state_changed_func_(NULL),
|
| np_thread_id_(base::PlatformThread::CurrentId()),
|
| failed_login_attempts_(0),
|
| disconnected_event_(true, false),
|
| @@ -135,13 +135,6 @@ HostNPScriptObject::~HostNPScriptObject() {
|
|
|
| // Stop all threads.
|
| host_context_.Stop();
|
| -
|
| - if (log_debug_info_func_) {
|
| - g_npnetscape_funcs->releaseobject(log_debug_info_func_);
|
| - }
|
| - if (on_state_changed_func_) {
|
| - g_npnetscape_funcs->releaseobject(on_state_changed_func_);
|
| - }
|
| }
|
|
|
| bool HostNPScriptObject::Init() {
|
| @@ -195,6 +188,7 @@ bool HostNPScriptObject::HasProperty(const std::string& property_name) {
|
| property_name == kAttrNameAccessCodeLifetime ||
|
| property_name == kAttrNameClient ||
|
| property_name == kAttrNameState ||
|
| + property_name == kAttrNameLocalizeString ||
|
| property_name == kAttrNameLogDebugInfo ||
|
| property_name == kAttrNameOnStateChanged ||
|
| property_name == kAttrNameDisconnected ||
|
| @@ -215,10 +209,13 @@ bool HostNPScriptObject::GetProperty(const std::string& property_name,
|
| }
|
|
|
| if (property_name == kAttrNameOnStateChanged) {
|
| - OBJECT_TO_NPVARIANT(on_state_changed_func_, *result);
|
| + OBJECT_TO_NPVARIANT(on_state_changed_func_.get(), *result);
|
| + return true;
|
| + } else if (property_name == kAttrNameLocalizeString) {
|
| + OBJECT_TO_NPVARIANT(localize_func_.get(), *result);
|
| return true;
|
| } else if (property_name == kAttrNameLogDebugInfo) {
|
| - OBJECT_TO_NPVARIANT(log_debug_info_func_, *result);
|
| + OBJECT_TO_NPVARIANT(log_debug_info_func_.get(), *result);
|
| return true;
|
| } else if (property_name == kAttrNameState) {
|
| INT32_TO_NPVARIANT(state_, *result);
|
| @@ -263,13 +260,18 @@ bool HostNPScriptObject::SetProperty(const std::string& property_name,
|
|
|
| if (property_name == kAttrNameOnStateChanged) {
|
| if (NPVARIANT_IS_OBJECT(*value)) {
|
| - if (on_state_changed_func_) {
|
| - g_npnetscape_funcs->releaseobject(on_state_changed_func_);
|
| - }
|
| on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value);
|
| - if (on_state_changed_func_) {
|
| - g_npnetscape_funcs->retainobject(on_state_changed_func_);
|
| - }
|
| + return true;
|
| + } else {
|
| + SetException("SetProperty: unexpected type for property " +
|
| + property_name);
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + if (property_name == kAttrNameLocalizeString) {
|
| + if (NPVARIANT_IS_OBJECT(*value)) {
|
| + localize_func_ = NPVARIANT_TO_OBJECT(*value);
|
| return true;
|
| } else {
|
| SetException("SetProperty: unexpected type for property " +
|
| @@ -280,13 +282,7 @@ bool HostNPScriptObject::SetProperty(const std::string& property_name,
|
|
|
| if (property_name == kAttrNameLogDebugInfo) {
|
| if (NPVARIANT_IS_OBJECT(*value)) {
|
| - if (log_debug_info_func_) {
|
| - g_npnetscape_funcs->releaseobject(log_debug_info_func_);
|
| - }
|
| log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value);
|
| - if (log_debug_info_func_) {
|
| - g_npnetscape_funcs->retainobject(log_debug_info_func_);
|
| - }
|
| return true;
|
| } else {
|
| SetException("SetProperty: unexpected type for property " +
|
| @@ -310,6 +306,7 @@ bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) {
|
| const char* entries[] = {
|
| kAttrNameAccessCode,
|
| kAttrNameState,
|
| + kAttrNameLocalizeString,
|
| kAttrNameLogDebugInfo,
|
| kAttrNameOnStateChanged,
|
| kFuncNameConnect,
|
| @@ -350,6 +347,7 @@ void HostNPScriptObject::OnClientAuthenticated(
|
| if (pos != std::string::npos)
|
| client_username_.replace(pos, std::string::npos, "");
|
| LOG(INFO) << "Client " << client_username_ << " connected.";
|
| + LocalizeStrings();
|
| OnStateChanged(kConnected);
|
| }
|
|
|
| @@ -589,9 +587,9 @@ void HostNPScriptObject::OnStateChanged(State state) {
|
| return;
|
| }
|
| state_ = state;
|
| - if (on_state_changed_func_) {
|
| + if (on_state_changed_func_.get()) {
|
| VLOG(2) << "Calling state changed " << state;
|
| - bool is_good = InvokeAndIgnoreResult(on_state_changed_func_, NULL, 0);
|
| + bool is_good = InvokeAndIgnoreResult(on_state_changed_func_.get(), NULL, 0);
|
| LOG_IF(ERROR, !is_good) << "OnStateChanged failed";
|
| }
|
| }
|
| @@ -627,10 +625,10 @@ void HostNPScriptObject::LogDebugInfo(const std::string& message) {
|
| return;
|
| }
|
|
|
| - if (log_debug_info_func_) {
|
| + if (log_debug_info_func_.get()) {
|
| NPVariant log_message;
|
| STRINGZ_TO_NPVARIANT(message.c_str(), log_message);
|
| - bool is_good = InvokeAndIgnoreResult(log_debug_info_func_,
|
| + bool is_good = InvokeAndIgnoreResult(log_debug_info_func_.get(),
|
| &log_message, 1);
|
| LOG_IF(ERROR, !is_good) << "LogDebugInfo failed";
|
| }
|
| @@ -642,6 +640,59 @@ void HostNPScriptObject::SetException(const std::string& exception_string) {
|
| LOG(INFO) << exception_string;
|
| }
|
|
|
| +void HostNPScriptObject::LocalizeStrings() {
|
| + UiStrings* ui_strings = host_->ui_strings();
|
| + std::string direction;
|
| + LocalizeString("@@bidi_dir", NULL, &direction);
|
| + ui_strings->direction =
|
| + direction == "rtl" ? remoting::UiStrings::RTL
|
| + : remoting::UiStrings::LTR;
|
| + LocalizeString("productName", NULL, &ui_strings->product_name);
|
| + LocalizeString("disconnectButton", NULL, &ui_strings->disconnect_button_text);
|
| + LocalizeString(
|
| +#if defined(OS_WIN)
|
| + "disconnectButtonPlusShortcutWindows",
|
| +#elif defined(OS_MAC)
|
| + "disconnectButtonPlusShortcutMacOSX",
|
| +#else
|
| + "disconnectButtonPlusShortcutLinux",
|
| +#endif
|
| + NULL, &ui_strings->disconnect_button_text_plus_shortcut);
|
| + LocalizeString("continuePrompt", NULL, &ui_strings->continue_prompt);
|
| + LocalizeString("continueButton", NULL, &ui_strings->continue_button_text);
|
| + LocalizeString("stopSharingButton", NULL,
|
| + &ui_strings->stop_sharing_button_text);
|
| + LocalizeString("messageShared", client_username_.c_str(),
|
| + &ui_strings->disconnect_message);
|
| +}
|
| +
|
| +bool HostNPScriptObject::LocalizeString(const char* tag,
|
| + const char* substitution,
|
| + std::string* result) {
|
| + NPVariant args[2];
|
| + STRINGZ_TO_NPVARIANT(tag, args[0]);
|
| + int arg_count = 1;
|
| + if (substitution) {
|
| + STRINGZ_TO_NPVARIANT(substitution, args[1]);
|
| + ++arg_count;
|
| + }
|
| + NPVariant np_result;
|
| + bool is_good = g_npnetscape_funcs->invokeDefault(
|
| + plugin_, localize_func_.get(), &args[0], arg_count, &np_result);
|
| + if (!is_good) {
|
| + LOG(ERROR) << "Localization failed for " << tag;
|
| + return false;
|
| + }
|
| + std::string translation = StringFromNPVariant(np_result);
|
| + g_npnetscape_funcs->releasevariantvalue(&np_result);
|
| + if (translation.empty()) {
|
| + LOG(ERROR) << "Missing translation for " << tag;
|
| + return false;
|
| + }
|
| + *result = translation;
|
| + return true;
|
| +}
|
| +
|
| bool HostNPScriptObject::InvokeAndIgnoreResult(NPObject* func,
|
| const NPVariant* args,
|
| uint32_t argCount) {
|
|
|