From 40f42682afc1bd543f9fde452f7f1f20fcf55492 Mon Sep 17 00:00:00 2001 From: "alexeypa@chromium.org" Date: Fri, 26 Jul 2013 22:55:00 +0000 Subject: Localized Chromoting Host on Mac and Linux. This CL implements generation of localizable strings from remoting_strings.grd file. Depending on the platform the localized resources are placed to: - Mac: localized .string and .pak resources are added to each application bundle under 'Resources/.lproj' - Linux: localized .pak files are placed under 'remoting_locales' directory next to the binary locading them. - Windows: .rc resources are generated from .jinja2 templates and embedded into a relevant binary. Chrome l10n and i18n APIs are used to retrieve the current locale and RTL flag (Mac & Linux). The it2me plugin sets the locale to match the locale of the browser. Collateral changes: - UiString is not used any more. - Increased width of disconnect window message on Mac. - The host plugin version is correctly reported on Mac. - Dialogs use RTL templates in case of RTL languages. No more updating the templates dynamically (Windows). - remoting_unittests.ResourcesTest row runs on Mac, LInux and Windows. - '@' is used for variable substitutions by remoting_localize.py. - HOST_PLUGIN_MIME_TYPE is defined in one place now. - Deleted unused commong_resources.grd. Mac installer and preference panel are not localized yet. BUG=155204 Review URL: https://chromiumcodereview.appspot.com/19803010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213997 0039d316-1c4b-4281-b951-d872f2087c98 --- remoting/base/resources.cc | 35 --- remoting/base/resources.h | 8 +- remoting/base/resources_linux.cc | 44 ++++ remoting/base/resources_mac.mm | 43 ++++ remoting/base/resources_unittest.cc | 44 ++-- remoting/base/resources_win.cc | 17 ++ remoting/branding_Chrome | 5 - remoting/branding_Chromium | 5 - remoting/host/basic_desktop_environment.cc | 6 +- remoting/host/basic_desktop_environment.h | 11 +- remoting/host/continue_window.cc | 3 +- remoting/host/continue_window.h | 8 +- remoting/host/continue_window_gtk.cc | 22 +- remoting/host/continue_window_mac.mm | 36 ++- remoting/host/continue_window_win.cc | 12 +- remoting/host/desktop_process_main.cc | 8 +- remoting/host/disconnect_window_gtk.cc | 29 ++- remoting/host/disconnect_window_mac.h | 10 +- remoting/host/disconnect_window_mac.mm | 43 ++-- remoting/host/disconnect_window_win.cc | 49 +--- remoting/host/host_main.cc | 6 + remoting/host/host_window.h | 7 +- .../uninstaller/remoting_uninstaller-Info.plist | 4 - .../remoting_uninstaller-InfoPlist.strings.jinja2 | 2 + remoting/host/it2me_desktop_environment.cc | 16 +- remoting/host/it2me_desktop_environment.h | 6 +- remoting/host/mac/me2me_preference_pane-Info.plist | 6 - .../me2me_preference_pane-InfoPlist.strings.jinja2 | 3 + remoting/host/me2me_desktop_environment.cc | 10 +- remoting/host/me2me_desktop_environment.h | 4 +- remoting/host/plugin/constants.h | 25 --- remoting/host/plugin/host_plugin-Info.plist | 8 +- .../plugin/host_plugin-InfoPlist.strings.jinja2 | 3 + remoting/host/plugin/host_plugin.cc | 57 ++++- remoting/host/plugin/host_script_object.cc | 39 ++-- remoting/host/plugin/host_script_object.h | 4 - remoting/host/remoting_me2me_host-Info.plist | 2 - .../remoting_me2me_host-InfoPlist.strings.jinja2 | 1 + remoting/host/remoting_me2me_host.cc | 7 +- remoting/host/ui_strings.cc | 34 --- remoting/host/ui_strings.h | 50 ----- remoting/host/win/core.rc.jinja2 | 6 +- remoting/host/win/session_desktop_environment.cc | 5 +- remoting/host/win/session_desktop_environment.h | 3 - remoting/host/win/version.rc.jinja2 | 3 +- remoting/remoting.gyp | 249 ++++++++++++++++----- remoting/resources/common_resources.grd | 18 -- remoting/resources/remoting_strings.grd | 113 ++++++---- remoting/resources/resource_ids | 3 - remoting/tools/build/remoting_copy_locales.py | 160 +++++++++++++ remoting/tools/build/remoting_localize.py | 14 +- remoting/tools/verify_resources.py | 4 +- remoting/unittests-Info.plist | 24 ++ remoting/webapp/build-webapp.py | 30 +-- 54 files changed, 774 insertions(+), 590 deletions(-) delete mode 100644 remoting/base/resources.cc create mode 100644 remoting/base/resources_linux.cc create mode 100644 remoting/base/resources_mac.mm create mode 100644 remoting/base/resources_win.cc create mode 100644 remoting/host/installer/mac/uninstaller/remoting_uninstaller-InfoPlist.strings.jinja2 create mode 100644 remoting/host/mac/me2me_preference_pane-InfoPlist.strings.jinja2 delete mode 100644 remoting/host/plugin/constants.h create mode 100644 remoting/host/plugin/host_plugin-InfoPlist.strings.jinja2 create mode 100644 remoting/host/remoting_me2me_host-InfoPlist.strings.jinja2 delete mode 100644 remoting/host/ui_strings.cc delete mode 100644 remoting/host/ui_strings.h delete mode 100644 remoting/resources/common_resources.grd create mode 100755 remoting/tools/build/remoting_copy_locales.py create mode 100644 remoting/unittests-Info.plist diff --git a/remoting/base/resources.cc b/remoting/base/resources.cc deleted file mode 100644 index 933be87..0000000 --- a/remoting/base/resources.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012 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/base/resources.h" - -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/ui_base_paths.h" - -namespace remoting { - -namespace { -const char kLocaleResourcesDirName[] = "remoting_locales"; -const char kCommonResourcesFileName[] = "chrome_remote_desktop.pak"; -} // namespace - -// Loads chromoting resources. -bool LoadResources(const std::string& pref_locale) { - base::FilePath path; - if (!PathService::Get(base::DIR_MODULE, &path)) - return false; - - PathService::Override(ui::DIR_LOCALES, - path.AppendASCII(kLocaleResourcesDirName)); - ui::ResourceBundle::InitSharedInstanceLocaleOnly(pref_locale, NULL); - - ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( - path.AppendASCII(kCommonResourcesFileName), ui::SCALE_FACTOR_100P); - - return true; -} - -} // namespace remoting diff --git a/remoting/base/resources.h b/remoting/base/resources.h index b08eb8d..371c533 100644 --- a/remoting/base/resources.h +++ b/remoting/base/resources.h @@ -9,11 +9,15 @@ namespace remoting { -// Loads chromoting resources. Returns false in case of a failure. |pref_locale| +// Loads (or reloads) Chromoting resources for the given locale. |pref_locale| // is passed to l10n_util::GetApplicationLocale(), so the default system locale -// is used if |pref_locale| is empty. +// is used if |pref_locale| is empty. Returns |true| if the shared resource +// bundle has been initialized. bool LoadResources(const std::string& pref_locale); +// Unloads Chromoting resources. +void UnloadResources(); + } // namespace remoting #endif // REMOTING_HOST_BASE_RESOURCES_H_ diff --git a/remoting/base/resources_linux.cc b/remoting/base/resources_linux.cc new file mode 100644 index 0000000..af530e8 --- /dev/null +++ b/remoting/base/resources_linux.cc @@ -0,0 +1,44 @@ +// Copyright 2013 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/base/resources.h" + +#include + +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_paths.h" + +namespace remoting { + +namespace { +const char kLocaleResourcesDirName[] = "remoting_locales"; +} // namespace + +bool LoadResources(const std::string& pref_locale) { + if (ui::ResourceBundle::HasSharedInstance()) { + ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(pref_locale); + } else { + // Retrive the path to the module containing this function. + Dl_info info; + CHECK(dladdr(reinterpret_cast(&LoadResources), &info) != 0); + + // Point DIR_LOCALES to 'remoting_locales'. + base::FilePath path = base::FilePath(info.dli_fname).DirName(); + PathService::Override(ui::DIR_LOCALES, + path.AppendASCII(kLocaleResourcesDirName)); + + ui::ResourceBundle::InitSharedInstanceLocaleOnly(pref_locale, NULL); + } + + return true; +} + +void UnloadResources() { + ui::ResourceBundle::CleanupSharedInstance(); +} + +} // namespace remoting diff --git a/remoting/base/resources_mac.mm b/remoting/base/resources_mac.mm new file mode 100644 index 0000000..d1ce4af --- /dev/null +++ b/remoting/base/resources_mac.mm @@ -0,0 +1,43 @@ +// Copyright 2013 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. + +#import + +#include "remoting/base/resources.h" +#include "base/mac/bundle_locations.h" +#include "ui/base/l10n/l10n_util_mac.h" +#include "ui/base/resource/resource_bundle.h" + +// A dummy class used to locate the host plugin's bundle. +@interface NSBundleLocator : NSObject +@end + +@implementation NSBundleLocator +@end + +namespace remoting { + +bool LoadResources(const std::string& pref_locale) { + if (ui::ResourceBundle::HasSharedInstance()) { + ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(pref_locale); + } else { + // Use the plugin's bundle instead of the hosting app bundle. + base::mac::SetOverrideFrameworkBundle( + [NSBundle bundleForClass:[NSBundleLocator class]]); + + // Override the locale with the value from Cocoa. + if (pref_locale.empty()) + l10n_util::OverrideLocaleWithCocoaLocale(); + + ui::ResourceBundle::InitSharedInstanceLocaleOnly(pref_locale, NULL); + } + + return true; +} + +void UnloadResources() { + ui::ResourceBundle::CleanupSharedInstance(); +} + +} // namespace remoting diff --git a/remoting/base/resources_unittest.cc b/remoting/base/resources_unittest.cc index 6d69cee..b02a12b 100644 --- a/remoting/base/resources_unittest.cc +++ b/remoting/base/resources_unittest.cc @@ -4,52 +4,46 @@ #include "remoting/base/resources.h" -#include "remoting/base/common_resources.h" #include "remoting/base/string_resources.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" #include "testing/gtest/include/gtest/gtest.h" namespace remoting { -// TODO(sergeyu): Resources loading doesn't work yet on OSX. Fix it and enable -// the test. -#if !defined(OS_MACOSX) -#define MAYBE_ProductName ProductName -#define MAYBE_ProductLogo ProductLogo -#else // !defined(OS_MACOSX) -#define MAYBE_ProductName DISABLED_ProductName -#define MAYBE_ProductLogo DISABLED_ProductLogo -#endif // defined(OS_MACOSX) - class ResourcesTest : public testing::Test { protected: + ResourcesTest(): resources_available_(false) { + } + virtual void SetUp() OVERRIDE { - ASSERT_TRUE(LoadResources("en-US")); + resources_available_ = LoadResources("en-US"); } virtual void TearDown() OVERRIDE { - ui::ResourceBundle::CleanupSharedInstance(); + UnloadResources(); } + + bool resources_available_; }; -TEST_F(ResourcesTest, MAYBE_ProductName) { +TEST_F(ResourcesTest, ProductName) { #if defined(GOOGLE_CHROME_BUILD) std::string expected_product_name = "Chrome Remote Desktop"; #else // defined(GOOGLE_CHROME_BUILD) std::string expected_product_name = "Chromoting"; #endif // !defined(GOOGLE_CHROME_BUILD) - EXPECT_EQ(expected_product_name, - l10n_util::GetStringUTF8(IDR_PRODUCT_NAME)); -} -TEST_F(ResourcesTest, MAYBE_ProductLogo) { - gfx::Image logo16 = ui::ResourceBundle::GetSharedInstance().GetImageNamed( - IDR_PRODUCT_LOGO_16); - EXPECT_FALSE(logo16.IsEmpty()); - gfx::Image logo32 = ui::ResourceBundle::GetSharedInstance().GetImageNamed( - IDR_PRODUCT_LOGO_32); - EXPECT_FALSE(logo32.IsEmpty()); + // Chrome-style i18n is not used on Windows. +#if defined(OS_WIN) + EXPECT_FALSE(resources_available_); +#else + EXPECT_TRUE(resources_available_); +#endif + + if (resources_available_) { + EXPECT_EQ(expected_product_name, + l10n_util::GetStringUTF8(IDR_PRODUCT_NAME)); + } } } // namespace remoting diff --git a/remoting/base/resources_win.cc b/remoting/base/resources_win.cc new file mode 100644 index 0000000..e4d9efa --- /dev/null +++ b/remoting/base/resources_win.cc @@ -0,0 +1,17 @@ +// Copyright 2013 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/base/resources.h" + +namespace remoting { + +bool LoadResources(const std::string& pref_locale) { + // Do nothing since .pak files are not used on Windows. + return false; +} + +void UnloadResources() { +} + +} // namespace remoting diff --git a/remoting/branding_Chrome b/remoting/branding_Chrome index 49e1e88..8e6acc8 100644 --- a/remoting/branding_Chrome +++ b/remoting/branding_Chrome @@ -1,6 +1,4 @@ -COPYRIGHT=Copyright 2013 Google Inc. All Rights Reserved. HOST_PLUGIN_FILE_NAME=Chrome Remote Desktop Host -HOST_PLUGIN_DESCRIPTION=Allow another user to access your computer securely over the Internet. DAEMON_FILE_NAME=Chrome Remote Desktop Host Service MAC_BUNDLE_ID=com.google.Chrome MAC_CREATOR=rimZ @@ -8,7 +6,4 @@ MAC_HOST_BUNDLE_ID=com.google.chrome_remote_desktop.remoting_me2me_host MAC_UNINSTALLER_NAME=Chrome Remote Desktop Host Uninstaller MAC_UNINSTALLER_BUNDLE_PREFIX=com.google.pkg MAC_UNINSTALLER_BUNDLE_ID=com.google.chromeremotedesktop.host_uninstaller -MAC_UNINSTALLER_BUNDLE_NAME=Chrome Remote Desktop Host Uninstaller MAC_PREFPANE_BUNDLE_ID=com.google.chromeremotedesktop.preferences -MAC_PREFPANE_BUNDLE_NAME=Chrome Remote Desktop Host Preferences -MAC_PREFPANE_ICON_LABEL=Chrome Remote Desktop Host diff --git a/remoting/branding_Chromium b/remoting/branding_Chromium index 22f3621..1a6a94a 100644 --- a/remoting/branding_Chromium +++ b/remoting/branding_Chromium @@ -1,6 +1,4 @@ -COPYRIGHT=Copyright 2013 The Chromium Authors. All Rights Reserved. HOST_PLUGIN_FILE_NAME=Chromoting Host -HOST_PLUGIN_DESCRIPTION=Allow another user to access your computer securely over the Internet. DAEMON_FILE_NAME=Chromoting Host Service MAC_BUNDLE_ID=org.chromium.Chromium MAC_CREATOR=Cr24 @@ -8,7 +6,4 @@ MAC_HOST_BUNDLE_ID=org.chromium.chromoting.remoting_me2me_host MAC_UNINSTALLER_NAME=Chromoting Host Uninstaller MAC_UNINSTALLER_BUNDLE_PREFIX=org.chromium.pkg MAC_UNINSTALLER_BUNDLE_ID=org.chromium.remoting.host_uninstaller -MAC_UNINSTALLER_BUNDLE_NAME=Chromoting Host Uninstaller MAC_PREFPANE_BUNDLE_ID=org.chromium.remoting.preferences -MAC_PREFPANE_BUNDLE_NAME=Chromoting Host Preferences -MAC_PREFPANE_ICON_LABEL=Chromoting Host diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc index e6e2db3..7698ca8 100644 --- a/remoting/host/basic_desktop_environment.cc +++ b/remoting/host/basic_desktop_environment.cc @@ -66,12 +66,10 @@ BasicDesktopEnvironment::BasicDesktopEnvironment( BasicDesktopEnvironmentFactory::BasicDesktopEnvironmentFactory( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, - scoped_refptr ui_task_runner, - const UiStrings& ui_strings) + scoped_refptr ui_task_runner) : caller_task_runner_(caller_task_runner), input_task_runner_(input_task_runner), - ui_task_runner_(ui_task_runner), - ui_strings_(ui_strings) { + ui_task_runner_(ui_task_runner) { } BasicDesktopEnvironmentFactory::~BasicDesktopEnvironmentFactory() { diff --git a/remoting/host/basic_desktop_environment.h b/remoting/host/basic_desktop_environment.h index 10429d1..dbc9822 100644 --- a/remoting/host/basic_desktop_environment.h +++ b/remoting/host/basic_desktop_environment.h @@ -12,7 +12,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "remoting/host/desktop_environment.h" -#include "remoting/host/ui_strings.h" namespace remoting { @@ -33,8 +32,6 @@ class BasicDesktopEnvironment : public DesktopEnvironment { protected: friend class BasicDesktopEnvironmentFactory; - // |ui_strings| are hosted by the BasicDesktopEnvironmentFactory instance that - // created |this|. |ui_strings| must outlive this object. BasicDesktopEnvironment( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, @@ -72,8 +69,7 @@ class BasicDesktopEnvironmentFactory : public DesktopEnvironmentFactory { BasicDesktopEnvironmentFactory( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, - scoped_refptr ui_task_runner, - const UiStrings& ui_strings); + scoped_refptr ui_task_runner); virtual ~BasicDesktopEnvironmentFactory(); // DesktopEnvironmentFactory implementation. @@ -92,8 +88,6 @@ class BasicDesktopEnvironmentFactory : public DesktopEnvironmentFactory { return ui_task_runner_; } - const UiStrings& ui_strings() const { return ui_strings_; } - private: // Task runner on which methods of DesktopEnvironmentFactory interface should // be called. @@ -105,9 +99,6 @@ class BasicDesktopEnvironmentFactory : public DesktopEnvironmentFactory { // Used to run UI code. scoped_refptr ui_task_runner_; - // Contains a copy of the localized UI strings. - const UiStrings ui_strings_; - DISALLOW_COPY_AND_ASSIGN(BasicDesktopEnvironmentFactory); }; diff --git a/remoting/host/continue_window.cc b/remoting/host/continue_window.cc index abea5cf..35a7f90 100644 --- a/remoting/host/continue_window.cc +++ b/remoting/host/continue_window.cc @@ -57,8 +57,7 @@ void ContinueWindow::DisconnectSession() { client_session_control_->DisconnectSession(); } -ContinueWindow::ContinueWindow(const UiStrings& ui_strings) - : ui_strings_(ui_strings) { +ContinueWindow::ContinueWindow() { } void ContinueWindow::OnSessionExpired() { diff --git a/remoting/host/continue_window.h b/remoting/host/continue_window.h index fb5db00..4a48e16 100644 --- a/remoting/host/continue_window.h +++ b/remoting/host/continue_window.h @@ -9,7 +9,6 @@ #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "remoting/host/host_window.h" -#include "remoting/host/ui_strings.h" namespace remoting { @@ -29,14 +28,12 @@ class ContinueWindow : public HostWindow { void DisconnectSession(); protected: - explicit ContinueWindow(const UiStrings& ui_strings); + ContinueWindow(); // Shows and hides the UI. virtual void ShowUi() = 0; virtual void HideUi() = 0; - const UiStrings& ui_strings() const { return ui_strings_; } - private: // Invoked periodically to ask for the local user whether the session should // be continued. @@ -51,9 +48,6 @@ class ContinueWindow : public HostWindow { // Used to ask the local user whether the session should be continued. base::OneShotTimer session_expired_timer_; - // Localized UI strings. - UiStrings ui_strings_; - DISALLOW_COPY_AND_ASSIGN(ContinueWindow); }; diff --git a/remoting/host/continue_window_gtk.cc b/remoting/host/continue_window_gtk.cc index 238b509..66cde62 100644 --- a/remoting/host/continue_window_gtk.cc +++ b/remoting/host/continue_window_gtk.cc @@ -7,14 +7,16 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "remoting/base/string_resources.h" #include "remoting/host/continue_window.h" #include "ui/base/gtk/gtk_signal.h" +#include "ui/base/l10n/l10n_util.h" namespace remoting { class ContinueWindowGtk : public ContinueWindow { public: - explicit ContinueWindowGtk(const UiStrings& ui_strings); + ContinueWindowGtk(); virtual ~ContinueWindowGtk(); protected: @@ -32,9 +34,8 @@ class ContinueWindowGtk : public ContinueWindow { DISALLOW_COPY_AND_ASSIGN(ContinueWindowGtk); }; -ContinueWindowGtk::ContinueWindowGtk(const UiStrings& ui_strings) - : ContinueWindow(ui_strings), - continue_window_(NULL) { +ContinueWindowGtk::ContinueWindowGtk() + : continue_window_(NULL) { } ContinueWindowGtk::~ContinueWindowGtk() { @@ -67,12 +68,12 @@ void ContinueWindowGtk::CreateWindow() { DCHECK(!continue_window_); continue_window_ = gtk_dialog_new_with_buttons( - UTF16ToUTF8(ui_strings().product_name).c_str(), + l10n_util::GetStringUTF8(IDR_PRODUCT_NAME).c_str(), NULL, static_cast(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), - UTF16ToUTF8(ui_strings().stop_sharing_button_text).c_str(), + l10n_util::GetStringUTF8(IDR_STOP_SHARING_BUTTON).c_str(), GTK_RESPONSE_CANCEL, - UTF16ToUTF8(ui_strings().continue_button_text).c_str(), + l10n_util::GetStringUTF8(IDR_CONTINUE_BUTTON).c_str(), GTK_RESPONSE_OK, NULL); @@ -91,7 +92,7 @@ void ContinueWindowGtk::CreateWindow() { gtk_dialog_get_content_area(GTK_DIALOG(continue_window_)); GtkWidget* text_label = - gtk_label_new(UTF16ToUTF8(ui_strings().continue_prompt).c_str()); + gtk_label_new(l10n_util::GetStringUTF8(IDR_CONTINUE_PROMPT).c_str()); gtk_label_set_line_wrap(GTK_LABEL(text_label), TRUE); // TODO(lambroslambrou): Fix magic numbers, as in disconnect_window_gtk.cc. gtk_misc_set_padding(GTK_MISC(text_label), 12, 12); @@ -113,9 +114,8 @@ void ContinueWindowGtk::OnResponse(GtkWidget* dialog, int response_id) { } // static -scoped_ptr HostWindow::CreateContinueWindow( - const UiStrings& ui_strings) { - return scoped_ptr(new ContinueWindowGtk(ui_strings)); +scoped_ptr HostWindow::CreateContinueWindow() { + return scoped_ptr(new ContinueWindowGtk()); } } // namespace remoting diff --git a/remoting/host/continue_window_mac.mm b/remoting/host/continue_window_mac.mm index 5ab2bdb..6c24dee 100644 --- a/remoting/host/continue_window_mac.mm +++ b/remoting/host/continue_window_mac.mm @@ -9,7 +9,9 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" +#include "remoting/base/string_resources.h" #include "remoting/host/continue_window.h" +#include "ui/base/l10n/l10n_util_mac.h" // Handles the ContinueWindow. @interface ContinueWindowMacController : NSObject { @@ -17,11 +19,9 @@ base::scoped_nsobject shades_; base::scoped_nsobject continue_alert_; remoting::ContinueWindow* continue_window_; - const remoting::UiStrings* ui_strings_; } -- (id)initWithUiStrings:(const remoting::UiStrings*)ui_strings - continue_window:(remoting::ContinueWindow*)continue_window; +- (id)initWithWindow:(remoting::ContinueWindow*)continue_window; - (void)show; - (void)hide; - (void)onCancel:(id)sender; @@ -34,7 +34,7 @@ namespace remoting { // Everything important occurs in ContinueWindowMacController. class ContinueWindowMac : public ContinueWindow { public: - explicit ContinueWindowMac(const UiStrings& ui_strings); + ContinueWindowMac(); virtual ~ContinueWindowMac(); protected: @@ -48,8 +48,7 @@ class ContinueWindowMac : public ContinueWindow { DISALLOW_COPY_AND_ASSIGN(ContinueWindowMac); }; -ContinueWindowMac::ContinueWindowMac(const UiStrings& ui_strings) - : ContinueWindow(ui_strings) { +ContinueWindowMac::ContinueWindowMac() { } ContinueWindowMac::~ContinueWindowMac() { @@ -61,8 +60,7 @@ void ContinueWindowMac::ShowUi() { base::mac::ScopedNSAutoreleasePool pool; controller_.reset( - [[ContinueWindowMacController alloc] initWithUiStrings:&ui_strings() - continue_window:this]); + [[ContinueWindowMacController alloc] initWithWindow:this]); [controller_ show]; } @@ -74,20 +72,17 @@ void ContinueWindowMac::HideUi() { } // static -scoped_ptr HostWindow::CreateContinueWindow( - const UiStrings& ui_strings) { - return scoped_ptr(new ContinueWindowMac(ui_strings)); +scoped_ptr HostWindow::CreateContinueWindow() { + return scoped_ptr(new ContinueWindowMac()); } } // namespace remoting @implementation ContinueWindowMacController -- (id)initWithUiStrings:(const remoting::UiStrings*)ui_strings - continue_window:(remoting::ContinueWindow*)continue_window { +- (id)initWithWindow:(remoting::ContinueWindow*)continue_window { if ((self = [super init])) { continue_window_ = continue_window; - ui_strings_ = ui_strings; } return self; } @@ -116,21 +111,18 @@ scoped_ptr HostWindow::CreateContinueWindow( } // Create alert. - NSString* message = base::SysUTF16ToNSString(ui_strings_->continue_prompt); - NSString* continue_button_string = base::SysUTF16ToNSString( - ui_strings_->continue_button_text); - NSString* cancel_button_string = base::SysUTF16ToNSString( - ui_strings_->stop_sharing_button_text); continue_alert_.reset([[NSAlert alloc] init]); - [continue_alert_ setMessageText:message]; + [continue_alert_ setMessageText:l10n_util::GetNSString(IDR_CONTINUE_PROMPT)]; NSButton* continue_button = - [continue_alert_ addButtonWithTitle:continue_button_string]; + [continue_alert_ addButtonWithTitle:l10n_util::GetNSString( + IDR_CONTINUE_BUTTON)]; [continue_button setAction:@selector(onContinue:)]; [continue_button setTarget:self]; NSButton* cancel_button = - [continue_alert_ addButtonWithTitle:cancel_button_string]; + [continue_alert_ addButtonWithTitle:l10n_util::GetNSString( + IDR_STOP_SHARING_BUTTON)]; [cancel_button setAction:@selector(onCancel:)]; [cancel_button setTarget:self]; diff --git a/remoting/host/continue_window_win.cc b/remoting/host/continue_window_win.cc index 0dcf907f0..1b06fd0 100644 --- a/remoting/host/continue_window_win.cc +++ b/remoting/host/continue_window_win.cc @@ -21,7 +21,7 @@ namespace { class ContinueWindowWin : public ContinueWindow { public: - explicit ContinueWindowWin(const UiStrings& ui_strings); + ContinueWindowWin(); virtual ~ContinueWindowWin(); protected: @@ -42,9 +42,8 @@ class ContinueWindowWin : public ContinueWindow { DISALLOW_COPY_AND_ASSIGN(ContinueWindowWin); }; -ContinueWindowWin::ContinueWindowWin(const UiStrings& ui_strings) - : ContinueWindow(ui_strings), - hwnd_(NULL) { +ContinueWindowWin::ContinueWindowWin() + : hwnd_(NULL) { } ContinueWindowWin::~ContinueWindowWin() { @@ -129,9 +128,8 @@ void ContinueWindowWin::EndDialog() { } // namespace // static -scoped_ptr HostWindow::CreateContinueWindow( - const UiStrings& ui_strings) { - return scoped_ptr(new ContinueWindowWin(ui_strings)); +scoped_ptr HostWindow::CreateContinueWindow() { + return scoped_ptr(new ContinueWindowWin()); } } // namespace remoting diff --git a/remoting/host/desktop_process_main.cc b/remoting/host/desktop_process_main.cc index c259e58..294413c 100644 --- a/remoting/host/desktop_process_main.cc +++ b/remoting/host/desktop_process_main.cc @@ -18,7 +18,6 @@ #include "remoting/host/host_main.h" #include "remoting/host/ipc_constants.h" #include "remoting/host/me2me_desktop_environment.h" -#include "remoting/host/ui_strings.h" #include "remoting/host/win/session_desktop_environment.h" namespace remoting { @@ -46,9 +45,6 @@ int DesktopProcessMain() { input_task_runner, channel_name); - // TODO(alexeypa): Localize the UI strings. See http://crbug.com/155204. - UiStrings ui_string; - // Create a platform-dependent environment factory. scoped_ptr desktop_environment_factory; #if defined(OS_WIN) @@ -57,15 +53,13 @@ int DesktopProcessMain() { ui_task_runner, input_task_runner, ui_task_runner, - ui_string, base::Bind(&DesktopProcess::InjectSas, desktop_process.AsWeakPtr()))); #else // !defined(OS_WIN) desktop_environment_factory.reset(new Me2MeDesktopEnvironmentFactory( ui_task_runner, input_task_runner, - ui_task_runner, - ui_string)); + ui_task_runner)); #endif // !defined(OS_WIN) if (!desktop_process.Start(desktop_environment_factory.Pass())) diff --git a/remoting/host/disconnect_window_gtk.cc b/remoting/host/disconnect_window_gtk.cc index f5dacf2..06d417a 100644 --- a/remoting/host/disconnect_window_gtk.cc +++ b/remoting/host/disconnect_window_gtk.cc @@ -9,10 +9,11 @@ #include "base/logging.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "remoting/base/string_resources.h" #include "remoting/host/client_session_control.h" #include "remoting/host/host_window.h" -#include "remoting/host/ui_strings.h" #include "ui/base/gtk/gtk_signal.h" +#include "ui/base/l10n/l10n_util.h" namespace remoting { @@ -20,7 +21,7 @@ namespace { class DisconnectWindowGtk : public HostWindow { public: - explicit DisconnectWindowGtk(const UiStrings& ui_strings); + DisconnectWindowGtk(); virtual ~DisconnectWindowGtk(); // HostWindow overrides. @@ -39,9 +40,6 @@ class DisconnectWindowGtk : public HostWindow { // Used to disconnect the client session. base::WeakPtr client_session_control_; - // Localized UI strings. - UiStrings ui_strings_; - GtkWidget* disconnect_window_; GtkWidget* message_; GtkWidget* button_; @@ -67,9 +65,8 @@ void AddRoundRectPath(cairo_t* cairo_context, int width, int height, cairo_close_path(cairo_context); } -DisconnectWindowGtk::DisconnectWindowGtk(const UiStrings& ui_strings) - : ui_strings_(ui_strings), - disconnect_window_(NULL), +DisconnectWindowGtk::DisconnectWindowGtk() + : disconnect_window_(NULL), current_width_(0), current_height_(0) { } @@ -98,7 +95,8 @@ void DisconnectWindowGtk::Start( g_signal_connect(disconnect_window_, "delete-event", G_CALLBACK(OnDeleteThunk), this); - gtk_window_set_title(window, UTF16ToUTF8(ui_strings_.product_name).c_str()); + gtk_window_set_title(window, + l10n_util::GetStringUTF8(IDR_PRODUCT_NAME).c_str()); gtk_window_set_resizable(window, FALSE); // Try to keep the window always visible. @@ -142,7 +140,7 @@ void DisconnectWindowGtk::Start( gtk_container_add(GTK_CONTAINER(align), button_row); button_ = gtk_button_new_with_label( - UTF16ToUTF8(ui_strings_.disconnect_button_text).c_str()); + l10n_util::GetStringUTF8(IDR_STOP_SHARING_BUTTON).c_str()); gtk_box_pack_end(GTK_BOX(button_row), button_, FALSE, FALSE, 0); g_signal_connect(button_, "clicked", G_CALLBACK(OnClickedThunk), this); @@ -163,9 +161,9 @@ void DisconnectWindowGtk::Start( // Extract the user name from the JID. std::string client_jid = client_session_control_->client_jid(); string16 username = UTF8ToUTF16(client_jid.substr(0, client_jid.find('/'))); - string16 text = - ReplaceStringPlaceholders(ui_strings_.disconnect_message, username, NULL); - gtk_label_set_text(GTK_LABEL(message_), UTF16ToUTF8(text).c_str()); + gtk_label_set_text( + GTK_LABEL(message_), + l10n_util::GetStringFUTF8(IDR_MESSAGE_SHARED, username).c_str()); gtk_window_present(window); } @@ -288,9 +286,8 @@ gboolean DisconnectWindowGtk::OnButtonPress(GtkWidget* widget, } // namespace // static -scoped_ptr HostWindow::CreateDisconnectWindow( - const UiStrings& ui_strings) { - return scoped_ptr(new DisconnectWindowGtk(ui_strings)); +scoped_ptr HostWindow::CreateDisconnectWindow() { + return scoped_ptr(new DisconnectWindowGtk()); } } // namespace remoting diff --git a/remoting/host/disconnect_window_mac.h b/remoting/host/disconnect_window_mac.h index 6eedb16..692a23d 100644 --- a/remoting/host/disconnect_window_mac.h +++ b/remoting/host/disconnect_window_mac.h @@ -10,24 +10,18 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -namespace remoting { -struct UiStrings; -} - // Controller for the disconnect window which allows the host user to // quickly disconnect a session. @interface DisconnectWindowController : NSWindowController { @private - const remoting::UiStrings* ui_strings_; base::Closure disconnect_callback_; string16 username_; IBOutlet NSTextField* connectedToField_; IBOutlet NSButton* disconnectButton_; } -- (id)initWithUiStrings:(const remoting::UiStrings*)ui_strings - callback:(const base::Closure&)disconnect_callback - username:(const std::string&)username; +- (id)initWithCallback:(const base::Closure&)disconnect_callback + username:(const std::string&)username; - (IBAction)stopSharing:(id)sender; @end diff --git a/remoting/host/disconnect_window_mac.mm b/remoting/host/disconnect_window_mac.mm index 56e4946..9cb170a 100644 --- a/remoting/host/disconnect_window_mac.mm +++ b/remoting/host/disconnect_window_mac.mm @@ -8,25 +8,27 @@ #include "base/bind.h" #include "base/compiler_specific.h" +#include "base/i18n/rtl.h" #include "base/memory/weak_ptr.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" +#include "remoting/base/string_resources.h" #include "remoting/host/client_session_control.h" #include "remoting/host/host_window.h" -#include "remoting/host/ui_strings.h" +#include "ui/base/l10n/l10n_util_mac.h" @interface DisconnectWindowController() - (BOOL)isRToL; - (void)Hide; @end -const int kMaximumConnectedNameWidthInPixels = 400; +const int kMaximumConnectedNameWidthInPixels = 600; namespace remoting { class DisconnectWindowMac : public HostWindow { public: - explicit DisconnectWindowMac(const UiStrings& ui_strings); + DisconnectWindowMac(); virtual ~DisconnectWindowMac(); // HostWindow overrides. @@ -35,17 +37,13 @@ class DisconnectWindowMac : public HostWindow { OVERRIDE; private: - // Localized UI strings. - UiStrings ui_strings_; - DisconnectWindowController* window_controller_; DISALLOW_COPY_AND_ASSIGN(DisconnectWindowMac); }; -DisconnectWindowMac::DisconnectWindowMac(const UiStrings& ui_strings) - : ui_strings_(ui_strings), - window_controller_(nil) { +DisconnectWindowMac::DisconnectWindowMac() + : window_controller_(nil) { } DisconnectWindowMac::~DisconnectWindowMac() { @@ -70,27 +68,23 @@ void DisconnectWindowMac::Start( std::string client_jid = client_session_control->client_jid(); std::string username = client_jid.substr(0, client_jid.find('/')); window_controller_ = - [[DisconnectWindowController alloc] initWithUiStrings:&ui_strings_ - callback:disconnect_callback - username:username]; + [[DisconnectWindowController alloc] initWithCallback:disconnect_callback + username:username]; [window_controller_ showWindow:nil]; } // static -scoped_ptr HostWindow::CreateDisconnectWindow( - const UiStrings& ui_strings) { - return scoped_ptr(new DisconnectWindowMac(ui_strings)); +scoped_ptr HostWindow::CreateDisconnectWindow() { + return scoped_ptr(new DisconnectWindowMac()); } } // namespace remoting @implementation DisconnectWindowController -- (id)initWithUiStrings:(const remoting::UiStrings*)ui_strings - callback:(const base::Closure&)disconnect_callback - username:(const std::string&)username { +- (id)initWithCallback:(const base::Closure&)disconnect_callback + username:(const std::string&)username { self = [super initWithWindowNibName:@"disconnect_window"]; if (self) { - ui_strings_ = ui_strings; disconnect_callback_ = disconnect_callback; username_ = UTF8ToUTF16(username); } @@ -108,7 +102,7 @@ scoped_ptr HostWindow::CreateDisconnectWindow( } - (BOOL)isRToL { - return ui_strings_->direction == remoting::UiStrings::RTL; + return base::i18n::IsRTL(); } - (void)Hide { @@ -117,12 +111,9 @@ scoped_ptr HostWindow::CreateDisconnectWindow( } - (void)windowDidLoad { - string16 text = ReplaceStringPlaceholders(ui_strings_->disconnect_message, - username_, NULL); - [connectedToField_ setStringValue:base::SysUTF16ToNSString(text)]; - - [disconnectButton_ setTitle:base::SysUTF16ToNSString( - ui_strings_->disconnect_button_text)]; + [connectedToField_ setStringValue:l10n_util::GetNSStringF(IDR_MESSAGE_SHARED, + username_)]; + [disconnectButton_ setTitle:l10n_util::GetNSString(IDR_STOP_SHARING_BUTTON)]; // Resize the window dynamically based on the content. CGFloat oldConnectedWidth = NSWidth([connectedToField_ bounds]); diff --git a/remoting/host/disconnect_window_win.cc b/remoting/host/disconnect_window_win.cc index f8845ca..2a8174d 100644 --- a/remoting/host/disconnect_window_win.cc +++ b/remoting/host/disconnect_window_win.cc @@ -14,7 +14,6 @@ #include "base/win/scoped_select_object.h" #include "remoting/host/client_session_control.h" #include "remoting/host/host_window.h" -#include "remoting/host/ui_strings.h" #include "remoting/host/win/core_resource.h" namespace remoting { @@ -35,7 +34,7 @@ const int kWindowTextMargin = 8; class DisconnectWindowWin : public HostWindow { public: - explicit DisconnectWindowWin(const UiStrings& ui_strings); + DisconnectWindowWin(); virtual ~DisconnectWindowWin(); // HostWindow overrides. @@ -68,9 +67,6 @@ class DisconnectWindowWin : public HostWindow { // Used to disconnect the client session. base::WeakPtr client_session_control_; - // Localized UI strings. - UiStrings ui_strings_; - // Specifies the remote user name. std::string username_; @@ -107,9 +103,8 @@ bool GetControlTextWidth(HWND control, const string16& text, LONG* width) { return true; } -DisconnectWindowWin::DisconnectWindowWin(const UiStrings& ui_strings) - : ui_strings_(ui_strings), - hwnd_(NULL), +DisconnectWindowWin::DisconnectWindowWin() + : hwnd_(NULL), has_hotkey_(false), border_pen_(CreatePen(PS_SOLID, 5, RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))) { @@ -231,38 +226,9 @@ bool DisconnectWindowWin::BeginDialog() { DCHECK(CalledOnValidThread()); DCHECK(!hwnd_); - // Load the dialog resource so that we can modify the RTL flags if necessary. HMODULE module = base::GetModuleFromAddress(&DialogProc); - HRSRC dialog_resource = - FindResource(module, MAKEINTRESOURCE(IDD_DISCONNECT), RT_DIALOG); - if (!dialog_resource) - return false; - - HGLOBAL dialog_template = LoadResource(module, dialog_resource); - if (!dialog_template) - return false; - - DLGTEMPLATE* dialog_pointer = - reinterpret_cast(LockResource(dialog_template)); - if (!dialog_pointer) - return false; - - // The actual resource type is DLGTEMPLATEEX, but this is not defined in any - // standard headers, so we treat it as a generic pointer and manipulate the - // correct offsets explicitly. - scoped_ptr rtl_dialog_template; - if (ui_strings_.direction == UiStrings::RTL) { - unsigned long dialog_template_size = - SizeofResource(module, dialog_resource); - rtl_dialog_template.reset(new unsigned char[dialog_template_size]); - memcpy(rtl_dialog_template.get(), dialog_pointer, dialog_template_size); - DWORD* rtl_dwords = reinterpret_cast(rtl_dialog_template.get()); - rtl_dwords[2] |= (WS_EX_LAYOUTRTL | WS_EX_RTLREADING); - dialog_pointer = reinterpret_cast(rtl_dwords); - } - - hwnd_ = CreateDialogIndirectParam(module, dialog_pointer, NULL, - DialogProc, reinterpret_cast(this)); + hwnd_ = CreateDialogParam(module, MAKEINTRESOURCE(IDD_DISCONNECT), NULL, + DialogProc, reinterpret_cast(this)); if (!hwnd_) return false; @@ -424,9 +390,8 @@ bool DisconnectWindowWin::SetStrings() { } // namespace // static -scoped_ptr HostWindow::CreateDisconnectWindow( - const UiStrings& ui_strings) { - return scoped_ptr(new DisconnectWindowWin(ui_strings)); +scoped_ptr HostWindow::CreateDisconnectWindow() { + return scoped_ptr(new DisconnectWindowWin()); } } // namespace remoting diff --git a/remoting/host/host_main.cc b/remoting/host/host_main.cc index 7f00000..ffff5bf 100644 --- a/remoting/host/host_main.cc +++ b/remoting/host/host_main.cc @@ -17,6 +17,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "remoting/base/breakpad.h" +#include "remoting/base/resources.h" #include "remoting/host/host_exit_codes.h" #include "remoting/host/logging.h" #include "remoting/host/usage_stats_consent.h" @@ -232,11 +233,16 @@ int HostMain(int argc, char** argv) { return kUsageExitCode; } + remoting::LoadResources(""); + // Invoke the entry point. int exit_code = main_routine(); if (exit_code == kUsageExitCode) { Usage(command_line->GetProgram()); } + + remoting::UnloadResources(); + return exit_code; } diff --git a/remoting/host/host_window.h b/remoting/host/host_window.h index 243f9ba..d193686 100644 --- a/remoting/host/host_window.h +++ b/remoting/host/host_window.h @@ -14,19 +14,16 @@ namespace remoting { class ClientSessionControl; -struct UiStrings; class HostWindow : public base::NonThreadSafe { public: virtual ~HostWindow() {} // Creates a platform-specific instance of the continue window. - static scoped_ptr CreateContinueWindow( - const UiStrings& ui_strings); + static scoped_ptr CreateContinueWindow(); // Creates a platform-specific instance of the disconnect window. - static scoped_ptr CreateDisconnectWindow( - const UiStrings& ui_strings); + static scoped_ptr CreateDisconnectWindow(); // Starts the UI state machine. |client_session_control| will be used to // notify the caller about the local user's actions. diff --git a/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist b/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist index beef6ef..87a4e82 100644 --- a/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist +++ b/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist @@ -12,8 +12,6 @@ BUNDLE_ID CFBundleInfoDictionaryVersion 6.0 - CFBundleName - BUNDLE_NAME CFBundlePackageType APPL CFBundleShortVersionString @@ -24,8 +22,6 @@ VERSION_FULL LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET}.0 - NSHumanReadableCopyright - COPYRIGHT_INFO NSMainNibFile remoting_uninstaller NSPrincipalClass diff --git a/remoting/host/installer/mac/uninstaller/remoting_uninstaller-InfoPlist.strings.jinja2 b/remoting/host/installer/mac/uninstaller/remoting_uninstaller-InfoPlist.strings.jinja2 new file mode 100644 index 0000000..4cdeca8 --- /dev/null +++ b/remoting/host/installer/mac/uninstaller/remoting_uninstaller-InfoPlist.strings.jinja2 @@ -0,0 +1,2 @@ +CFBundleName = "{% trans %}MAC_UNINSTALLER_BUNDLE_NAME{% endtrans %}"; +NSHumanReadableCopyright = "{% trans %}COPYRIGHT{% endtrans %}"; diff --git a/remoting/host/it2me_desktop_environment.cc b/remoting/host/it2me_desktop_environment.cc index 6a289c9..68aa57d 100644 --- a/remoting/host/it2me_desktop_environment.cc +++ b/remoting/host/it2me_desktop_environment.cc @@ -26,8 +26,7 @@ It2MeDesktopEnvironment::It2MeDesktopEnvironment( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, scoped_refptr ui_task_runner, - base::WeakPtr client_session_control, - const UiStrings& ui_strings) + base::WeakPtr client_session_control) : BasicDesktopEnvironment(caller_task_runner, input_task_runner, ui_task_runner) { @@ -54,14 +53,14 @@ It2MeDesktopEnvironment::It2MeDesktopEnvironment( // Create the continue and disconnect windows. if (want_user_interface) { - continue_window_ = HostWindow::CreateContinueWindow(ui_strings); + continue_window_ = HostWindow::CreateContinueWindow(); continue_window_.reset(new HostWindowProxy( caller_task_runner, ui_task_runner, continue_window_.Pass())); continue_window_->Start(client_session_control); - disconnect_window_ = HostWindow::CreateDisconnectWindow(ui_strings); + disconnect_window_ = HostWindow::CreateDisconnectWindow(); disconnect_window_.reset(new HostWindowProxy( caller_task_runner, ui_task_runner, @@ -73,12 +72,10 @@ It2MeDesktopEnvironment::It2MeDesktopEnvironment( It2MeDesktopEnvironmentFactory::It2MeDesktopEnvironmentFactory( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, - scoped_refptr ui_task_runner, - const UiStrings& ui_strings) + scoped_refptr ui_task_runner) : BasicDesktopEnvironmentFactory(caller_task_runner, input_task_runner, - ui_task_runner, - ui_strings) { + ui_task_runner) { } It2MeDesktopEnvironmentFactory::~It2MeDesktopEnvironmentFactory() { @@ -92,8 +89,7 @@ scoped_ptr It2MeDesktopEnvironmentFactory::Create( new It2MeDesktopEnvironment(caller_task_runner(), input_task_runner(), ui_task_runner(), - client_session_control, - ui_strings())); + client_session_control)); } } // namespace remoting diff --git a/remoting/host/it2me_desktop_environment.h b/remoting/host/it2me_desktop_environment.h index 99e6af7..368a6ab 100644 --- a/remoting/host/it2me_desktop_environment.h +++ b/remoting/host/it2me_desktop_environment.h @@ -26,8 +26,7 @@ class It2MeDesktopEnvironment : public BasicDesktopEnvironment { scoped_refptr caller_task_runner, scoped_refptr input_task_runner, scoped_refptr ui_task_runner, - base::WeakPtr client_session_control, - const UiStrings& ui_strings); + base::WeakPtr client_session_control); private: // Presents the continue window to the local user. @@ -48,8 +47,7 @@ class It2MeDesktopEnvironmentFactory : public BasicDesktopEnvironmentFactory { It2MeDesktopEnvironmentFactory( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, - scoped_refptr ui_task_runner, - const UiStrings& ui_strings); + scoped_refptr ui_task_runner); virtual ~It2MeDesktopEnvironmentFactory(); // DesktopEnvironmentFactory interface. diff --git a/remoting/host/mac/me2me_preference_pane-Info.plist b/remoting/host/mac/me2me_preference_pane-Info.plist index 1fab228..001968e 100644 --- a/remoting/host/mac/me2me_preference_pane-Info.plist +++ b/remoting/host/mac/me2me_preference_pane-Info.plist @@ -12,8 +12,6 @@ BUNDLE_ID CFBundleInfoDictionaryVersion 6.0 - CFBundleName - BUNDLE_NAME CFBundlePackageType BNDL CFBundleShortVersionString @@ -22,14 +20,10 @@ ???? CFBundleVersion VERSION_FULL - NSHumanReadableCopyright - COPYRIGHT_INFO NSMainNibFile me2me_preference_pane NSPrefPaneIconFile chromoting128.png - NSPrefPaneIconLabel - PREF_PANE_ICON_LABEL NSPrincipalClass Me2MePreferencePane diff --git a/remoting/host/mac/me2me_preference_pane-InfoPlist.strings.jinja2 b/remoting/host/mac/me2me_preference_pane-InfoPlist.strings.jinja2 new file mode 100644 index 0000000..c0a7df6 --- /dev/null +++ b/remoting/host/mac/me2me_preference_pane-InfoPlist.strings.jinja2 @@ -0,0 +1,3 @@ +CFBundleName = "{% trans %}MAC_PREFPANE_BUNDLE_NAME{% endtrans %}"; +NSHumanReadableCopyright = "{% trans %}COPYRIGHT{% endtrans %}"; +NSPrefPaneIconLabel = "{% trans %}MAC_PREFPANE_ICON_LABEL{% endtrans %}"; diff --git a/remoting/host/me2me_desktop_environment.cc b/remoting/host/me2me_desktop_environment.cc index 71dc6b7..edc5b87 100644 --- a/remoting/host/me2me_desktop_environment.cc +++ b/remoting/host/me2me_desktop_environment.cc @@ -65,7 +65,6 @@ Me2MeDesktopEnvironment::Me2MeDesktopEnvironment( bool Me2MeDesktopEnvironment::InitializeSecurity( base::WeakPtr client_session_control, - const UiStrings& ui_strings, bool curtain_enabled) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); @@ -106,7 +105,7 @@ bool Me2MeDesktopEnvironment::InitializeSecurity( ui_task_runner(), client_session_control); - disconnect_window_ = HostWindow::CreateDisconnectWindow(ui_strings); + disconnect_window_ = HostWindow::CreateDisconnectWindow(); disconnect_window_.reset(new HostWindowProxy( caller_task_runner(), ui_task_runner(), @@ -120,12 +119,10 @@ bool Me2MeDesktopEnvironment::InitializeSecurity( Me2MeDesktopEnvironmentFactory::Me2MeDesktopEnvironmentFactory( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, - scoped_refptr ui_task_runner, - const UiStrings& ui_strings) + scoped_refptr ui_task_runner) : BasicDesktopEnvironmentFactory(caller_task_runner, input_task_runner, - ui_task_runner, - ui_strings), + ui_task_runner), curtain_enabled_(false) { } @@ -141,7 +138,6 @@ scoped_ptr Me2MeDesktopEnvironmentFactory::Create( input_task_runner(), ui_task_runner())); if (!desktop_environment->InitializeSecurity(client_session_control, - ui_strings(), curtain_enabled_)) { return scoped_ptr(); } diff --git a/remoting/host/me2me_desktop_environment.h b/remoting/host/me2me_desktop_environment.h index f981a89..f028664 100644 --- a/remoting/host/me2me_desktop_environment.h +++ b/remoting/host/me2me_desktop_environment.h @@ -35,7 +35,6 @@ class Me2MeDesktopEnvironment : public BasicDesktopEnvironment { // and in-session UI). bool InitializeSecurity( base::WeakPtr client_session_control, - const UiStrings& ui_strings, bool curtain_enabled); private: @@ -58,8 +57,7 @@ class Me2MeDesktopEnvironmentFactory : public BasicDesktopEnvironmentFactory { Me2MeDesktopEnvironmentFactory( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, - scoped_refptr ui_task_runner, - const UiStrings& ui_strings); + scoped_refptr ui_task_runner); virtual ~Me2MeDesktopEnvironmentFactory(); // DesktopEnvironmentFactory interface. diff --git a/remoting/host/plugin/constants.h b/remoting/host/plugin/constants.h deleted file mode 100644 index 780a2c9..0000000 --- a/remoting/host/plugin/constants.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2012 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_PLUGIN_CONSTANTS_H_ -#define REMOTING_HOST_PLUGIN_CONSTANTS_H_ - -// Warning: If you modify any macro in this file, make sure to modify -// the following files too: -// - remoting/branding_Chrome -// - remoting/branding_Chromium -// - remoting/remoting.gyp -// - remoting/host/plugin/host_plugin.ver - -#define HOST_PLUGIN_DESCRIPTION \ - "Allow another user to access your computer securely over the Internet." -#define HOST_PLUGIN_MIME_TYPE "application/vnd.chromium.remoting-host" - -#if defined(GOOGLE_CHROME_BUILD) -#define HOST_PLUGIN_NAME "Chrome Remote Desktop Host" -#else -#define HOST_PLUGIN_NAME "Chromoting Host" -#endif // defined(GOOGLE_CHROME_BUILD) - -#endif // REMOTING_HOST_PLUGIN_CONSTANTS_H_ diff --git a/remoting/host/plugin/host_plugin-Info.plist b/remoting/host/plugin/host_plugin-Info.plist index 42cecdd..a2ff900 100644 --- a/remoting/host/plugin/host_plugin-Info.plist +++ b/remoting/host/plugin/host_plugin-Info.plist @@ -13,21 +13,17 @@ CFBundlePackageType BRPL CFBundleShortVersionString - 1.0.0.0 + VERSION_SHORT CFBundleVersion - 1.0.0.0 + VERSION_FULL CFBundleSignature ${CHROMIUM_CREATOR} LSMinimumSystemVersion 10.5.0 - WebPluginName - HOST_PLUGIN_NAME WebPluginMIMETypes HOST_PLUGIN_MIME_TYPE - WebPluginDescription - HOST_PLUGIN_DESCRIPTION diff --git a/remoting/host/plugin/host_plugin-InfoPlist.strings.jinja2 b/remoting/host/plugin/host_plugin-InfoPlist.strings.jinja2 new file mode 100644 index 0000000..4bec263 --- /dev/null +++ b/remoting/host/plugin/host_plugin-InfoPlist.strings.jinja2 @@ -0,0 +1,3 @@ +NSHumanReadableCopyright = "{% trans %}COPYRIGHT{% endtrans %}"; +WebPluginDescription = "{% trans %}REMOTING_HOST_PLUGIN_NAME{% endtrans %}"; +WebPluginName = "{% trans %}REMOTING_HOST_PLUGIN_DESCRIPTION{% endtrans %}"; diff --git a/remoting/host/plugin/host_plugin.cc b/remoting/host/plugin/host_plugin.cc index 80d7cce..a0a98549 100644 --- a/remoting/host/plugin/host_plugin.cc +++ b/remoting/host/plugin/host_plugin.cc @@ -15,7 +15,8 @@ #include "base/strings/stringize_macros.h" #include "net/socket/ssl_server_socket.h" #include "remoting/base/plugin_thread_task_runner.h" -#include "remoting/host/plugin/constants.h" +#include "remoting/base/resources.h" +#include "remoting/base/string_resources.h" #include "remoting/host/plugin/host_log_handler.h" #include "remoting/host/plugin/host_plugin_utils.h" #include "remoting/host/plugin/host_script_object.h" @@ -25,6 +26,7 @@ #include "third_party/npapi/bindings/npapi.h" #include "third_party/npapi/bindings/npfunctions.h" #include "third_party/npapi/bindings/npruntime.h" +#include "ui/base/l10n/l10n_util.h" // Symbol export is handled with a separate def file on Windows. #if defined (__GNUC__) && __GNUC__ >= 4 @@ -56,8 +58,14 @@ using remoting::StringFromNPIdentifier; namespace { +bool g_initialized = false; + base::AtExitManager* g_at_exit_manager = NULL; +// The plugin name and description returned by GetValue(). +std::string* g_ui_name = NULL; +std::string* g_ui_description = NULL; + // NPAPI plugin implementation for remoting host. // Documentation for most of the calls in this class can be found here: // https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins @@ -355,6 +363,36 @@ class HostNPPlugin : public remoting::PluginThreadTaskRunner::Delegate { base::Lock timers_lock_; }; +void InitializePlugin() { + if (g_initialized) + return; + + g_initialized = true; + g_at_exit_manager = new base::AtExitManager; + + // Init an empty command line for common objects that use it. + CommandLine::Init(0, NULL); + + if (remoting::LoadResources("")) { + g_ui_name = new std::string( + l10n_util::GetStringUTF8(IDR_REMOTING_HOST_PLUGIN_NAME)); + g_ui_description = new std::string( + l10n_util::GetStringUTF8(IDR_REMOTING_HOST_PLUGIN_DESCRIPTION)); + } else { + g_ui_name = new std::string(); + g_ui_description = new std::string(); + } +} + +void ShutdownPlugin() { + delete g_ui_name; + delete g_ui_description; + + remoting::UnloadResources(); + + delete g_at_exit_manager; +} + // Utility functions to map NPAPI Entry Points to C++ Objects. HostNPPlugin* PluginFromInstance(NPP instance) { return reinterpret_cast(instance->pdata); @@ -408,17 +446,20 @@ NPError DestroyPlugin(NPP instance, } NPError GetValue(NPP instance, NPPVariable variable, void* value) { + // NP_GetValue() can be called before NP_Initialize(). + InitializePlugin(); + switch(variable) { default: VLOG(2) << "GetValue - default " << variable; return NPERR_GENERIC_ERROR; case NPPVpluginNameString: VLOG(2) << "GetValue - name string"; - *reinterpret_cast(value) = HOST_PLUGIN_NAME; + *reinterpret_cast(value) = g_ui_name->c_str(); break; case NPPVpluginDescriptionString: VLOG(2) << "GetValue - description string"; - *reinterpret_cast(value) = HOST_PLUGIN_DESCRIPTION; + *reinterpret_cast(value) = g_ui_description->c_str(); break; case NPPVpluginNeedsXEmbed: VLOG(2) << "GetValue - NeedsXEmbed"; @@ -490,8 +531,7 @@ EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnetscape_funcs #endif ) { VLOG(2) << "NP_Initialize"; - if (g_at_exit_manager) - return NPERR_MODULE_LOAD_FAILED_ERROR; + InitializePlugin(); if(npnetscape_funcs == NULL) return NPERR_INVALID_FUNCTABLE_ERROR; @@ -499,13 +539,10 @@ EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnetscape_funcs if(((npnetscape_funcs->version & 0xff00) >> 8) > NP_VERSION_MAJOR) return NPERR_INCOMPATIBLE_VERSION_ERROR; - g_at_exit_manager = new base::AtExitManager; g_npnetscape_funcs = npnetscape_funcs; #if defined(OS_POSIX) && !defined(OS_MACOSX) NP_GetEntryPoints(nppfuncs); #endif - // Init an empty command line for common objects that use it. - CommandLine::Init(0, NULL); #if defined(OS_WIN) ui::EnableHighDPISupport(); @@ -516,8 +553,8 @@ EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnetscape_funcs EXPORT NPError API_CALL NP_Shutdown() { VLOG(2) << "NP_Shutdown"; - delete g_at_exit_manager; - g_at_exit_manager = NULL; + ShutdownPlugin(); + return NPERR_NO_ERROR; } diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index 9b78eb3..f9a8299 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -18,6 +18,7 @@ #include "net/base/net_util.h" #include "remoting/base/auth_token_util.h" #include "remoting/base/auto_thread.h" +#include "remoting/base/resources.h" #include "remoting/base/rsa_key_pair.h" #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" @@ -104,8 +105,7 @@ class HostNPScriptObject::It2MeImpl // Creates It2Me host structures and starts the host. void Connect(const std::string& uid, const std::string& auth_token, - const std::string& auth_service, - const UiStrings& ui_strings); + const std::string& auth_service); // Disconnects the host, ready for tear-down. // Also called internally, from the network thread. @@ -222,22 +222,19 @@ HostNPScriptObject::It2MeImpl::It2MeImpl( void HostNPScriptObject::It2MeImpl::Connect( const std::string& uid, const std::string& auth_token, - const std::string& auth_service, - const UiStrings& ui_strings) { + const std::string& auth_service) { if (!host_context_->ui_task_runner()->BelongsToCurrentThread()) { DCHECK(plugin_task_runner_->BelongsToCurrentThread()); host_context_->ui_task_runner()->PostTask( FROM_HERE, - base::Bind(&It2MeImpl::Connect, this, uid, auth_token, auth_service, - ui_strings)); + base::Bind(&It2MeImpl::Connect, this, uid, auth_token, auth_service)); return; } desktop_environment_factory_.reset(new It2MeDesktopEnvironmentFactory( host_context_->network_task_runner(), host_context_->input_task_runner(), - host_context_->ui_task_runner(), - ui_strings)); + host_context_->ui_task_runner())); // Start monitoring configured policies. policy_watcher_.reset( @@ -1056,7 +1053,7 @@ bool HostNPScriptObject::Connect(const NPVariant* args, it2me_impl_ = new It2MeImpl( host_context.Pass(), plugin_task_runner_, weak_ptr_, xmpp_server_config_, directory_bot_jid_); - it2me_impl_->Connect(uid, auth_token, auth_service, ui_strings_); + it2me_impl_->Connect(uid, auth_token, auth_service); return true; } @@ -1496,23 +1493,13 @@ void HostNPScriptObject::SetWindow(NPWindow* np_window) { void HostNPScriptObject::LocalizeStrings(NPObject* localize_func) { DCHECK(plugin_task_runner_->BelongsToCurrentThread()); - string16 direction; - LocalizeString(localize_func, "@@bidi_dir", &direction); - ui_strings_.direction = UTF16ToUTF8(direction) == "rtl" ? - remoting::UiStrings::RTL : remoting::UiStrings::LTR; - LocalizeString(localize_func, /*i18n-content*/"PRODUCT_NAME", - &ui_strings_.product_name); - LocalizeString(localize_func, /*i18n-content*/"DISCONNECT_OTHER_BUTTON", - &ui_strings_.disconnect_button_text); - LocalizeString(localize_func, /*i18n-content*/"CONTINUE_PROMPT", - &ui_strings_.continue_prompt); - LocalizeString(localize_func, /*i18n-content*/"CONTINUE_BUTTON", - &ui_strings_.continue_button_text); - LocalizeString(localize_func, /*i18n-content*/"STOP_SHARING_BUTTON", - &ui_strings_.stop_sharing_button_text); - LocalizeStringWithSubstitution(localize_func, - /*i18n-content*/"MESSAGE_SHARED", "$1", - &ui_strings_.disconnect_message); + // Reload resources for the current locale. The default UI locale is used on + // Windows. +#if !defined(OS_WIN) + string16 ui_locale; + LocalizeString(localize_func, "@@ui_locale", &ui_locale); + remoting::LoadResources(UTF16ToUTF8(ui_locale)); +#endif // !defined(OS_WIN) } bool HostNPScriptObject::LocalizeString(NPObject* localize_func, diff --git a/remoting/host/plugin/host_script_object.h b/remoting/host/plugin/host_script_object.h index a3d5bcd..e1120ec 100644 --- a/remoting/host/plugin/host_script_object.h +++ b/remoting/host/plugin/host_script_object.h @@ -25,7 +25,6 @@ #include "remoting/host/log_to_server.h" #include "remoting/host/plugin/host_plugin_utils.h" #include "remoting/host/setup/daemon_controller.h" -#include "remoting/host/ui_strings.h" #include "remoting/jingle_glue/xmpp_signal_strategy.h" #include "remoting/protocol/pairing_registry.h" #include "third_party/npapi/bindings/npapi.h" @@ -302,9 +301,6 @@ class HostNPScriptObject { base::TimeDelta access_code_lifetime_; std::string client_username_; - // Localized strings for use by the |it2me_impl_| UI. - UiStrings ui_strings_; - // IT2Me Talk server configuration used by |it2me_impl_| to connect. XmppSignalStrategy::XmppServerConfig xmpp_server_config_; diff --git a/remoting/host/remoting_me2me_host-Info.plist b/remoting/host/remoting_me2me_host-Info.plist index 66f04b1..1f2b9df 100644 --- a/remoting/host/remoting_me2me_host-Info.plist +++ b/remoting/host/remoting_me2me_host-Info.plist @@ -24,8 +24,6 @@ VERSION_SHORT LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET}.0 - NSHumanReadableCopyright - COPYRIGHT_INFO NSPrincipalClass CrApplication LSUIElement diff --git a/remoting/host/remoting_me2me_host-InfoPlist.strings.jinja2 b/remoting/host/remoting_me2me_host-InfoPlist.strings.jinja2 new file mode 100644 index 0000000..4a650d8 --- /dev/null +++ b/remoting/host/remoting_me2me_host-InfoPlist.strings.jinja2 @@ -0,0 +1 @@ +NSHumanReadableCopyright = "{% trans %}COPYRIGHT{% endtrans %}"; diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 7b7d3e3..408d293 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -64,7 +64,6 @@ #include "remoting/host/session_manager_factory.h" #include "remoting/host/signaling_connector.h" #include "remoting/host/token_validator_factory_impl.h" -#include "remoting/host/ui_strings.h" #include "remoting/host/usage_stats_consent.h" #include "remoting/jingle_glue/network_settings.h" #include "remoting/jingle_glue/xmpp_signal_strategy.h" @@ -581,9 +580,6 @@ void HostProcess::StartOnUiThread() { } #endif // defined(OS_LINUX) - // TODO(alexeypa): Localize the UI strings. See http://crbug.com/155204. - UiStrings ui_strings; - // Create a desktop environment factory appropriate to the build type & // platform. #if defined(OS_WIN) @@ -600,8 +596,7 @@ void HostProcess::StartOnUiThread() { new Me2MeDesktopEnvironmentFactory( context_->network_task_runner(), context_->input_task_runner(), - context_->ui_task_runner(), - ui_strings); + context_->ui_task_runner()); #endif // !defined(OS_WIN) desktop_environment_factory_.reset(desktop_environment_factory); diff --git a/remoting/host/ui_strings.cc b/remoting/host/ui_strings.cc deleted file mode 100644 index e59dd5c6..0000000 --- a/remoting/host/ui_strings.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2012 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" - -#include "base/strings/utf_string_conversions.h" - -namespace remoting { - -UiStrings::UiStrings() : - direction(LTR), - product_name(ASCIIToUTF16("Chromoting")), - // Audio is currently only supported for Me2Me, and not on Mac. However, - // for IT2Me, these strings are replaced during l10n, so it's fine to - // hard-code a mention of audio here. -#if defined(OS_MACOSX) - disconnect_message( - ASCIIToUTF16("Your desktop is currently shared with $1.")), -#else - disconnect_message(ASCIIToUTF16( - "Your desktop and any audio output are currently shared with $1.")), -#endif - disconnect_button_text(ASCIIToUTF16("Disconnect")), - continue_prompt(ASCIIToUTF16( - "You are currently sharing this machine with another user. " - "Please confirm that you want to continue sharing.")), - continue_button_text(ASCIIToUTF16("Continue")), - stop_sharing_button_text(ASCIIToUTF16("Stop Sharing")) { -} - -UiStrings::~UiStrings() {} - -} // namespace remoting diff --git a/remoting/host/ui_strings.h b/remoting/host/ui_strings.h deleted file mode 100644 index 356c27a..0000000 --- a/remoting/host/ui_strings.h +++ /dev/null @@ -1,50 +0,0 @@ -// 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 "base/strings/string16.h" - -// 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). - string16 product_name; - - // The message in the disconnect dialog. - string16 disconnect_message; - - // The label on the disconnect dialog button, without the keyboard shortcut. - string16 disconnect_button_text; - - // The confirmation prompt displayed by the continue window. - string16 continue_prompt; - - // The label on the 'Continue' button of the continue window. - string16 continue_button_text; - - // The label on the 'Stop Sharing' button of the continue window. - string16 stop_sharing_button_text; -}; - -} - -#endif // REMOTING_HOST_UI_STRINGS_H_ diff --git a/remoting/host/win/core.rc.jinja2 b/remoting/host/win/core.rc.jinja2 index cf7c1807..b19c005 100644 --- a/remoting/host/win/core.rc.jinja2 +++ b/remoting/host/win/core.rc.jinja2 @@ -29,7 +29,7 @@ IDD_VERIFY_CONFIG_DIALOG ICON "remoting/resources/chromoting.ico" IDD_VERIFY_CONFIG_DIALOG DIALOGEX 0, 0, 221, 106 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUPWINDOW | WS_CAPTION -EXSTYLE 0 {% if IsRtlLanguage(lang) %} | WS_EX_LAYOUTRTL {% endif %} +EXSTYLE 0 {% if IsRtlLanguage(lang) %} | WS_EX_LAYOUTRTL | WS_EX_RTLREADING {% endif %} CAPTION "{% trans %}PRODUCT_NAME{% endtrans %}" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN @@ -44,7 +44,7 @@ END IDD_DISCONNECT DIALOGEX 0, 0, 145, 24 STYLE DS_SETFONT | WS_POPUP -EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW {% if IsRtlLanguage(lang) %} | WS_EX_LAYOUTRTL {% endif %} +EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW {% if IsRtlLanguage(lang) %} | WS_EX_LAYOUTRTL | WS_EX_RTLREADING {% endif %} FONT 9, "Microsoft Sans Serif", 400, 0, 0x0 BEGIN DEFPUSHBUTTON "{% trans %}DISCONNECT_OTHER_BUTTON{% endtrans %}",IDC_DISCONNECT,68,5,70,14 @@ -55,7 +55,7 @@ END IDD_CONTINUE DIALOGEX 0, 0, 221, 58 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION -EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW {% if IsRtlLanguage(lang) %} | WS_EX_LAYOUTRTL {% endif %} +EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW {% if IsRtlLanguage(lang) %} | WS_EX_LAYOUTRTL | WS_EX_RTLREADING {% endif %} CAPTION "kTitle" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN diff --git a/remoting/host/win/session_desktop_environment.cc b/remoting/host/win/session_desktop_environment.cc index 0f4ffda..82951ea 100644 --- a/remoting/host/win/session_desktop_environment.cc +++ b/remoting/host/win/session_desktop_environment.cc @@ -44,12 +44,10 @@ SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory( scoped_refptr caller_task_runner, scoped_refptr input_task_runner, scoped_refptr ui_task_runner, - const UiStrings& ui_strings, const base::Closure& inject_sas) : Me2MeDesktopEnvironmentFactory(caller_task_runner, input_task_runner, - ui_task_runner, - ui_strings), + ui_task_runner), inject_sas_(inject_sas) { DCHECK(caller_task_runner->BelongsToCurrentThread()); } @@ -67,7 +65,6 @@ scoped_ptr SessionDesktopEnvironmentFactory::Create( ui_task_runner(), inject_sas_)); if (!desktop_environment->InitializeSecurity(client_session_control, - ui_strings(), curtain_enabled())) { return scoped_ptr(); } diff --git a/remoting/host/win/session_desktop_environment.h b/remoting/host/win/session_desktop_environment.h index 1eb9c6a..7d14413 100644 --- a/remoting/host/win/session_desktop_environment.h +++ b/remoting/host/win/session_desktop_environment.h @@ -13,8 +13,6 @@ namespace remoting { -struct UiStrings; - // Used to create audio/video capturers and event executor that are compatible // with Windows sessions. class SessionDesktopEnvironment : public Me2MeDesktopEnvironment { @@ -45,7 +43,6 @@ class SessionDesktopEnvironmentFactory : public Me2MeDesktopEnvironmentFactory { scoped_refptr caller_task_runner, scoped_refptr input_task_runner, scoped_refptr ui_task_runner, - const UiStrings& ui_strings, const base::Closure& inject_sas); virtual ~SessionDesktopEnvironmentFactory(); diff --git a/remoting/host/win/version.rc.jinja2 b/remoting/host/win/version.rc.jinja2 index 19ba83d..0480767 100644 --- a/remoting/host/win/version.rc.jinja2 +++ b/remoting/host/win/version.rc.jinja2 @@ -3,6 +3,7 @@ // found in the LICENSE file. #include + #ifdef IDC_STATIC #undef IDC_STATIC #endif @@ -57,7 +58,7 @@ BEGIN VALUE "FileDescription", "{% trans %}REMOTING_HOST_PLUGIN_DESCRIPTION{% endtrans %}" VALUE "InternalName", "remoting_host_plugin.dll" VALUE "OriginalFilename", "remoting_host_plugin.dll" - VALUE "MIMEType", "application/vnd.chromium.remoting-host" + VALUE "MIMEType", HOST_PLUGIN_MIME_TYPE #else #error BINARY must be set to one of BINARY_XXX values. #endif diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 6816b7e..c8deacc 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -43,15 +43,10 @@ ' - - - - - - - - - - - - - - - diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd index 3c69d18..f71fafd 100644 --- a/remoting/resources/remoting_strings.grd +++ b/remoting/resources/remoting_strings.grd @@ -5,89 +5,91 @@ - - + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -217,6 +219,18 @@ Please confirm your account and PIN below to allow access by Chrome Remote Desktop. + + Chrome Remote Desktop Host + + + Chrome Remote Desktop Host Preferences + + + Chrome Remote Desktop Host + + + Chrome Remote Desktop Host Uninstaller + @@ -301,6 +315,18 @@ Please confirm your account and PIN below to allow access by Chromoting. + + Chromoting Host + + + Chromoting Host Preferences + + + Chromoting Host + + + Chromoting Host Uninstaller + @@ -363,9 +389,6 @@ Disconnect - - Disconnect - Duration diff --git a/remoting/resources/resource_ids b/remoting/resources/resource_ids index fc0ba05..3becde5 100644 --- a/remoting/resources/resource_ids +++ b/remoting/resources/resource_ids @@ -19,7 +19,4 @@ "remoting/resources/remoting_strings.grd": { "messages": [1000], }, - "remoting/resources/common_resources.grd": { - "structures": [10000], - }, } diff --git a/remoting/tools/build/remoting_copy_locales.py b/remoting/tools/build/remoting_copy_locales.py new file mode 100755 index 0000000..4d1d41a --- /dev/null +++ b/remoting/tools/build/remoting_copy_locales.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# Copyright 2013 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. + +"""Helper script to repack paks for a list of locales. + +Gyp doesn't have any built-in looping capability, so this just provides a way to +loop over a list of locales when repacking pak files, thus avoiding a +proliferation of mostly duplicate, cut-n-paste gyp actions. +""" + +import optparse +import os +import sys + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', + 'tools', 'grit')) +from grit.format import data_pack + +# Some build paths defined by gyp. +GRIT_DIR = None +INT_DIR = None + +# The target platform. If it is not defined, sys.platform will be used. +OS = None + +# Extra input files. +EXTRA_INPUT_FILES = [] + +class Usage(Exception): + def __init__(self, msg): + self.msg = msg + + +def calc_output(locale): + """Determine the file that will be generated for the given locale.""" + #e.g. '<(INTERMEDIATE_DIR)/remoting_locales/da.pak', + if OS == 'mac' or OS == 'ios': + # For Cocoa to find the locale at runtime, it needs to use '_' instead + # of '-' (http://crbug.com/20441). + return os.path.join(INT_DIR, 'remoting', 'resources', + '%s.lproj' % locale.replace('-', '_'), 'locale.pak') + else: + return os.path.join(INT_DIR, 'remoting_locales', locale + '.pak') + + +def calc_inputs(locale): + """Determine the files that need processing for the given locale.""" + inputs = [] + + #e.g. '<(grit_out_dir)/remoting/resources/da.pak' + inputs.append(os.path.join(GRIT_DIR, 'remoting/resources/%s.pak' % locale)) + + # Add any extra input files. + for extra_file in EXTRA_INPUT_FILES: + inputs.append('%s_%s.pak' % (extra_file, locale)) + + return inputs + + +def list_outputs(locales): + """Returns the names of files that will be generated for the given locales. + + This is to provide gyp the list of output files, so build targets can + properly track what needs to be built. + """ + outputs = [] + for locale in locales: + outputs.append(calc_output(locale)) + # Quote each element so filename spaces don't mess up gyp's attempt to parse + # it into a list. + return " ".join(['"%s"' % x for x in outputs]) + + +def list_inputs(locales): + """Returns the names of files that will be processed for the given locales. + + This is to provide gyp the list of input files, so build targets can properly + track their prerequisites. + """ + inputs = [] + for locale in locales: + inputs += calc_inputs(locale) + # Quote each element so filename spaces don't mess up gyp's attempt to parse + # it into a list. + return " ".join(['"%s"' % x for x in inputs]) + + +def repack_locales(locales): + """ Loop over and repack the given locales.""" + for locale in locales: + inputs = calc_inputs(locale) + output = calc_output(locale) + data_pack.DataPack.RePack(output, inputs) + + +def DoMain(argv): + global GRIT_DIR + global INT_DIR + global OS + global EXTRA_INPUT_FILES + + parser = optparse.OptionParser("usage: %prog [options] locales") + parser.add_option("-i", action="store_true", dest="inputs", default=False, + help="Print the expected input file list, then exit.") + parser.add_option("-o", action="store_true", dest="outputs", default=False, + help="Print the expected output file list, then exit.") + parser.add_option("-g", action="store", dest="grit_dir", + help="GRIT build files output directory.") + parser.add_option("-x", action="store", dest="int_dir", + help="Intermediate build files output directory.") + parser.add_option("-e", action="append", dest="extra_input", default=[], + help="Full path to an extra input pak file without the\ + locale suffix and \".pak\" extension.") + parser.add_option("-p", action="store", dest="os", + help="The target OS. (e.g. mac, linux, win, etc.)") + options, locales = parser.parse_args(argv) + + if not locales: + parser.error('Please specificy at least one locale to process.\n') + + print_inputs = options.inputs + print_outputs = options.outputs + GRIT_DIR = options.grit_dir + INT_DIR = options.int_dir + EXTRA_INPUT_FILES = options.extra_input + OS = options.os + + if not OS: + if sys.platform == 'darwin': + OS = 'mac' + elif sys.platform.startswith('linux'): + OS = 'linux' + elif sys.platform in ('cygwin', 'win32'): + OS = 'win' + else: + OS = sys.platform + + if print_inputs and print_outputs: + parser.error('Please specify only one of "-i" or "-o".\n') + if print_inputs and not GRIT_DIR: + parser.error('Please specify "-g".\n') + if print_outputs and not INT_DIR: + parser.error('Please specify "-x".\n') + if not (print_inputs or print_outputs or (GRIT_DIR and INT_DIR)): + parser.error('Please specify both "-g" and "-x".\n') + + if print_inputs: + return list_inputs(locales) + + if print_outputs: + return list_outputs(locales) + + return repack_locales(locales) + +if __name__ == '__main__': + results = DoMain(sys.argv[1:]) + if results: + print results diff --git a/remoting/tools/build/remoting_localize.py b/remoting/tools/build/remoting_localize.py index 8dc0538..6a88884 100755 --- a/remoting/tools/build/remoting_localize.py +++ b/remoting/tools/build/remoting_localize.py @@ -542,7 +542,10 @@ def IsRtlLanguage(language): def NormalizeLanguageCode(language): - return language.replace('_', '-', 1) + lang = language.replace('_', '-', 1) + if lang == 'en-US': + lang = 'en' + return lang def GetDataPackageSuffix(language): @@ -639,6 +642,12 @@ class MessageMap: return lambda message: self.GetText(message) +# Use '@' as a delimiter for string templates instead of '$' to avoid unintended +# expansion when passing the string from GYP. +class GypTemplate(Template): + delimiter = '@' + + def Localize(source, locales, options): # Set the list of languages to use. languages = map(NormalizeLanguageCode, locales) @@ -701,12 +710,13 @@ def Localize(source, locales, options): # Generate a separate file per each locale if requested. outputs = [] if options.locale_output: - target = Template(options.locale_output) + target = GypTemplate(options.locale_output) for lang in languages: context['languages'] = [ lang ] context['language'] = lang context['pak_suffix'] = GetDataPackageSuffix(lang) context['json_suffix'] = GetJsonSuffix(lang) + message_map.SelectLanguage(lang) template_file_name = target.safe_substitute(context) outputs.append(template_file_name) diff --git a/remoting/tools/verify_resources.py b/remoting/tools/verify_resources.py index 4ffd494..eb59b2f 100755 --- a/remoting/tools/verify_resources.py +++ b/remoting/tools/verify_resources.py @@ -62,7 +62,7 @@ def ExtractTagFromLine(file_type, line): # Javascript style m = re.search('/\*i18n-content\*/[\'"]([^\`"]*)[\'"]', line) if m: return m.group(1) - elif file_type == 'cc': + elif file_type == 'cc' or file_type == 'mm': # C++ style m = re.search('IDR_([A-Z0-9_]*)', line) if m: return m.group(1) @@ -89,7 +89,7 @@ def VerifyFile(filename, messages, used_tags): base_name, extension = os.path.splitext(filename) extension = extension[1:] - if extension not in ['js', 'cc', 'html', 'json', 'jinja2']: + if extension not in ['js', 'cc', 'html', 'json', 'jinja2', 'mm']: raise Exception("Unknown file type: %s" % extension) result = True diff --git a/remoting/unittests-Info.plist b/remoting/unittests-Info.plist new file mode 100644 index 0000000..fcb8ee6 --- /dev/null +++ b/remoting/unittests-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.chromium.chromoting.remoting_unittests + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BRPL + CFBundleShortVersionString + 1.0.0.0 + CFBundleVersion + 1.0.0.0 + CFBundleSignature + ${CHROMIUM_CREATOR} + LSMinimumSystemVersion + 10.5.0 + + diff --git a/remoting/webapp/build-webapp.py b/remoting/webapp/build-webapp.py index d221d3d..384aaf1 100755 --- a/remoting/webapp/build-webapp.py +++ b/remoting/webapp/build-webapp.py @@ -124,21 +124,23 @@ def buildWebApp(buildtype, version, mimetype, destination, zip_path, plugin, # Copy all the locales, preserving directory structure destination_locales = os.path.join(destination, "_locales") os.mkdir(destination_locales , 0775) - locale_dir = "/_locales/" + remoting_locales = os.path.join(destination, "remoting_locales") + os.mkdir(remoting_locales , 0775) for current_locale in locales: - pos = current_locale.find(locale_dir) - if (pos == -1): - raise Exception("Missing locales directory in " + current_locale) - subtree = current_locale[pos + len(locale_dir):] - pos = subtree.find("/") - if (pos == -1): - raise Exception("Malformed locale: " + current_locale) - locale_id = subtree[:pos] - messages = subtree[pos+1:] - destination_dir = os.path.join(destination_locales, locale_id) - destination_file = os.path.join(destination_dir, messages) - os.mkdir(destination_dir, 0775) - shutil.copy2(current_locale, destination_file) + extension = os.path.splitext(current_locale)[1] + if extension == '.json': + locale_id = os.path.split(os.path.split(current_locale)[0])[1] + destination_dir = os.path.join(destination_locales, locale_id) + destination_file = os.path.join(destination_dir, + os.path.split(current_locale)[1]) + os.mkdir(destination_dir, 0775) + shutil.copy2(current_locale, destination_file) + elif extension == '.pak': + destination_file = os.path.join(remoting_locales, + os.path.split(current_locale)[1]) + shutil.copy2(current_locale, destination_file) + else: + raise Exception("Unknown extension: " + current_locale); # Create fake plugin files to appease the manifest checker. # It requires that if there is a plugin listed in the manifest that -- cgit v1.1