Run LocalizeStrings() on plugin thread.

BUG=94135
TEST=Manual


Review URL: http://codereview.chromium.org/7792011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98831 0039d316-1c4b-4281-b951-d872f2087c98
parent 546f0ae7
...@@ -42,6 +42,11 @@ NPObject* ObjectFromNPVariant(const NPVariant& variant) { ...@@ -42,6 +42,11 @@ NPObject* ObjectFromNPVariant(const NPVariant& variant) {
ScopedRefNPObject::ScopedRefNPObject() : object_(NULL) { } ScopedRefNPObject::ScopedRefNPObject() : object_(NULL) { }
ScopedRefNPObject::ScopedRefNPObject(NPObject* object)
: object_(NULL) {
*this = object;
}
ScopedRefNPObject::~ScopedRefNPObject() { ScopedRefNPObject::~ScopedRefNPObject() {
*this = NULL; *this = NULL;
} }
......
...@@ -35,6 +35,7 @@ NPObject* ObjectFromNPVariant(const NPVariant& variant); ...@@ -35,6 +35,7 @@ NPObject* ObjectFromNPVariant(const NPVariant& variant);
class ScopedRefNPObject { class ScopedRefNPObject {
public: public:
ScopedRefNPObject(); ScopedRefNPObject();
explicit ScopedRefNPObject(NPObject* object);
~ScopedRefNPObject(); ~ScopedRefNPObject();
// Release the held reference and replace it with |object|, incrementing // Release the held reference and replace it with |object|, incrementing
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "remoting/host/plugin/policy_hack/nat_policy.h" #include "remoting/host/plugin/policy_hack/nat_policy.h"
#include "remoting/host/register_support_host_request.h" #include "remoting/host/register_support_host_request.h"
#include "remoting/host/support_access_verifier.h" #include "remoting/host/support_access_verifier.h"
#include "remoting/host/ui_strings.h"
namespace remoting { namespace remoting {
...@@ -42,12 +41,12 @@ namespace remoting { ...@@ -42,12 +41,12 @@ namespace remoting {
// //
// attribute Function void logDebugInfo(string); // attribute Function void logDebugInfo(string);
// attribute Function void onStateChanged(); // attribute Function void onStateChanged();
// attribute Function string localizeString(string,...);
// //
// // The |auth_service_with_token| parameter should be in the format // // The |auth_service_with_token| parameter should be in the format
// // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". // // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd".
// void connect(string uid, string auth_service_with_token); // void connect(string uid, string auth_service_with_token);
// void disconnect(); // void disconnect();
// void localize(string (*localize_func)(string,...));
namespace { namespace {
...@@ -55,11 +54,11 @@ const char* kAttrNameAccessCode = "accessCode"; ...@@ -55,11 +54,11 @@ const char* kAttrNameAccessCode = "accessCode";
const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime"; const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime";
const char* kAttrNameClient = "client"; const char* kAttrNameClient = "client";
const char* kAttrNameState = "state"; const char* kAttrNameState = "state";
const char* kAttrNameLocalizeString = "localizeString";
const char* kAttrNameLogDebugInfo = "logDebugInfo"; const char* kAttrNameLogDebugInfo = "logDebugInfo";
const char* kAttrNameOnStateChanged = "onStateChanged"; const char* kAttrNameOnStateChanged = "onStateChanged";
const char* kFuncNameConnect = "connect"; const char* kFuncNameConnect = "connect";
const char* kFuncNameDisconnect = "disconnect"; const char* kFuncNameDisconnect = "disconnect";
const char* kFuncNameLocalize = "localize";
// States. // States.
const char* kAttrNameDisconnected = "DISCONNECTED"; const char* kAttrNameDisconnected = "DISCONNECTED";
...@@ -158,7 +157,8 @@ bool HostNPScriptObject::HasMethod(const std::string& method_name) { ...@@ -158,7 +157,8 @@ bool HostNPScriptObject::HasMethod(const std::string& method_name) {
VLOG(2) << "HasMethod " << method_name; VLOG(2) << "HasMethod " << method_name;
CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
return (method_name == kFuncNameConnect || return (method_name == kFuncNameConnect ||
method_name == kFuncNameDisconnect); method_name == kFuncNameDisconnect ||
method_name == kFuncNameLocalize);
} }
bool HostNPScriptObject::InvokeDefault(const NPVariant* args, bool HostNPScriptObject::InvokeDefault(const NPVariant* args,
...@@ -180,6 +180,8 @@ bool HostNPScriptObject::Invoke(const std::string& method_name, ...@@ -180,6 +180,8 @@ bool HostNPScriptObject::Invoke(const std::string& method_name,
return Connect(args, argCount, result); return Connect(args, argCount, result);
} else if (method_name == kFuncNameDisconnect) { } else if (method_name == kFuncNameDisconnect) {
return Disconnect(args, argCount, result); return Disconnect(args, argCount, result);
} else if (method_name == kFuncNameLocalize) {
return Localize(args, argCount, result);
} else { } else {
SetException("Invoke: unknown method " + method_name); SetException("Invoke: unknown method " + method_name);
return false; return false;
...@@ -193,7 +195,6 @@ bool HostNPScriptObject::HasProperty(const std::string& property_name) { ...@@ -193,7 +195,6 @@ bool HostNPScriptObject::HasProperty(const std::string& property_name) {
property_name == kAttrNameAccessCodeLifetime || property_name == kAttrNameAccessCodeLifetime ||
property_name == kAttrNameClient || property_name == kAttrNameClient ||
property_name == kAttrNameState || property_name == kAttrNameState ||
property_name == kAttrNameLocalizeString ||
property_name == kAttrNameLogDebugInfo || property_name == kAttrNameLogDebugInfo ||
property_name == kAttrNameOnStateChanged || property_name == kAttrNameOnStateChanged ||
property_name == kAttrNameDisconnected || property_name == kAttrNameDisconnected ||
...@@ -216,9 +217,6 @@ bool HostNPScriptObject::GetProperty(const std::string& property_name, ...@@ -216,9 +217,6 @@ bool HostNPScriptObject::GetProperty(const std::string& property_name,
if (property_name == kAttrNameOnStateChanged) { if (property_name == kAttrNameOnStateChanged) {
OBJECT_TO_NPVARIANT(on_state_changed_func_.get(), *result); OBJECT_TO_NPVARIANT(on_state_changed_func_.get(), *result);
return true; return true;
} else if (property_name == kAttrNameLocalizeString) {
OBJECT_TO_NPVARIANT(localize_func_.get(), *result);
return true;
} else if (property_name == kAttrNameLogDebugInfo) { } else if (property_name == kAttrNameLogDebugInfo) {
OBJECT_TO_NPVARIANT(log_debug_info_func_.get(), *result); OBJECT_TO_NPVARIANT(log_debug_info_func_.get(), *result);
return true; return true;
...@@ -274,17 +272,6 @@ bool HostNPScriptObject::SetProperty(const std::string& property_name, ...@@ -274,17 +272,6 @@ bool HostNPScriptObject::SetProperty(const std::string& property_name,
return false; 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 " +
property_name);
}
return false;
}
if (property_name == kAttrNameLogDebugInfo) { if (property_name == kAttrNameLogDebugInfo) {
if (NPVARIANT_IS_OBJECT(*value)) { if (NPVARIANT_IS_OBJECT(*value)) {
log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value); log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value);
...@@ -311,11 +298,11 @@ bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { ...@@ -311,11 +298,11 @@ bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) {
const char* entries[] = { const char* entries[] = {
kAttrNameAccessCode, kAttrNameAccessCode,
kAttrNameState, kAttrNameState,
kAttrNameLocalizeString,
kAttrNameLogDebugInfo, kAttrNameLogDebugInfo,
kAttrNameOnStateChanged, kAttrNameOnStateChanged,
kFuncNameConnect, kFuncNameConnect,
kFuncNameDisconnect, kFuncNameDisconnect,
kFuncNameLocalize,
kAttrNameDisconnected, kAttrNameDisconnected,
kAttrNameRequestedAccessCode, kAttrNameRequestedAccessCode,
kAttrNameReceivedAccessCode, kAttrNameReceivedAccessCode,
...@@ -483,7 +470,10 @@ void HostNPScriptObject::FinishConnect( ...@@ -483,7 +470,10 @@ void HostNPScriptObject::FinishConnect(
host_->AddStatusObserver(register_request_.get()); host_->AddStatusObserver(register_request_.get());
host_->set_it2me(true); host_->set_it2me(true);
LocalizeStrings(); {
base::AutoLock auto_lock(ui_strings_lock_);
host_->SetUiStrings(ui_strings_);
}
// Start the Host. // Start the Host.
host_->Start(); host_->Start();
...@@ -506,6 +496,25 @@ bool HostNPScriptObject::Disconnect(const NPVariant* args, ...@@ -506,6 +496,25 @@ bool HostNPScriptObject::Disconnect(const NPVariant* args,
return true; return true;
} }
bool HostNPScriptObject::Localize(const NPVariant* args,
uint32_t arg_count,
NPVariant* result) {
CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
if (arg_count != 1) {
SetException("localize: bad number of arguments");
return false;
}
if (NPVARIANT_IS_OBJECT(args[0])) {
ScopedRefNPObject localize_func(NPVARIANT_TO_OBJECT(args[0]));
LocalizeStrings(localize_func.get());
return true;
} else {
SetException("localize: unexpected type for argument 1");
return false;
}
}
void HostNPScriptObject::DisconnectInternal() { void HostNPScriptObject::DisconnectInternal() {
if (MessageLoop::current() != host_context_.main_message_loop()) { if (MessageLoop::current() != host_context_.main_message_loop()) {
host_context_.main_message_loop()->PostTask( host_context_.main_message_loop()->PostTask(
...@@ -645,16 +654,19 @@ void HostNPScriptObject::SetException(const std::string& exception_string) { ...@@ -645,16 +654,19 @@ void HostNPScriptObject::SetException(const std::string& exception_string) {
LOG(INFO) << exception_string; LOG(INFO) << exception_string;
} }
void HostNPScriptObject::LocalizeStrings() { void HostNPScriptObject::LocalizeStrings(NPObject* localize_func) {
DCHECK(plugin_message_loop_proxy_->BelongsToCurrentThread());
UiStrings ui_strings; UiStrings ui_strings;
string16 direction; string16 direction;
LocalizeString("@@bidi_dir", &direction); LocalizeString(localize_func, "@@bidi_dir", &direction);
ui_strings.direction = UTF16ToUTF8(direction) == "rtl" ? ui_strings.direction = UTF16ToUTF8(direction) == "rtl" ?
remoting::UiStrings::RTL : remoting::UiStrings::LTR; remoting::UiStrings::RTL : remoting::UiStrings::LTR;
LocalizeString(/*i18n-content*/"PRODUCT_NAME", &ui_strings.product_name); LocalizeString(localize_func, /*i18n-content*/"PRODUCT_NAME",
LocalizeString(/*i18n-content*/"DISCONNECT_BUTTON", &ui_strings.product_name);
LocalizeString(localize_func, /*i18n-content*/"DISCONNECT_BUTTON",
&ui_strings.disconnect_button_text); &ui_strings.disconnect_button_text);
LocalizeString( LocalizeString(localize_func,
#if defined(OS_WIN) #if defined(OS_WIN)
/*i18n-content*/"DISCONNECT_BUTTON_PLUS_SHORTCUT_WINDOWS", /*i18n-content*/"DISCONNECT_BUTTON_PLUS_SHORTCUT_WINDOWS",
#elif defined(OS_MAC) #elif defined(OS_MAC)
...@@ -663,24 +675,26 @@ void HostNPScriptObject::LocalizeStrings() { ...@@ -663,24 +675,26 @@ void HostNPScriptObject::LocalizeStrings() {
/*i18n-content*/"DISCONNECT_BUTTON_PLUS_SHORTCUT_LINUX", /*i18n-content*/"DISCONNECT_BUTTON_PLUS_SHORTCUT_LINUX",
#endif #endif
&ui_strings.disconnect_button_text_plus_shortcut); &ui_strings.disconnect_button_text_plus_shortcut);
LocalizeString(/*i18n-content*/"CONTINUE_PROMPT", LocalizeString(localize_func, /*i18n-content*/"CONTINUE_PROMPT",
&ui_strings.continue_prompt); &ui_strings.continue_prompt);
LocalizeString(/*i18n-content*/"CONTINUE_BUTTON", LocalizeString(localize_func, /*i18n-content*/"CONTINUE_BUTTON",
&ui_strings.continue_button_text); &ui_strings.continue_button_text);
LocalizeString(/*i18n-content*/"STOP_SHARING_BUTTON", LocalizeString(localize_func, /*i18n-content*/"STOP_SHARING_BUTTON",
&ui_strings.stop_sharing_button_text); &ui_strings.stop_sharing_button_text);
LocalizeString(/*i18n-content*/"MESSAGE_SHARED", LocalizeString(localize_func, /*i18n-content*/"MESSAGE_SHARED",
&ui_strings.disconnect_message); &ui_strings.disconnect_message);
host_->SetUiStrings(ui_strings); base::AutoLock auto_lock(ui_strings_lock_);
ui_strings_ = ui_strings;
} }
bool HostNPScriptObject::LocalizeString(const char* tag, string16* result) { bool HostNPScriptObject::LocalizeString(NPObject* localize_func,
const char* tag, string16* result) {
NPVariant args[2]; NPVariant args[2];
STRINGZ_TO_NPVARIANT(tag, args[0]); STRINGZ_TO_NPVARIANT(tag, args[0]);
NPVariant np_result; NPVariant np_result;
bool is_good = g_npnetscape_funcs->invokeDefault( bool is_good = g_npnetscape_funcs->invokeDefault(
plugin_, localize_func_.get(), &args[0], 1, &np_result); plugin_, localize_func, &args[0], 1, &np_result);
if (!is_good) { if (!is_good) {
LOG(ERROR) << "Localization failed for " << tag; LOG(ERROR) << "Localization failed for " << tag;
return false; return false;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/synchronization/cancellation_flag.h" #include "base/synchronization/cancellation_flag.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/string16.h" #include "base/string16.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include "remoting/host/chromoting_host_context.h" #include "remoting/host/chromoting_host_context.h"
#include "remoting/host/host_status_observer.h" #include "remoting/host/host_status_observer.h"
#include "remoting/host/plugin/host_plugin_utils.h" #include "remoting/host/plugin/host_plugin_utils.h"
#include "remoting/host/ui_strings.h"
#include "third_party/npapi/bindings/npapi.h" #include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npfunctions.h" #include "third_party/npapi/bindings/npfunctions.h"
#include "third_party/npapi/bindings/npruntime.h" #include "third_party/npapi/bindings/npruntime.h"
...@@ -102,6 +104,12 @@ class HostNPScriptObject : public HostStatusObserver { ...@@ -102,6 +104,12 @@ class HostNPScriptObject : public HostStatusObserver {
// Disconnect. No arguments or result. // Disconnect. No arguments or result.
bool Disconnect(const NPVariant* args, uint32_t argCount, NPVariant* result); bool Disconnect(const NPVariant* args, uint32_t argCount, NPVariant* result);
// Localize strings. args are:
// localize_func - a callback function which returns a localized string for
// a given tag name.
// No result.
bool Localize(const NPVariant* args, uint32_t argCount, NPVariant* result);
// Call OnStateChanged handler if there is one. // Call OnStateChanged handler if there is one.
void OnStateChanged(State state); void OnStateChanged(State state);
...@@ -130,13 +138,14 @@ class HostNPScriptObject : public HostStatusObserver { ...@@ -130,13 +138,14 @@ class HostNPScriptObject : public HostStatusObserver {
// Called when the nat traversal policy is updated. // Called when the nat traversal policy is updated.
void OnNatPolicyUpdate(bool nat_traversal_enabled); void OnNatPolicyUpdate(bool nat_traversal_enabled);
void LocalizeStrings(); void LocalizeStrings(NPObject* localize_func);
// Helper function for executing InvokeDefault on an NPObject that performs // Helper function for executing InvokeDefault on an NPObject that performs
// a string->string mapping with one optional substitution parameter. Stores // a string->string mapping with one optional substitution parameter. Stores
// the translation in |result| and returns true on success, or leaves it // the translation in |result| and returns true on success, or leaves it
// unchanged and returns false on failure. // unchanged and returns false on failure.
bool LocalizeString(const char* tag, string16* result); bool LocalizeString(NPObject* localize_func, const char* tag,
string16* result);
// Helper function for executing InvokeDefault on an NPObject, and ignoring // Helper function for executing InvokeDefault on an NPObject, and ignoring
// the return value. // the return value.
...@@ -153,7 +162,6 @@ class HostNPScriptObject : public HostStatusObserver { ...@@ -153,7 +162,6 @@ class HostNPScriptObject : public HostStatusObserver {
std::string access_code_; std::string access_code_;
std::string client_username_; std::string client_username_;
base::TimeDelta access_code_lifetime_; base::TimeDelta access_code_lifetime_;
ScopedRefNPObject localize_func_;
ScopedRefNPObject log_debug_info_func_; ScopedRefNPObject log_debug_info_func_;
ScopedRefNPObject on_state_changed_func_; ScopedRefNPObject on_state_changed_func_;
base::PlatformThreadId np_thread_id_; base::PlatformThreadId np_thread_id_;
...@@ -167,6 +175,9 @@ class HostNPScriptObject : public HostStatusObserver { ...@@ -167,6 +175,9 @@ class HostNPScriptObject : public HostStatusObserver {
scoped_refptr<ChromotingHost> host_; scoped_refptr<ChromotingHost> host_;
int failed_login_attempts_; int failed_login_attempts_;
UiStrings ui_strings_;
base::Lock ui_strings_lock_;
base::WaitableEvent disconnected_event_; base::WaitableEvent disconnected_event_;
scoped_ptr<policy_hack::NatPolicy> nat_policy_; scoped_ptr<policy_hack::NatPolicy> nat_policy_;
......
...@@ -240,7 +240,7 @@ remoting.tryShare = function() { ...@@ -240,7 +240,7 @@ remoting.tryShare = function() {
div.appendChild(plugin); div.appendChild(plugin);
plugin.onStateChanged = onStateChanged_; plugin.onStateChanged = onStateChanged_;
plugin.logDebugInfo = debugInfoCallback_; plugin.logDebugInfo = debugInfoCallback_;
plugin.localizeString = chrome.i18n.getMessage; plugin.localize(chrome.i18n.getMessage);
plugin.connect(getEmail(), plugin.connect(getEmail(),
'oauth2:' + remoting.oauth2.getAccessToken()); 'oauth2:' + remoting.oauth2.getAccessToken());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment