Upstream version 8.37.183.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / tizen / tizen_locale_listener.cc
1 // Copyright (c) 2014 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "xwalk/runtime/browser/tizen/tizen_locale_listener.h"
6
7 #include <vconf.h>
8 #include <algorithm>
9
10 #include "base/logging.h"
11 #include "content/public/browser/browser_thread.h"
12
13 namespace xwalk {
14 namespace {
15 const char kTizenDefaultLocale[] = "en-GB";
16 const char kTizenLocaleListenerThreadName[] = "TizenLocaleListener";
17
18 bool TizenLocaleToBCP47Locale(const std::string& tizen_locale,
19                               std::string* out_BCP47_locale) {
20   if (tizen_locale.empty())
21     return false;
22
23   // Tizen locale format [language[_territory][.codeset][@modifier]] .
24   // Conver to BCP47 format language[-territory] .
25   *out_BCP47_locale = tizen_locale.substr(0, tizen_locale.find_first_of("."));
26   std::replace(out_BCP47_locale->begin(), out_BCP47_locale->end(), '_', '-');
27   return true;
28 }
29
30 void OnVconfLangSetChanged(keynode_t *key, void *user_data) {
31   if (vconf_keynode_get_type(key) != VCONF_TYPE_STRING)
32     return;
33   TizenLocaleListener* tizen_locale_listener =
34       static_cast<TizenLocaleListener*>(user_data);
35
36   std::string locale;
37   if (TizenLocaleToBCP47Locale(vconf_keynode_get_str(key), &locale)) {
38     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
39         base::Bind(&TizenLocaleListener::SetLocale,
40                    base::Unretained(tizen_locale_listener),
41                    locale));
42   }
43 }
44
45 std::string GetSystemLocale() {
46   std::string tizen_locale;
47   char* langset = vconf_get_str(VCONFKEY_LANGSET);
48   if (langset) {
49     tizen_locale = langset;
50   } else {
51     LOG(ERROR) << "Can not get VCONFKEY_LANGSET from vconf or "
52                << "VCONFKEY_LANGSET vlaue is not a string value";
53   }
54   free(langset);
55
56   // Tizen take en-GB as default.
57   std::string BCP47_locale(kTizenDefaultLocale);
58   TizenLocaleToBCP47Locale(tizen_locale, &BCP47_locale);
59   return BCP47_locale;
60 }
61
62 }  // namespace
63
64 TizenLocaleListener::TizenLocaleListener()
65     : SimpleThread(kTizenLocaleListenerThreadName),
66       locale_(GetSystemLocale()) {
67   vconf_notify_key_changed(VCONFKEY_LANGSET, OnVconfLangSetChanged, this);
68   main_loop_ = g_main_loop_new(NULL, FALSE);
69   Start();
70 }
71
72 TizenLocaleListener::~TizenLocaleListener() {
73   g_main_loop_quit(main_loop_);
74   g_main_loop_unref(main_loop_);
75   SimpleThread::Join();
76   vconf_ignore_key_changed(VCONFKEY_LANGSET, OnVconfLangSetChanged);
77 }
78
79 void TizenLocaleListener::Run() {
80   g_main_loop_run(main_loop_);
81 }
82
83 std::string TizenLocaleListener::GetLocale() const {
84   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
85   // Note: we can only get locale from main thread for thread safe.
86   return locale_;
87 }
88
89 void TizenLocaleListener::SetLocale(const std::string& locale) {
90   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
91   // Note: we can only set locale from main thread for thread safe.
92   // If you need set locale from other thread, please PostTask to main thread.
93   if (locale_ == locale)
94     return;
95
96   LOG(INFO) << "Locale change from " << locale_ << " to " << locale;
97   locale_ = locale;
98 }
99
100 }  // namespace xwalk