Generalize and improve current suport for l10n
authorPiotr Tworek <p.tworek@samsung.com>
Fri, 13 Feb 2015 14:56:12 +0000 (15:56 +0100)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Tue, 10 Jul 2018 06:57:09 +0000 (06:57 +0000)
Current version of chromium-efl uses two different localization systems.
First from generic chromium product (pak files), second is based around
libintl. Both systems are pretty generic and serve their purpose well
enough. The problem is our current libintl system works only on tizen,
but not on desktop. This is unfortunate considering the fact libintl is
a generic library available on almsost every unix system, not only linux.
There is no good reason to make the funcionality tizen specific.

This patch tries to fix this problem. To do this it:
1. Adds a proper gyp support for compiling portable object (po) files.
   It replaces the previous solution with inline shell code in RPM spec
   file. Spec is only responsible for packaging output produced during
   build (ninja) step.
2. All the generic code responsible for changing application locale is
   moved outside of OS_TIZEN ifdefs. The only Tizen specific part is
   usage of vconf to get current system locale. To keep the alternative
   simple desktop uses hardcoded english localization. (Can be improved
   if necessary)
3. The bindtextdomain calls are moved to
   ContentMainDelegate::BasicStartupComplete function implementations
   (one for UI another for renderer). Bindtextdomain should be called
   only once during application initialization. The filesystem location
   of translation files is not supposed to change during app lifetime.
4. Implements necessary PathsEfl support to find necessary translation
   files on desktop (out.x64/{Debug|Release}/locale.

With the patch in place all the application menus which use
libintl/gettext for translation work on both desktop and tizen. It
should make it easier to test the functionality.

On a side note I also believe that the translation files should be moved
out of ewk directory into impl. Technically they are used by the code
from impl, not ewk. Still, if we'd like to do this it might be a good
idea for a separate patch.
Reviewed by: Antonio Gomes, Kamil Klimek, Piotr Tworek, arno renevier

Change-Id: I8e06778c730a7c313a08dc195d7fff513ca7e32f
Signed-off-by: Piotr Tworek <p.tworek@samsung.com>
tizen_src/ewk/po_tizen/locale.gyp [new file with mode: 0644]
tizen_src/impl/chromium-efl.gyp
tizen_src/impl/content_main_delegate_efl.cc
tizen_src/impl/locale_efl.cc [new file with mode: 0644]
tizen_src/impl/locale_efl.h [new file with mode: 0644]
tizen_src/impl/paths_efl.cc
tizen_src/impl/web_process_content_main_delegate_efl.cc
tizen_src/packaging/chromium-efl.spec

diff --git a/tizen_src/ewk/po_tizen/locale.gyp b/tizen_src/ewk/po_tizen/locale.gyp
new file mode 100644 (file)
index 0000000..26b9527
--- /dev/null
@@ -0,0 +1,36 @@
+{
+  'variables': {
+    'msgfmt%': '/usr/bin/msgfmt',
+  },
+  'targets': [{
+    'target_name': 'locale_efl',
+    'type': 'none',
+    'sources': [
+      'bn.po',
+      'en.po',
+      'gu.po',
+      'hi.po',
+      'kn.po',
+      'ko_KR.po',
+      'ml.po',
+      'pl.po',
+      'si.po',
+      'ta.po',
+      'te.po',
+      'ur.po',
+    ],
+    'rules': [{
+      'rule_name': 'translations',
+      'message': 'MSGFMT <(RULE_INPUT_NAME)',
+      'extension': 'po',
+      'outputs': [
+        '<(PRODUCT_DIR)/locale/<(RULE_INPUT_ROOT)/LC_MESSAGES/WebKit.mo',
+      ],
+      'action': [
+        '<(msgfmt)', '-o',
+        '<(PRODUCT_DIR)/locale/<(RULE_INPUT_ROOT)/LC_MESSAGES/WebKit.mo',
+        '<(RULE_INPUT_PATH)',
+      ],
+    }],
+  }],
+}
index 15a9a11984cc95524bb987c0b35fbc3cc37b0243..d2c511124f0bd7471a58a0966480fec28a2856e0 100644 (file)
@@ -52,6 +52,7 @@
       'chromium-efl-deps.gyp:efl',
       'chromium-efl-deps.gyp:gstreamer',
       'theme/theme.gyp:tizen_theme',
+      '../ewk/po_tizen/locale.gyp:locale_efl',
       '<(chrome_src_dir)/base/allocator/allocator.gyp:allocator',
       '<(chrome_src_dir)/content/content.gyp:content',
       '<(chrome_src_dir)/content/content.gyp:content_app_browser',
       'gpu/gpu_thread_override_efl.h',
       'http_user_agent_settings_efl.cc',
       'http_user_agent_settings_efl.h',
+      'locale_efl.h',
+      'locale_efl.cc',
       'memory_purger.cc',
       'memory_purger.h',
       'message_pump_for_ui_efl.cc',
index 1e7c2c8068e45976aa5ee9f6f8433ddf55a4a774..8d75594340b6df0d3eb1bb26887d8499620f3728 100644 (file)
 #include "content_browser_client_efl.h"
 #include "gpu/gpu_thread_override_efl.h"
 #include "paths_efl.h"
-
-#if defined(OS_TIZEN)
-#include "vconf/vconf.h"
-#include <libintl.h>
-#include "paths_efl.h"
-#include "base/path_service.h"
-#include <unistd.h>
-#endif
+#include "locale_efl.h"
 
 namespace content {
 
+namespace {
 std::string SubProcessPath() {
   static std::string result;
   if (!result.empty())
@@ -72,6 +66,7 @@ void InitializeDiskCacheDir() {
     command_line->AppendSwitchPath("disk-cache-dir", disk_cache_dir);
   }
 }
+} // namespace
 
 void ContentMainDelegateEfl::PreSandboxStartup() {
   PathService::Override(base::FILE_EXE, base::FilePath(SubProcessPath()));
@@ -92,24 +87,10 @@ ContentBrowserClient* ContentMainDelegateEfl::CreateContentBrowserClient() {
   return client_.get();
 }
 
-
-#if defined(OS_TIZEN)
-void platformLanguageChanged(keynode_t* keynode, void* data) {
-  base::FilePath locale_dir;
-  PathService::Get(PathsEfl::DIR_LOCALE, &locale_dir);
-  setlocale(LC_ALL, vconf_get_str(VCONFKEY_LANGSET));
-  bindtextdomain("WebKit", locale_dir.value().c_str());
-}
-#endif
-
 bool ContentMainDelegateEfl::BasicStartupComplete(int* /*exit_code*/) {
   content::SetContentClient(&content_client_);
   PathsEfl::Register();
-
-#if defined(OS_TIZEN)
-  platformLanguageChanged(0, 0);
-  vconf_notify_key_changed(VCONFKEY_LANGSET, platformLanguageChanged, 0);
-#endif
+  LocaleEfl::Initialize();
   return false;
 }
 
diff --git a/tizen_src/impl/locale_efl.cc b/tizen_src/impl/locale_efl.cc
new file mode 100644 (file)
index 0000000..071581b
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright 2015 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "locale_efl.h"
+
+#include <libintl.h>
+#include <string>
+#include <unistd.h>
+
+#include "base/files/file_path.h"
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "content/public/common/content_switches.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "paths_efl.h"
+
+#if defined(OS_TIZEN)
+#include <vconf/vconf.h>
+#endif
+
+#if !defined(OS_TIZEN)
+typedef void keynode_t;
+#endif
+
+namespace LocaleEfl {
+
+namespace {
+
+void ReloadCorrectPakForLocale() {
+  if (!ui::ResourceBundle::HasSharedInstance())
+    return;
+
+#if defined(OS_TIZEN)
+  std::string new_locale(vconf_get_str(VCONFKEY_LANGSET));
+#else
+  std::string new_locale("en-US");
+#endif
+
+  // Note: locale from vconf is in format:
+  // xy_ZW.UTF-8
+  // blink pak files are not named same way, so we need to find correct pak.
+  std::string chosen_locale = new_locale;
+  bool pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
+      chosen_locale);
+
+  // xy_ZW.UTF-8 -> xy-ZW
+  // Note: pak files are named after IETF_language_tag, which uses '-' not '_'
+  if (!pak_exist) {
+    chosen_locale = chosen_locale.substr(0, 5);
+    if (chosen_locale.length() >=3 && chosen_locale[2] == '_')
+      chosen_locale[2] = '-';
+
+    pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
+        chosen_locale);
+  }
+
+  // xy-ZW -> xy
+  if (!pak_exist) {
+    chosen_locale = chosen_locale.substr(0, 2);
+    pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
+        chosen_locale);
+  }
+
+  if (!pak_exist) {
+    LOG(WARNING) << "Unable to find any locale pak for " << chosen_locale;
+    return;
+  }
+
+  ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(chosen_locale);
+}
+
+void PlatformLanguageChanged(keynode_t* keynode, void* data) {
+#if defined(OS_TIZEN)
+  const char* lang = vconf_get_str(VCONFKEY_LANGSET);
+#else
+  const char* lang = "en";
+#endif
+
+  if (!setlocale(LC_ALL, lang))
+    LOG(WARNING) << "Failed to set LC_ALL to: " << lang;
+
+  // FIXME: this workaround guarantees correct order of locales which will
+  // be returned by g_get_language_names() in GetApplicationLocaleInternal()
+  // from l10n_util.cc. That function ignores it's argument: pref_locale.
+  // Without this, locale can't be changed in runtime by LoadLocaleResources()
+  setenv("LANGUAGE", lang, 1);
+
+  std::string process_type = CommandLine::ForCurrentProcess()->
+      GetSwitchValueASCII(switches::kProcessType);
+  if (process_type == switches::kRendererProcess) {
+    // Note: in case when someone will use IDS_BR_* from WebProcess this needs
+    // to be enabled or those strings have to be moved to chromium locale files.
+    // bindtextdomain("browser", "/usr/apps/org.tizen.browser/res/locale");
+    ReloadCorrectPakForLocale();
+  }
+}
+} // namespace
+
+void Initialize() {
+  base::FilePath locale_dir;
+  PathService::Get(PathsEfl::DIR_LOCALE, &locale_dir);
+  bindtextdomain("WebKit", locale_dir.value().c_str());
+
+  PlatformLanguageChanged(0, 0);
+#if defined(OS_TIZEN)
+  vconf_notify_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged, 0);
+#endif
+}
+
+}
+
diff --git a/tizen_src/impl/locale_efl.h b/tizen_src/impl/locale_efl.h
new file mode 100644 (file)
index 0000000..08990a4
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2015 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+namespace LocaleEfl {
+void Initialize();
+}
index ceed7160cb1c97539733a11ab072f7cee8fa3324..0521180b679e4118c3007ad9004b92ada597f7eb 100644 (file)
@@ -27,9 +27,9 @@ const base::FilePath::CharType kApplicationDataDir[] = FILE_PATH_LITERAL("data")
 const base::FilePath::CharType kApplicationCacheDir[] = FILE_PATH_LITERAL("cache");
 const base::FilePath::CharType kDownloadsDir[] = FILE_PATH_LITERAL("/opt/usr/media/Downloads/");
 const base::FilePath::CharType kImagesDir[] = FILE_PATH_LITERAL("/opt/usr/media/Images/");
-
 #else
 const base::FilePath::CharType kEdjeThemesDir[] = FILE_PATH_LITERAL("resources");
+const base::FilePath::CharType kLocaleDir[] = FILE_PATH_LITERAL("locale");
 const base::FilePath::CharType kDownloadsDir[] = FILE_PATH_LITERAL("/tmp/");
 const base::FilePath::CharType kImagesDir[] = FILE_PATH_LITERAL("/tmp/");
 #endif
@@ -155,6 +155,10 @@ bool PathProvider(int key, base::FilePath* result) {
       *result = base::FilePath(kDataPath).Append(kEdjeThemesDir);
       return true;
 #else
+    case DIR_LOCALE:
+      PathService::Get(base::DIR_MODULE, result);
+      *result = result->Append(kLocaleDir);
+      return true;
     case EDJE_RESOURCE_DIR:
       PathService::Get(base::DIR_MODULE, result);
       *result = result->Append(kEdjeThemesDir);
index b81178703bec95864415926779f3472ba243e92b..adb76778b37b53c2d601487d404111d3bdf9ac88 100644 (file)
 #include "paths_efl.h"
 #include "renderer/content_renderer_client_efl.h"
 #include "common/content_client_efl.h"
-#if defined(OS_TIZEN)
-#include <libintl.h>
-#include <string>
-#include <unistd.h>
-#include "vconf/vconf.h"
-#endif
+#include "locale_efl.h"
 
 namespace content {
 
@@ -25,47 +20,6 @@ ContentRendererClient* WebProcessContentMainDelegateEfl::CreateContentRendererCl
   return new ContentRendererClientEfl();
 }
 
-#if defined(OS_TIZEN)
-void reloadCorrectPakForLocale() {
-  if (!ui::ResourceBundle::HasSharedInstance())
-    return;
-
-  std::string new_locale(vconf_get_str(VCONFKEY_LANGSET));
-
-  // Note: locale from vconf is in format:
-  // xy_ZW.UTF-8
-  // blink pak files are not named same way, so we need to find correct pak.
-  std::string chosen_locale = new_locale;
-  bool pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
-      chosen_locale);
-
-  // xy_ZW.UTF-8 -> xy-ZW
-  // Note: pak files are named after IETF_language_tag, which uses '-' not '_'
-  if (!pak_exist) {
-    chosen_locale = chosen_locale.substr(0, 5);
-    if (chosen_locale.length() >=3 && chosen_locale[2] == '_')
-      chosen_locale[2] = '-';
-
-    pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
-        chosen_locale);
-  }
-
-  // xy-ZW -> xy
-  if (!pak_exist) {
-    chosen_locale = chosen_locale.substr(0, 2);
-    pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
-        chosen_locale);
-  }
-
-  if (!pak_exist) {
-    LOG(WARNING) << "Unable to find any locale pak for " << chosen_locale;
-    return;
-  }
-
-  ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(chosen_locale);
-}
-#endif
-
 // ContentMainDelegate implementation:
 void WebProcessContentMainDelegateEfl::PreSandboxStartup() {
   base::FilePath pak_dir;
@@ -73,37 +27,12 @@ void WebProcessContentMainDelegateEfl::PreSandboxStartup() {
   PathService::Get(base::DIR_EXE, &pak_dir);
   pak_file = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
   ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
-#if defined(OS_TIZEN)
-  reloadCorrectPakForLocale();
-#endif
 }
 
-#if defined(OS_TIZEN)
-void webPlatformLanguageChanged(keynode_t* keynode, void* data) {
-  base::FilePath locale_dir;
-  PathService::Get(PathsEfl::DIR_LOCALE, &locale_dir);
-  setlocale(LC_ALL, vconf_get_str(VCONFKEY_LANGSET));
-
-  // FIXME: this workaround guarantees correct order of locales which will
-  // be returned by g_get_language_names() in GetApplicationLocaleInternal()
-  // from l10n_util.cc. That function ignores it's argument: pref_locale.
-  // Without this, locale can't be changed in runtime by LoadLocaleResources()
-  setenv("LANGUAGE", vconf_get_str(VCONFKEY_LANGSET), 1);
-
-  bindtextdomain("WebKit", locale_dir.value().c_str());
-  // Note: in case when someone will use IDS_BR_* from WebProcess this needs to be enabled
-  // or those strings have to be moved to chromium locale files.
-  // bindtextdomain("browser", "/usr/apps/org.tizen.browser/res/locale");
-  reloadCorrectPakForLocale();
-}
-#endif
-
 bool WebProcessContentMainDelegateEfl::BasicStartupComplete(int* exit_code) {
   PathsEfl::Register();
-#if defined(OS_TIZEN)
-  webPlatformLanguageChanged(0, 0);
-  vconf_notify_key_changed(VCONFKEY_LANGSET, webPlatformLanguageChanged, 0);
-#endif
+  LocaleEfl::Initialize();
+
   ContentClientEfl* content_client = new ContentClientEfl();
   content::SetContentClient(content_client);
   return false;
index 0d95ac9efe0d9cc31e47e85a00e5855c21c9d150..cace8926ab5c8c02cef65bbccb37d8c9a61c59f5 100644 (file)
@@ -160,7 +160,8 @@ Selenium WebDriver for t-browser
 %global CHROMIUM_DATA_DIR %{_datadir}/%{name}
 # Chromium unit tests install directory
 %global CHROMIUM_UNITTESTS_DIR /opt/usr/chromium-unittests/
-%global LOCALE_DIR /usr/share/chromium-efl
+# Directory containing localization files
+%global CHROMIUM_LOCALE_DIR %{_datadir}/%{name}/locale
 %global CHROMIUM_WEBDB_DIR /opt/usr/apps/chromium-efl
 
 %prep
@@ -228,6 +229,7 @@ fi
   -Dexe_dir="%{CHROMIUM_EXE_DIR}" \
   -Ddata_dir="%{CHROMIUM_DATA_DIR}" \
   -Dedje_dir="%{CHROMIUM_DATA_DIR}"/themes \
+  -Dlocale_dir="%{CHROMIUM_LOCALE_DIR}" \
 %if 0%{?_remove_webcore_debug_symbols:1}
   -Dremove_webcore_debug_symbols=1 \
 %endif
@@ -308,17 +310,11 @@ install -d "%{buildroot}"%{_includedir}/v8
 install -d "%{buildroot}%{CHROMIUM_EXE_DIR}"
 install -d "%{buildroot}%{CHROMIUM_EXE_DIR}/locales"
 install -d "%{buildroot}%{CHROMIUM_DATA_DIR}"/themes
-install -d "%{buildroot}%{CHROMIUM_DATA_DIR}"/locale
 %if 0%{?build_chromedriver}
 install -d "%{buildroot}"/usr/apps/com.samsung.chromedriver/bin
 %endif
 
-mkdir -p %{OUTPUT_FOLDER}/po_tizen
-for file in ewk/po_tizen/*.po; do
-  /usr/bin/msgfmt ${file} -o %{OUTPUT_FOLDER}/po_tizen/$(basename $file .po).mo
-  install -d "%{buildroot}%{CHROMIUM_DATA_DIR}"/locale/$(basename $file .po)/LC_MESSAGES
-  install -m 0755 %{OUTPUT_FOLDER}/po_tizen/$(basename $file .po).mo "%{buildroot}%{CHROMIUM_DATA_DIR}"/locale/$(basename $file .po)/LC_MESSAGES/WebKit.mo
-done
+cp -r "%{OUTPUT_FOLDER}/locale" "%{buildroot}/%{CHROMIUM_LOCALE_DIR}"
 
 install -m 0755 "%{OUTPUT_FOLDER}"/locales/*.pak      "%{buildroot}%{CHROMIUM_EXE_DIR}"/locales
 
@@ -426,7 +422,7 @@ chown -R app:app %{CHROMIUM_WEBDB_DIR}/data
 %{CHROMIUM_EXE_DIR}/content_shell.pak
 %{CHROMIUM_EXE_DIR}/locales/*.pak
 %{CHROMIUM_DATA_DIR}/themes/*.edj
-%{CHROMIUM_DATA_DIR}/locale/*
+%{CHROMIUM_LOCALE_DIR}
 
 %files devel
 %defattr(-,root,root,-)