Merge "Apply string localization for web" into tizen_2.2
[platform/framework/native/appfw.git] / src / server / system / setting / providers / FSys_SettingLocaleProvider.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        FSys_SettingLocaleProvider.cpp
19  * @brief       This is the implementation for the _SettingLocaleProvider class.
20  */
21
22 #include <unique_ptr.h>
23 #include <sysman.h>
24 #include <libxml/xpath.h>
25 #include <libxml/tree.h>
26 #include <locale.h>
27
28 #include <FApp.h>
29 #include <FBase.h>
30 #include <FBaseSysLog.h>
31 #include <FLocales.h>
32
33 #include <FBase_StringConverter.h>
34
35 #include "FSys_SettingInfo.h"
36 #include "FSys_SettingLocaleProvider.h"
37
38 using namespace std;
39
40 using namespace Tizen::App;
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Collection;
43 using namespace Tizen::Base::Utility;
44 using namespace Tizen::Locales;
45
46 namespace Tizen { namespace System
47 {
48
49 //Language and Region
50 static const wchar_t* _LOCALE_COUNTRY = L"http://tizen.org/setting/locale.country";
51 static const wchar_t* _LOCALE_LANGUAGE = L"http://tizen.org/setting/locale.language";
52 static const char* _LANGUAGE_LIST_FILE_PATH = "/opt/usr/data/setting/langlist.xml";
53
54 //Format
55 static const wchar_t* _LOCALE_DATE_FORMAT = L"http://tizen.org/setting/locale.date.format";
56 static const wchar_t* _LOCALE_DATETIME_FORMAT = L"http://tizen.org/setting/locale.date_time.format";
57 static const wchar_t* _LOCALE_TIME_FORMAT = L"http://tizen.org/setting/locale.time.format";
58 static const wchar_t* _LOCALE_TIME_FORMAT_24HOUR = L"http://tizen.org/setting/locale.time.format.24hour";
59
60 static const wchar_t* _LOCALE_WEEK_FORMAT_FIRSTDAY = L"http://tizen.org/setting/locale.week.format.firstday";
61 static const wchar_t* _LOCALE_WEEK_FORMAT_FIRSTDAY_MONDAY = L"Monday";
62 static const wchar_t* _LOCALE_WEEK_FORMAT_FIRSTDAY_SUNDAY = L"Sunday";
63
64 static const int _LOCALE_WEEK_FORMAT_VCONF_SUNDAY = 0;
65 static const int _LOCALE_WEEK_FORMAT_VCONF_MONDAY = 1;
66
67 //Timezone
68 static const wchar_t* _LOCALE_TIMEZONE = L"http://tizen.org/setting/locale.time_zone";
69 static const wchar_t* _LOCALE_UPDATE_AUTO= L"http://tizen.org/setting/locale.update.auto";
70
71 static const char* _LOCALE_TIMEZONE_ROOT_PATH = "/usr/share/zoneinfo/";
72 static const char* _LOCALE_TIMEZONE_LINK = "/opt/etc/localtime";
73 static const int _LOCALE_TIMEZONE_ROOT_PATH_LENGTH = 20;
74
75 //Date time
76 static const wchar_t* _LOCALE_DATE = L"http://tizen.org/setting/locale.date";
77 static const wchar_t* _LOCALE_TIME = L"http://tizen.org/setting/locale.time";
78 static const wchar_t* _LOCALE_DATETIME = L"http://tizen.org/setting/locale.date_time";
79
80 struct charDeleter
81 {
82         void operator()(char* pValue)
83         {
84                 if(pValue != null)
85                 {
86                         free(pValue);
87                         pValue = null;
88                 }
89         }
90 };
91
92 _SettingLocaleProvider::_SettingLocaleProvider()
93 {
94         int errorCode = 0;
95         errorCode = runtime_info_set_changed_cb(RUNTIME_INFO_KEY_REGION, SettingEventRuntimeInfo, null);
96         if(errorCode != 0)
97         {
98                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register region event listener");
99         }
100
101         errorCode = runtime_info_set_changed_cb(RUNTIME_INFO_KEY_LANGUAGE, SettingEventRuntimeInfo, null);
102         if(errorCode != 0)
103         {
104                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register language event listener");
105         }
106
107         errorCode = runtime_info_set_changed_cb(RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, SettingEventRuntimeInfo, null);
108         if(errorCode != 0)
109         {
110                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register 24hour format event listener");
111         }
112
113         errorCode = vconf_notify_key_changed(VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT, SettingEventVConf, null);
114         if(errorCode != 0)
115         {
116                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT event listener");
117         }
118
119         errorCode = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, SettingEventVConf, null);
120         if(errorCode != 0)
121         {
122                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT event listener");
123         }
124
125         errorCode = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_ID, SettingEventVConf, null);
126         if(errorCode != 0)
127         {
128                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT event listener");
129         }
130
131         errorCode = vconf_notify_key_changed(VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, SettingEventVConf, null);
132         if(errorCode != 0)
133         {
134                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL event listener");
135         }
136 }
137
138 _SettingLocaleProvider::~_SettingLocaleProvider()
139 {
140         int errorCode = 0;
141         errorCode = runtime_info_unset_changed_cb(RUNTIME_INFO_KEY_REGION);
142         if(errorCode != 0)
143         {
144                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to unregister region event listener");
145         }
146
147         errorCode = runtime_info_unset_changed_cb(RUNTIME_INFO_KEY_LANGUAGE);
148         if(errorCode != 0)
149         {
150                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register language event listener");
151         }
152
153         errorCode = runtime_info_unset_changed_cb(RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED);
154         if(errorCode != 0)
155         {
156                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register 24hour format event listener");
157         }
158         errorCode = vconf_ignore_key_changed(VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT, SettingEventVConf);
159         if(errorCode != 0)
160         {
161                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to unregister VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT event listener");
162         }
163
164         errorCode = vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, SettingEventVConf);
165         if(errorCode != 0)
166         {
167                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT event listener");
168         }
169
170         errorCode = vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_ID, SettingEventVConf);
171         if(errorCode != 0)
172         {
173                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register VCONFKEY_SETAPPL_TIMEZONE_ID event listener");
174         }
175
176         errorCode = vconf_ignore_key_changed(VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, SettingEventVConf);
177         if(errorCode != 0)
178         {
179                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to register VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL event listener");
180         }
181 }
182
183 result
184 _SettingLocaleProvider::GetValue(const String& key, bool& value)
185 {
186         int errorCode = 0;
187         result r = E_OBJ_NOT_FOUND;
188         if(key == _LOCALE_TIME_FORMAT_24HOUR)
189         {
190                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support 24hour format feature.");
191                 r = E_SUCCESS;
192                 bool is24HoueEnabled = false;
193                 errorCode = runtime_info_get_value_bool(RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, &is24HoueEnabled);
194                 SysTryReturnResult(NID_SYS, errorCode == RUNTIME_INFO_ERROR_NONE, E_SYSTEM, "It is failed to get the SYSTEM_INFO_KEY__WIFI_SUPPORTED");
195                 value = is24HoueEnabled;
196         }
197         else if (key == _LOCALE_UPDATE_AUTO)
198         {
199                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support locale auto update feature.");
200                 r = E_SUCCESS;
201                 int isAutomaticUpdate = 0;
202                 errorCode = vconf_get_bool(VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, &isAutomaticUpdate);
203                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to get on VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL vconf");
204                 if(isAutomaticUpdate == 1)
205                 {
206                         value = true;
207                 }
208                 else
209                 {
210                         value = false;
211                 }
212         }
213         return r;
214 }
215
216 result
217 _SettingLocaleProvider::SetValue(const String& key, const bool value)
218 {
219         int errorCode = 0;
220         result r = E_OBJ_NOT_FOUND;
221
222         if(key == _LOCALE_TIME_FORMAT_24HOUR)
223         {
224                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support 24hour format feature.");
225                 r = E_SUCCESS;
226                 errorCode = vconf_set_int(VCONFKEY_REGIONFORMAT_TIME1224, value ? VCONFKEY_TIME_FORMAT_24 : VCONFKEY_TIME_FORMAT_12);
227                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set on VCONFKEY_REGIONFORMAT_TIME1224 vconf");
228         }
229         else if(key == _LOCALE_UPDATE_AUTO)
230         {
231                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support locale auto update feature.");
232                 r = E_SUCCESS;
233                 errorCode = vconf_set_bool(VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, value);
234                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set on VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL vconf");
235         }
236         return r;
237 }
238
239 result
240 _SettingLocaleProvider::GetValue(const String& key, String& value)
241 {
242         int errorCode = 0;
243         result r = E_OBJ_NOT_FOUND;
244
245         if (key == _LOCALE_COUNTRY || key == _LOCALE_LANGUAGE)
246         {
247                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support %ls feature.", key.GetPointer());
248                 r = E_SUCCESS;
249
250                 unique_ptr<char, charDeleter> pLocale(null);
251                 char* pTemp = null;
252                 runtime_info_key_e vconfKey = (key == _LOCALE_COUNTRY)
253                                         ? RUNTIME_INFO_KEY_REGION // Region locale
254                                         : RUNTIME_INFO_KEY_LANGUAGE; // Display language locale
255
256                 errorCode = runtime_info_get_value_string(vconfKey, &pTemp);
257                 SysTryReturnResult(NID_SYS, errorCode == RUNTIME_INFO_ERROR_NONE && pTemp != null, E_SYSTEM, "[E_SYSTEM] runtime_info_get_value_string [%ls] failed", key.GetPointer());
258                 pLocale.reset(pTemp);
259                 icu::Locale icuLocale(pLocale.get());
260                 String localeString(icuLocale.getISO3Language());
261                 String languageScriptTmp(icuLocale.getScript());
262
263                 if (!languageScriptTmp.IsEmpty())
264                 {
265                         String languageScript;
266                         languageScriptTmp.ToLowerCase(languageScript);
267                         localeString.Append(L"-");
268                         localeString.Append(languageScript);
269                 }
270                 localeString.Append("_");
271
272                 localeString.Append(icuLocale.getCountry());
273
274                 value = localeString;
275         }
276         else if ( key == _LOCALE_TIME_FORMAT)
277         {
278                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support date format feature.");
279                 r = E_SUCCESS;
280
281                 unique_ptr<char, charDeleter> pTimeFormat(null);
282                 char* pTemp = null;
283                 bool selected24Format = false;
284
285                 r = GetValue(_LOCALE_TIME_FORMAT_24HOUR, selected24Format);
286
287                 if (selected24Format == true)
288                 {
289                         pTemp = __icu.GetDateTimeFormatN(_ICU_TIME_24_FORMAT);
290                 }
291                 else
292                 {
293                         pTemp = __icu.GetDateTimeFormatN(_ICU_TIME_12_FORMAT);
294                 }
295                 SysTryReturnResult(NID_SYS, pTemp != null, E_SYSTEM, "Failed to get time format");
296                 pTimeFormat.reset(pTemp);
297                 r = StringUtil::Utf8ToString(pTimeFormat.get(), value);
298         }
299         else if ( key == _LOCALE_DATE_FORMAT)
300         {
301                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support date format feature.");
302                 r = E_SUCCESS;
303
304                 unique_ptr<char, charDeleter> pDateFormat(__icu.GetDateTimeFormatN(_ICU_DATE_FORMAT));
305                 SysTryReturnResult(NID_SYS, pDateFormat.get() != null, E_SYSTEM, "It is failed to get date format");
306
307                 r = StringUtil::Utf8ToString(pDateFormat.get(), value);
308         }
309         else if (key == _LOCALE_DATETIME_FORMAT)
310         {
311                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support date time format feature.");
312                 r = E_SUCCESS;
313
314                 unique_ptr<char, charDeleter> pDateFormat(__icu.GetDateTimeFormatN(_ICU_DATE_FORMAT));
315                 unique_ptr<char, charDeleter> pTimeFormat(null);
316                 char* pTemp = null;
317                 String timeFormat;
318                 bool selected24Format = false;
319
320                 SysLog(NID_SYS, "Date Time format is %s.", pDateFormat.get());
321                 SysTryReturnResult(NID_SYS, pDateFormat.get() != null, E_SYSTEM, "It is failed to get date format.");
322
323                 r = GetValue(_LOCALE_TIME_FORMAT_24HOUR, selected24Format);
324                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get time format.");
325
326                 SysLog(NID_SYS, "24hour format, %d", selected24Format);
327
328                 if (selected24Format == true)
329                 {
330                         pTemp = __icu.GetDateTimeFormatN(_ICU_TIME_24_FORMAT);
331                 }
332                 else
333                 {
334                         pTemp = __icu.GetDateTimeFormatN(_ICU_TIME_12_FORMAT);
335                 }
336
337                 SysTryReturnResult(NID_SYS, pTemp != null, E_SYSTEM, "It is failed to get time format.");
338                 pTimeFormat.reset(pTemp);
339                 r = StringUtil::Utf8ToString(pDateFormat.get(), value);
340                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to convert string to UTF8.");
341                 r = StringUtil::Utf8ToString(pTimeFormat.get(), timeFormat);
342                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to convert string to UTF8.");
343
344                 value.Append(" ");
345                 value.Append(timeFormat);
346         }
347         else if (key == _LOCALE_WEEK_FORMAT_FIRSTDAY)
348         {
349                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support week format feature.");
350                 r = E_SUCCESS;
351
352                 int firstDay = 0;
353                 int errorCode = 0;
354
355                 errorCode = vconf_get_int(VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT, &firstDay);
356                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to get on VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT vconf");
357
358                 if (firstDay == _LOCALE_WEEK_FORMAT_VCONF_SUNDAY)
359                 {
360                         value = _LOCALE_WEEK_FORMAT_FIRSTDAY_SUNDAY;
361                 }
362                 else if (firstDay == _LOCALE_WEEK_FORMAT_VCONF_MONDAY)
363                 {
364                         value = _LOCALE_WEEK_FORMAT_FIRSTDAY_MONDAY;
365                 }
366                 else
367                 {
368                         r = E_SYSTEM;
369                 }
370         }
371         else if (key == _LOCALE_TIMEZONE)
372         {
373                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support time zone feature.");
374                 r = E_SUCCESS;
375
376                 char pTZPath[256] = {0,};
377                 ssize_t nLen = readlink(_LOCALE_TIMEZONE_LINK, pTZPath, sizeof(pTZPath)-1);
378                 if (nLen != -1)
379                 {
380                         value.Clear();
381                         pTZPath[nLen] = '\0';
382                         value.Append(&pTZPath[_LOCALE_TIMEZONE_ROOT_PATH_LENGTH]);
383                 }
384                 else
385                 {
386                         SysLogException(NID_SYS, E_SYSTEM, "It is failed to get timezone from readlink.");
387                         unique_ptr<char, charDeleter> pTimeZone(vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID));
388                         SysTryReturnResult(NID_SYS, pTimeZone != null, E_SYSTEM, "It is failed to get timezone from vconf also.");
389                         value.Clear();
390                         value.Append(pTimeZone.get());
391                 }
392         }
393         else if (key == _LOCALE_DATE)
394         {
395                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support date feature.");
396                 r = E_SUCCESS;
397
398                 DateTime currentTime;
399                 SystemTime::GetCurrentTime(TIME_MODE_WALL, currentTime);
400                 String currentFormat;
401                 GetValue(_LOCALE_DATE_FORMAT, currentFormat);
402
403                 unique_ptr<DateTimeFormatter> pFormatter(DateTimeFormatter::CreateTimeFormatterN());
404                 SysTryReturnResult(NID_SYS, pFormatter != null, E_OUT_OF_MEMORY, "It is failed to create DateTimeFomatter");
405                 pFormatter->ApplyPattern(currentFormat);
406                 value.Clear();
407                 pFormatter->Format(currentTime, value);
408         }
409         else if (key == _LOCALE_DATETIME)
410         {
411                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support date time feature.");
412                 r = E_SUCCESS;
413
414                 DateTime currentTime;
415                 SystemTime::GetCurrentTime(TIME_MODE_WALL, currentTime);
416                 String currentFormat;
417                 GetValue(_LOCALE_DATETIME_FORMAT, currentFormat);
418
419                 unique_ptr<DateTimeFormatter> pFormatter(DateTimeFormatter::CreateTimeFormatterN());
420                 pFormatter->ApplyPattern(currentFormat);
421                 value.Clear();
422                 pFormatter->Format(currentTime, value);
423         }
424         else if (key == _LOCALE_TIME)
425         {
426                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support time feature.");
427                 r = E_SUCCESS;
428
429                 DateTime currentTime;
430                 SystemTime::GetCurrentTime(TIME_MODE_WALL, currentTime);
431                 String currentFormat;
432                 GetValue(_LOCALE_TIME_FORMAT, currentFormat);
433
434                 unique_ptr<DateTimeFormatter> pFormatter(DateTimeFormatter::CreateTimeFormatterN());
435                 pFormatter->ApplyPattern(currentFormat);
436                 value.Clear();
437                 pFormatter->Format(currentTime, value);
438         }
439         return r;
440 }
441
442 result
443 _SettingLocaleProvider::SetValue(const String& key, const String value)
444 {
445         int errorCode = 0;
446         result r = E_OBJ_NOT_FOUND;
447
448         if(key == _LOCALE_COUNTRY || key == _LOCALE_LANGUAGE)
449         {
450                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support locale country selection feature.");
451
452                 r = E_SUCCESS;
453
454                 unique_ptr<char []> lang (_StringConverter::CopyToCharArrayN(value));
455                 SysTryReturnResult(NID_SYS, lang != null, E_SYSTEM, "It is failed to convert String to string");
456
457                 icu::Locale locale(lang.get());
458                 errorCode = locale.isBogus();
459                 SysTryReturnResult(NID_SYS, errorCode == 0 && IsValidLocaleString(value, locale) == true, E_INVALID_ARG, "Unknown language format");
460
461                 std::string localeCode(locale.getLanguage());
462                 localeCode.append("_");
463                 localeCode.append(locale.getCountry());
464
465                 const char* vconfKey = null;
466
467                 if (key == _LOCALE_LANGUAGE)
468                 {
469                         SysTryReturnResult(NID_SYS, IsSupportedDisplayLanguageLocale(localeCode.c_str()),
470                                 E_INVALID_ARG, "It is not the supported display language locale [%s].", localeCode.c_str());
471                         vconfKey = VCONFKEY_LANGSET;
472                         localeCode.append(".utf8");
473                 }
474                 else if (key == _LOCALE_COUNTRY)
475                 {
476                         localeCode.append(".utf8");
477                         SysTryReturnResult(NID_SYS, IsSupportedRegionLocale(localeCode.c_str()),
478                                 E_INVALID_ARG, "It is not the supported region locale [%s].", localeCode.c_str());
479                         vconfKey = VCONFKEY_REGIONFORMAT;
480                 }
481                 errorCode = vconf_set_str(vconfKey, localeCode.c_str());
482                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set on %ls vconf",key.GetPointer());
483                 r = E_SUCCESS;
484         }
485         else if(key == _LOCALE_WEEK_FORMAT_FIRSTDAY)
486         {
487                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support week format selection feature.");
488                 r = E_SUCCESS;
489
490                 int firstDay = 0;
491
492                 String sunday(_LOCALE_WEEK_FORMAT_FIRSTDAY_SUNDAY);
493                 String monday(_LOCALE_WEEK_FORMAT_FIRSTDAY_MONDAY);
494
495                 String requiredValue(value);
496                 requiredValue.ToLowerCase();
497                 sunday.ToLowerCase();
498                 monday.ToLowerCase();
499
500                 if (requiredValue == sunday)
501                 {
502                         firstDay = _LOCALE_WEEK_FORMAT_VCONF_SUNDAY;
503                 }
504                 else if (requiredValue == monday)
505                 {
506                         firstDay = _LOCALE_WEEK_FORMAT_VCONF_MONDAY;
507                 }
508                 else
509                 {
510                         return E_INVALID_ARG;
511                 }
512
513                 errorCode = vconf_set_int(VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT, firstDay);
514                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set on VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT vconf");
515         }
516         else if(key == _LOCALE_TIMEZONE)
517         {
518                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support time zone feature.");
519                 r = E_SUCCESS;
520
521                 LocaleManager localeManager;
522                 localeManager.Construct();
523                 unique_ptr<IList, AllElementsDeleter> pSupportedTimeZoneList(localeManager.GetAvailableTimeZonesN());
524
525                 SysTryReturnResult(NID_SYS, pSupportedTimeZoneList != null, E_SYSTEM, "It is failed to get supported timezone list.");
526                 SysTryReturnResult(NID_SYS, pSupportedTimeZoneList->Contains(value) == true, E_INVALID_ARG, "Specified timezone id[%S] is not valid", value.GetPointer());
527
528                 unique_ptr<char []> tzpath (_StringConverter::CopyToCharArrayN(value));
529                 SysTryReturnResult(NID_SYS, tzpath != null, E_SYSTEM, "It is failed to convert String to string");
530                 std::string tzStr(_LOCALE_TIMEZONE_ROOT_PATH);
531                 tzStr.append(tzpath.get());
532                 unique_ptr<char, charDeleter> cstrTzpath (strdup(tzStr.c_str()));
533                 int errorCode = sysman_set_timezone(cstrTzpath.get());
534                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set timezone");
535
536                 errorCode = vconf_set_str(VCONFKEY_SETAPPL_TIMEZONE_ID, cstrTzpath.get()+_LOCALE_TIMEZONE_ROOT_PATH_LENGTH);
537                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set VCONFKEY_SETAPPL_TIMEZONE_ID vconf");
538
539                 errorCode = vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, -1);
540                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to notify to system about time changing");
541         }
542         return r;
543 }
544
545 bool
546 _SettingLocaleProvider::HasKey(const Tizen::Base::String& key)
547 {
548         if(key == _LOCALE_COUNTRY || key == _LOCALE_LANGUAGE)
549         {
550                 return true;
551         }
552         else if(key == _LOCALE_DATE_FORMAT || key == _LOCALE_DATETIME_FORMAT || key == _LOCALE_TIME_FORMAT || key == _LOCALE_TIME_FORMAT_24HOUR || key == _LOCALE_WEEK_FORMAT_FIRSTDAY)
553         {
554                 return true;
555         }
556         else if(key == _LOCALE_TIMEZONE || key == _LOCALE_UPDATE_AUTO)
557         {
558                 return true;
559         }
560         else if(key == _LOCALE_DATE || key == _LOCALE_TIME || _LOCALE_DATETIME)
561         {
562                 return true;
563         }
564         return false;
565 }
566
567 void
568 _SettingLocaleProvider::SettingEventRuntimeInfo(runtime_info_key_e key, void* userData)
569 {
570         result r = E_SUCCESS;
571         String settingKey;
572
573         _SettingInfo* pSettingInfo = _SettingInfo::GetInstance();
574         SysTryReturnVoidResult(NID_SYS, pSettingInfo != null, E_SYSTEM, "_SettingInfo is not ready.");
575
576         if(key == RUNTIME_INFO_KEY_REGION)
577         {
578                 settingKey = _LOCALE_DATE_FORMAT;
579                 pSettingInfo->AnnounceSettingEvent(settingKey);
580                 settingKey = _LOCALE_DATETIME_FORMAT;
581                 pSettingInfo->AnnounceSettingEvent(settingKey);
582                 settingKey = _LOCALE_TIME_FORMAT;
583                 pSettingInfo->AnnounceSettingEvent(settingKey);
584                 settingKey = _LOCALE_COUNTRY;
585         }
586         else if(key == RUNTIME_INFO_KEY_LANGUAGE)
587         {
588                 settingKey = _LOCALE_LANGUAGE;
589         }
590         else if(key == RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED)
591         {
592                 settingKey = _LOCALE_DATETIME_FORMAT;
593                 pSettingInfo->AnnounceSettingEvent(settingKey);
594                 settingKey = _LOCALE_TIME_FORMAT;
595                 pSettingInfo->AnnounceSettingEvent(settingKey);
596                 settingKey = _LOCALE_TIME_FORMAT_24HOUR;
597         }
598         else
599         {
600                 return;
601         }
602         r = pSettingInfo->AnnounceSettingEvent(settingKey);
603         SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to send the event[%ls].", settingKey.GetPointer());
604 }
605
606 void
607 _SettingLocaleProvider::SettingEventVConf(keynode_t* node, void* userData)
608 {
609         result r = E_SUCCESS;
610         String settingKey;
611
612         _SettingInfo* pSettingInfo = _SettingInfo::GetInstance();
613         SysTryReturnVoidResult(NID_SYS, pSettingInfo != null, E_SYSTEM, "_SettingInfo is not ready.");
614
615         if (strcmp(VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT, vconf_keynode_get_name(node)) == 0)
616         {
617                 settingKey.Append(_LOCALE_WEEK_FORMAT_FIRSTDAY);
618         }
619         else if (strcmp(VCONFKEY_SYSTEM_TIME_CHANGED, vconf_keynode_get_name(node)) == 0)
620         {
621                 settingKey = _LOCALE_DATETIME;
622                 pSettingInfo->AnnounceSettingEvent(settingKey);
623                 settingKey = _LOCALE_DATE;
624                 pSettingInfo->AnnounceSettingEvent(settingKey);
625                 settingKey = _LOCALE_TIME;
626         }
627         else if (strcmp(VCONFKEY_SETAPPL_TIMEZONE_ID, vconf_keynode_get_name(node)) == 0)
628         {
629                 settingKey.Append(_LOCALE_TIMEZONE);
630         }
631         else if (strcmp(VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, vconf_keynode_get_name(node)) == 0)
632         {
633                 settingKey.Append(_LOCALE_UPDATE_AUTO);
634         }
635         else
636         {
637                 return;
638         }
639
640         r = pSettingInfo->AnnounceSettingEvent(settingKey);
641         SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to send the event[%ls].", settingKey.GetPointer());
642 }
643
644 bool
645 _SettingLocaleProvider::IsValidLocaleString(const Tizen::Base::String& localeString, const icu::Locale& icuLocale)
646 {
647         int indexOfScript = -1;
648         int indexOfCountryCode = -1;
649
650         localeString.IndexOf(L"-", 0, indexOfScript);
651         localeString.IndexOf(L"_", 0, indexOfCountryCode);
652
653         SysTryReturnResult(NID_SYS, indexOfCountryCode == 3 || (indexOfScript == 3 && indexOfCountryCode == 8)
654                                 , E_INVALID_ARG, "localeString %ls is invalid.", localeString.GetPointer());
655
656         // Tizen locale format languageCode-scriptCode_countryCode (ex: aze-latn_AZ)
657         String languageCode;
658         String scriptCode;
659         String countryCode;
660
661         localeString.SubString(0, 3, languageCode);
662
663         if (indexOfScript == 3)
664         {
665                 localeString.SubString(4, 4, scriptCode);
666         }
667
668         int countryCodeLength = (localeString.Contains(L"419") == true) ? 3 : 2;
669         int countryCodeIndex = (indexOfCountryCode == 3) ? 4 : 9;
670
671         localeString.SubString(countryCodeIndex, countryCodeLength, countryCode);
672
673         // icu locale format languageCode_ScriptCode_countryCode (ex: az_Latn_AZ)
674         String icuLanguageCode(icuLocale.getISO3Language());
675         String icuScriptCode(icuLocale.getScript());
676         String icuCountryCode(icuLocale.getCountry());
677
678         if (!icuScriptCode.IsEmpty())
679         {
680                 icuScriptCode.ToLowerCase();
681         }
682
683         if (languageCode == icuLanguageCode && scriptCode == icuScriptCode && countryCode == icuCountryCode)
684         {
685                 return true;
686         }
687
688         return false;
689 }
690
691 bool
692 _SettingLocaleProvider::IsSupportedDisplayLanguageLocale(const char* localeId)
693 {
694         xmlDocPtr doc = null;
695         xmlNodePtr cur = null;
696
697         doc = xmlParseFile(_LANGUAGE_LIST_FILE_PATH);
698         SysTryCatch(NID_SYS, doc != null, , E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
699
700         cur = xmlDocGetRootElement(doc);
701         SysTryCatch(NID_SYS, cur != null, , E_EMPTY_BODY, "[E_EMPTY_BODY] It is empty document.");
702         SysTryCatch(NID_SYS, xmlStrcmp(cur->name, (const xmlChar *) "langlist") == 0, , E_INVALID_CONTENT, "[E_INVALID_CONTENT] The document is wrong type");
703
704         cur = cur->xmlChildrenNode;
705
706         for (xmlNodePtr cur_node = cur; cur_node; cur_node = cur_node->next)
707         {
708                 if (cur_node->type == XML_ELEMENT_NODE)
709                 {
710                         char* pLocId = (char*)xmlGetProp(cur_node, (const xmlChar *)"id");
711                         if (!strcmp(localeId, pLocId))
712                         {
713                                 xmlFreeDoc(doc);
714                                 return true;
715                         }
716                 }
717         }
718
719 CATCH:
720         if (doc)
721         {
722                 xmlFreeDoc(doc);
723         }
724         return false;
725 }
726
727 bool
728 _SettingLocaleProvider::IsSupportedRegionLocale(const char* localeId)
729 {
730         locale_t cLoc = newlocale(LC_ALL_MASK, localeId, null);
731         if (cLoc == (locale_t)null)
732         {
733                 return false;
734         }
735         freelocale(cLoc);
736         return true;
737 }
738
739 } }