Commit d600e2d2 authored by jamiewalch@google.com's avatar jamiewalch@google.com

Host process i18n and Linux implementation.

BUG=None
TEST=Manual

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96972 0039d316-1c4b-4281-b951-d872f2087c98
parent 0999cb0a
......@@ -493,6 +493,11 @@ void ChromotingHost::LocalLoginSucceeded(
// Immediately add the connection and start the session.
recorder_->AddConnection(connection);
recorder_->Start();
// Notify observers that there is at least one authenticated client.
for (StatusObserverList::iterator it = status_observers_.begin();
it != status_observers_.end(); ++it) {
(*it)->OnClientAuthenticated(connection);
}
// TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect,
// including closing the connection on failure of a critical operation.
EnableCurtainMode(true);
......@@ -503,12 +508,6 @@ void ChromotingHost::LocalLoginSucceeded(
username.replace(pos, std::string::npos, "");
desktop_environment_->OnConnect(username);
}
// Notify observers that there is at least one authenticated client.
for (StatusObserverList::iterator it = status_observers_.begin();
it != status_observers_.end(); ++it) {
(*it)->OnClientAuthenticated(connection);
}
}
void ChromotingHost::LocalLoginFailed(
......
......@@ -15,6 +15,7 @@
#include "remoting/host/client_session.h"
#include "remoting/host/desktop_environment.h"
#include "remoting/host/host_status_observer.h"
#include "remoting/host/ui_strings.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/signal_strategy.h"
#include "remoting/protocol/session_manager.h"
......@@ -144,6 +145,8 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
// is ignored.
void PauseSession(bool pause);
UiStrings* ui_strings() { return &ui_strings_; }
private:
friend class base::RefCountedThreadSafe<ChromotingHost>;
friend class ChromotingHostTest;
......@@ -239,6 +242,8 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
// shutdown. Used only while |state_| is set to kStopping.
std::vector<Task*> shutdown_tasks_;
UiStrings ui_strings_;
DISALLOW_COPY_AND_ASSIGN(ChromotingHost);
};
......
......@@ -4,13 +4,14 @@
#include "remoting/host/continue_window.h"
namespace remoting {
// TODO(jamiewalch): Remove this file once all platforms pick up the
// localized versions from ui_strings.h
namespace remoting {
const char ContinueWindow::kTitle[] = "Remoting";
const char ContinueWindow::kMessage[] =
"You are currently sharing this machine with another user. "
"Please confirm that you want to continue sharing.";
const char ContinueWindow::kDefaultButtonText[] = "Continue";
const char ContinueWindow::kCancelButtonText[] = "Stop";
}
......@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "remoting/host/chromoting_host.h"
#include "remoting/host/ui_strings.h"
#include "ui/base/gtk/gtk_signal.h"
namespace remoting {
......@@ -24,7 +25,7 @@ class ContinueWindowLinux : public remoting::ContinueWindow {
private:
CHROMEGTK_CALLBACK_1(ContinueWindowLinux, void, OnResponse, int);
void CreateWindow();
void CreateWindow(UiStrings* ui_strings);
ChromotingHost* host_;
GtkWidget* continue_window_;
......@@ -40,15 +41,15 @@ ContinueWindowLinux::ContinueWindowLinux()
ContinueWindowLinux::~ContinueWindowLinux() {
}
void ContinueWindowLinux::CreateWindow() {
void ContinueWindowLinux::CreateWindow(UiStrings* ui_strings) {
if (continue_window_) return;
continue_window_ = gtk_dialog_new_with_buttons(
kTitle,
ui_strings->product_name.c_str(),
NULL,
static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
kCancelButtonText, GTK_RESPONSE_CANCEL,
kDefaultButtonText, GTK_RESPONSE_OK,
ui_strings->stop_sharing_button_text.c_str(), GTK_RESPONSE_CANCEL,
ui_strings->continue_button_text.c_str(), GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response(GTK_DIALOG(continue_window_),
......@@ -65,7 +66,7 @@ void ContinueWindowLinux::CreateWindow() {
GtkWidget* content_area =
gtk_dialog_get_content_area(GTK_DIALOG(continue_window_));
GtkWidget* text_label = gtk_label_new(kMessage);
GtkWidget* text_label = gtk_label_new(ui_strings->continue_prompt.c_str());
gtk_label_set_line_wrap(GTK_LABEL(text_label), TRUE);
// TODO(lambroslambrou): Fix magic numbers, as in disconnect_window_linux.cc.
gtk_misc_set_padding(GTK_MISC(text_label), 12, 12);
......@@ -76,7 +77,7 @@ void ContinueWindowLinux::CreateWindow() {
void ContinueWindowLinux::Show(remoting::ChromotingHost* host) {
host_ = host;
CreateWindow();
CreateWindow(host->ui_strings());
gtk_window_set_urgency_hint(GTK_WINDOW(continue_window_), TRUE);
gtk_window_present(GTK_WINDOW(continue_window_));
}
......
......@@ -4,8 +4,10 @@
#include "remoting/host/disconnect_window.h"
// TODO(jamiewalch): Remove this file once all platforms pick up the
// localized versions from ui_strings.h
namespace remoting {
// TODO(garykac): These strings should be localized.
const char DisconnectWindow::kTitle[] = "Remoting";
const char DisconnectWindow::kSharingWith[] = "Sharing with: ";
const char DisconnectWindow::kDisconnectButton[] = "Disconnect";
......
......@@ -24,6 +24,9 @@ class DisconnectWindow {
static const char kDisconnectKeysWin[];
// Show the disconnect window allowing the user to shut down |host|.
// TODO(jamiewalch): Once all platforms are using localized strings,
// remove |username| from this signature (it will be substituted as
// appropriate at the localization stage).
virtual void Show(ChromotingHost* host, const std::string& username) = 0;
// Hide the disconnect window.
......
......@@ -9,8 +9,19 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "remoting/host/chromoting_host.h"
#include "remoting/host/ui_strings.h"
#include "ui/base/gtk/gtk_signal.h"
namespace {
// The width in pixels at which the message will wrap. Given that the message
// contains an un-splittable email address, it's unlikely that a fixed width
// is going to look aesthetically pleasing in all languages.
// TODO(jamiewalch): Replace this with a layout that only uses a single line,
// and which is docked at the top or bottom of the host screen, as in our
// UI mocks.
const int kMessageWidth = 300;
}
namespace remoting {
class DisconnectWindowLinux : public DisconnectWindow {
......@@ -25,11 +36,11 @@ class DisconnectWindowLinux : public DisconnectWindow {
private:
CHROMEGTK_CALLBACK_1(DisconnectWindowLinux, void, OnResponse, int);
void CreateWindow();
void CreateWindow(UiStrings* ui_strings);
ChromotingHost* host_;
GtkWidget* disconnect_window_;
GtkWidget* user_label_;
GtkWidget* message_;
DISALLOW_COPY_AND_ASSIGN(DisconnectWindowLinux);
};
......@@ -42,16 +53,14 @@ DisconnectWindowLinux::DisconnectWindowLinux()
DisconnectWindowLinux::~DisconnectWindowLinux() {
}
void DisconnectWindowLinux::CreateWindow() {
void DisconnectWindowLinux::CreateWindow(UiStrings* ui_strings) {
if (disconnect_window_) return;
std::string disconnect_button(kDisconnectButton);
disconnect_button += kDisconnectKeysLinux;
disconnect_window_ = gtk_dialog_new_with_buttons(
kTitle,
ui_strings->product_name.c_str(),
NULL,
GTK_DIALOG_NO_SEPARATOR,
disconnect_button.c_str(), GTK_RESPONSE_OK,
ui_strings->disconnect_button_text_plus_shortcut.c_str(), GTK_RESPONSE_OK,
NULL);
GtkWindow* window = GTK_WINDOW(disconnect_window_);
......@@ -69,27 +78,27 @@ void DisconnectWindowLinux::CreateWindow() {
GtkWidget* content_area =
gtk_dialog_get_content_area(GTK_DIALOG(disconnect_window_));
GtkWidget* username_row = gtk_hbox_new(FALSE, 0);
GtkWidget* message_row = gtk_hbox_new(FALSE, 0);
// TODO(lambroslambrou): Replace the magic number with an appropriate
// constant from a header file (such as chrome/browser/ui/gtk/gtk_util.h
// but check_deps disallows its #inclusion here).
gtk_container_set_border_width(GTK_CONTAINER(username_row), 12);
gtk_container_add(GTK_CONTAINER(content_area), username_row);
GtkWidget* share_label = gtk_label_new(kSharingWith);
gtk_container_add(GTK_CONTAINER(username_row), share_label);
gtk_container_set_border_width(GTK_CONTAINER(message_row), 12);
gtk_container_add(GTK_CONTAINER(content_area), message_row);
user_label_ = gtk_label_new(NULL);
gtk_container_add(GTK_CONTAINER(username_row), user_label_);
message_ = gtk_label_new(NULL);
gtk_widget_set_size_request(message_, kMessageWidth, -1);
gtk_label_set_line_wrap(GTK_LABEL(message_), true);
gtk_container_add(GTK_CONTAINER(message_row), message_);
gtk_widget_show_all(content_area);
}
void DisconnectWindowLinux::Show(ChromotingHost* host,
const std::string& username) {
const std::string& /* unused */) {
host_ = host;
CreateWindow();
gtk_label_set_text(GTK_LABEL(user_label_), username.c_str());
CreateWindow(host->ui_strings());
gtk_label_set_text(GTK_LABEL(message_),
host->ui_strings()->disconnect_message.c_str());
gtk_window_present(GTK_WINDOW(disconnect_window_));
}
......
......@@ -40,4 +40,21 @@ NPObject* ObjectFromNPVariant(const NPVariant& variant) {
return NPVARIANT_TO_OBJECT(variant);
}
ScopedRefNPObject::ScopedRefNPObject() : object_(NULL) { }
ScopedRefNPObject::~ScopedRefNPObject() {
*this = NULL;
}
ScopedRefNPObject& ScopedRefNPObject::operator=(NPObject* object) {
if (object) {
g_npnetscape_funcs->retainobject(object);
}
if (object_) {
g_npnetscape_funcs->releaseobject(object_);
}
object_ = object;
return *this;
}
} // namespace remoting
......@@ -30,6 +30,25 @@ NPVariant NPVariantFromString(const std::string& val);
// Convert an NPVariant into an NSPObject.
NPObject* ObjectFromNPVariant(const NPVariant& variant);
// Scoped reference pointer for NPObjects. All objects using this class
// must be owned by g_npnetscape_funcs.
class ScopedRefNPObject {
public:
ScopedRefNPObject();
~ScopedRefNPObject();
// Release the held reference and replace it with |object|, incrementing
// its reference count.
ScopedRefNPObject& operator=(NPObject* object);
NPObject* get() { return object_; }
private:
NPObject* object_;
DISALLOW_COPY_AND_ASSIGN(ScopedRefNPObject);
};
} // namespace remoting
#endif // REMOTING_HOST_PLUGIN_HOST_PLUGIN_UTILS_H_
......@@ -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) {
......
......@@ -17,6 +17,7 @@
#include "base/time.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/host_status_observer.h"
#include "remoting/host/plugin/host_plugin_utils.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npfunctions.h"
#include "third_party/npapi/bindings/npruntime.h"
......@@ -79,6 +80,7 @@ class HostNPScriptObject : public HostStatusObserver {
// base/logging.h.
static bool LogToUI(int severity, const char* file, int line,
size_t message_start, const std::string& str);
private:
enum State {
kDisconnected,
......@@ -125,6 +127,15 @@ class HostNPScriptObject : public HostStatusObserver {
// Called when the nat traversal policy is updated.
void OnNatPolicyUpdate(bool nat_traversal_enabled);
void LocalizeStrings();
// Helper function for executing InvokeDefault on an NPObject that performs
// a string->string mapping with one optional substitution parameter. Stores
// the translation in |result| and returns true on success, or leaves it
// unchanged and returns false on failure.
bool LocalizeString(const char* tag, const char* substitution,
std::string* result);
// Helper function for executing InvokeDefault on an NPObject, and ignoring
// the return value.
bool InvokeAndIgnoreResult(NPObject* func,
......@@ -147,8 +158,9 @@ class HostNPScriptObject : public HostStatusObserver {
std::string access_code_;
std::string client_username_;
base::TimeDelta access_code_lifetime_;
NPObject* log_debug_info_func_;
NPObject* on_state_changed_func_;
ScopedRefNPObject localize_func_;
ScopedRefNPObject log_debug_info_func_;
ScopedRefNPObject on_state_changed_func_;
base::PlatformThreadId np_thread_id_;
scoped_ptr<RegisterSupportHostRequest> register_request_;
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/ui_strings.h"
namespace remoting {
UiStrings::UiStrings() :
direction(LTR),
product_name("Chromoting"),
// The default string doesn't include the user name, so this will be
// missing for remoting_simple_host
disconnect_message("Your desktop is currently being shared."),
disconnect_button_text("Disconnect"),
// This is the wrong shortcut on Mac OS X, but remoting_simple_host
// doesn't have a bundle (and hence no dialog) on that platform and
// the web-app will provide the correct localization for this string.
disconnect_button_shortcut("Ctrl+Alt+Esc"),
continue_prompt(
"You are currently sharing this machine with another user. "
"Please confirm that you want to continue sharing."),
continue_button_text("Continue"),
stop_sharing_button_text("Stop Sharing") {
}
UiStrings::~UiStrings() { }
}
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_HOST_UI_STRINGS_H_
#define REMOTING_HOST_UI_STRINGS_H_
#include <string>
// This struct contains localized strings to be displayed in host dialogs.
// For the web-app, these are loaded from the appropriate messages.json
// file when the plugin is created. For remoting_simple_host, they are
// left set to the default (English) values.
//
// Since we don't anticipate having a significant host-side UI presented
// in this way, a namespace containing all available strings should be
// a reasonable way to implement this.
namespace remoting {
struct UiStrings {
UiStrings();
~UiStrings();
// The direction (left-to-right or right-to-left) for the current language.
enum Direction { RTL, LTR };
Direction direction;
// The product name (Chromoting or Chrome Remote Desktop).
std::string product_name;
// The message in the disconnect dialog.
std::string disconnect_message;
// The label on the disconnect dialog button, without the keyboard shortcut.
std::string disconnect_button_text;
// The label on the disconnect dialog button, with the keyboard shortcut.
std::string disconnect_button_text_plus_shortcut;
// The keyboard shortcut for disconnecting clients.
std::string disconnect_button_shortcut;
// The confirmation prompt displayed by the continue window.
std::string continue_prompt;
// The label on the 'Continue' button of the continue window.
std::string continue_button_text;
// The label on the 'Stop Sharing' button of the continue window.
std::string stop_sharing_button_text;
};
}
#endif // REMOTING_HOST_UI_STRINGS_H_
......@@ -422,6 +422,8 @@
'host/screen_recorder.h',
'host/support_access_verifier.cc',
'host/support_access_verifier.h',
'host/ui_strings.cc',
'host/ui_strings.h',
'host/user_authenticator.h',
'host/user_authenticator_linux.cc',
'host/user_authenticator_mac.cc',
......
......@@ -23,6 +23,10 @@
"message": "Continue",
"description": "Label for the continue button on the pre-authorization page"
},
"continuePrompt": {
"message": "You are currently sharing this machine with another user. Please confirm that you want to continue sharing.",
"description": "Message displayed when the session has lasted longer than five minutes, explaining that the host computer is being shared and asking whether or not the user wants to continue sharing it"
},
"debugButton": {
"message": "Debug Log",
"description": "Label for the debug log button"
......@@ -39,6 +43,18 @@
"message": "Disconnect",
"description": "Label for the disconnect button"
},
"disconnectButtonPlusShortcutLinux": {
"message": "Disconnect (Ctrl+Alt+Esc)",
"description": "Shortcut for the disconnect action on Linux"
},
"disconnectButtonPlusShortcutMacOSX": {
"message": "Disconnect (⌥⌃⎋)",
"description": "Shortcut for the disconnect action on Mac OS X. This probably doesn't need localizing since it is common practise on this platform to refer to the keys involved using symbols."
},
"disconnectButtonPlusShortcutWindows": {
"message": "Disconnect (Ctrl+Alt+Esc)",
"description": "Shortcut for the disconnect action on Windows"
},
"errorGeneric": {
"message": "An error occurred.",
"description": "Generic error message"
......
......@@ -3,11 +3,6 @@
* found in the LICENSE file.
*/
/**
* Localize the document by replacing innerText of nodes with an i18n-content
* attribute with the corresponding localized string.
*/
var l10n = l10n || {};
/**
......
......@@ -229,6 +229,7 @@ remoting.tryShare = function() {
div.appendChild(plugin);
plugin.onStateChanged = onStateChanged_;
plugin.logDebugInfo = debugInfoCallback_;
plugin.localizeString = chrome.i18n.getMessage;
plugin.connect(getEmail(),
'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