Add Setting feature on system-server lib
[platform/framework/native/appfw.git] / src / system-server / 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"locale.time_zone";
69 static const wchar_t* _LOCALE_UPDATE_AUTO= L"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"locale.date";
77 static const wchar_t* _LOCALE_TIME = L"locale.time";
78 static const wchar_t* _LOCALE_DATETIME = L"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                         pTZPath[nLen] = '\0';
381                 }
382                 else
383                 {
384                         SysLogException(NID_SYS, E_SYSTEM, "It is failed to get timezone");
385                 }
386                 value.Clear();
387                 value.Append(&pTZPath[_LOCALE_TIMEZONE_ROOT_PATH_LENGTH]);
388         }
389         else if (key == _LOCALE_DATE)
390         {
391                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support date feature.");
392                 r = E_SUCCESS;
393
394                 DateTime currentTime;
395                 SystemTime::GetCurrentTime(TIME_MODE_WALL, currentTime);
396                 String currentFormat;
397                 GetValue(_LOCALE_DATE_FORMAT, currentFormat);
398
399                 unique_ptr<DateTimeFormatter> pFormatter(DateTimeFormatter::CreateTimeFormatterN());
400                 SysTryReturnResult(NID_SYS, pFormatter != null, E_OUT_OF_MEMORY, "It is failed to create DateTimeFomatter");
401                 pFormatter->ApplyPattern(currentFormat);
402                 value.Clear();
403                 pFormatter->Format(currentTime, value);
404         }
405         else if (key == _LOCALE_DATETIME)
406         {
407                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support date time feature.");
408                 r = E_SUCCESS;
409
410                 DateTime currentTime;
411                 SystemTime::GetCurrentTime(TIME_MODE_WALL, currentTime);
412                 String currentFormat;
413                 GetValue(_LOCALE_DATETIME_FORMAT, currentFormat);
414
415                 unique_ptr<DateTimeFormatter> pFormatter(DateTimeFormatter::CreateTimeFormatterN());
416                 pFormatter->ApplyPattern(currentFormat);
417                 value.Clear();
418                 pFormatter->Format(currentTime, value);
419         }
420         else if (key == _LOCALE_TIME)
421         {
422                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support time feature.");
423                 r = E_SUCCESS;
424
425                 DateTime currentTime;
426                 SystemTime::GetCurrentTime(TIME_MODE_WALL, currentTime);
427                 String currentFormat;
428                 GetValue(_LOCALE_TIME_FORMAT, currentFormat);
429
430                 unique_ptr<DateTimeFormatter> pFormatter(DateTimeFormatter::CreateTimeFormatterN());
431                 pFormatter->ApplyPattern(currentFormat);
432                 value.Clear();
433                 pFormatter->Format(currentTime, value);
434         }
435         return r;
436 }
437
438 result
439 _SettingLocaleProvider::SetValue(const String& key, const String value)
440 {
441         int errorCode = 0;
442         result r = E_OBJ_NOT_FOUND;
443
444         if(key == _LOCALE_COUNTRY || key == _LOCALE_LANGUAGE)
445         {
446                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support locale country selection feature.");
447
448                 r = E_SUCCESS;
449
450                 unique_ptr<char []> lang (_StringConverter::CopyToCharArrayN(value));
451                 SysTryReturnResult(NID_SYS, lang != null, E_SYSTEM, "It is failed to convert String to string");
452
453                 icu::Locale locale(lang.get());
454                 errorCode = locale.isBogus();
455                 SysTryReturnResult(NID_SYS, errorCode == 0 && IsValidLocaleString(value, locale) == true, E_INVALID_ARG, "Unknown language format");
456
457                 std::string localeCode(locale.getLanguage());
458                 localeCode.append("_");
459                 localeCode.append(locale.getCountry());
460
461                 const char* vconfKey = null;
462
463                 if (key == _LOCALE_LANGUAGE)
464                 {
465                         SysTryReturnResult(NID_SYS, IsSupportedDisplayLanguageLocale(localeCode.c_str()),
466                                 E_INVALID_ARG, "It is not the supported display language locale [%s].", localeCode.c_str());
467                         vconfKey = VCONFKEY_LANGSET;
468                         localeCode.append(".utf8");
469                 }
470                 else if (key == _LOCALE_COUNTRY)
471                 {
472                         localeCode.append(".utf8");
473                         SysTryReturnResult(NID_SYS, IsSupportedRegionLocale(localeCode.c_str()),
474                                 E_INVALID_ARG, "It is not the supported region locale [%s].", localeCode.c_str());
475                         vconfKey = VCONFKEY_REGIONFORMAT;
476                 }
477                 errorCode = vconf_set_str(vconfKey, localeCode.c_str());
478                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set on %ls vconf",key.GetPointer());
479                 r = E_SUCCESS;
480         }
481         else if(key == _LOCALE_WEEK_FORMAT_FIRSTDAY)
482         {
483                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support week format selection feature.");
484                 r = E_SUCCESS;
485
486                 int firstDay = 0;
487
488                 String sunday(_LOCALE_WEEK_FORMAT_FIRSTDAY_SUNDAY);
489                 String monday(_LOCALE_WEEK_FORMAT_FIRSTDAY_MONDAY);
490
491                 String requiredValue(value);
492                 requiredValue.ToLowerCase();
493                 sunday.ToLowerCase();
494                 monday.ToLowerCase();
495
496                 if (requiredValue == sunday)
497                 {
498                         firstDay = _LOCALE_WEEK_FORMAT_VCONF_SUNDAY;
499                 }
500                 else if (requiredValue == monday)
501                 {
502                         firstDay = _LOCALE_WEEK_FORMAT_VCONF_MONDAY;
503                 }
504                 else
505                 {
506                         return E_INVALID_ARG;
507                 }
508
509                 errorCode = vconf_set_int(VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT, firstDay);
510                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set on VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT vconf");
511         }
512         else if(key == _LOCALE_TIMEZONE)
513         {
514                 SysTryReturnResult(NID_SYS, HasKey(key) == true, E_UNSUPPORTED_OPERATION, "Current device does not support time zone feature.");
515                 r = E_SUCCESS;
516
517                 LocaleManager localeManager;
518                 localeManager.Construct();
519                 unique_ptr<IList, AllElementsDeleter> pSupportedTimeZoneList(localeManager.GetAvailableTimeZonesN());
520
521                 SysTryReturnResult(NID_SYS, pSupportedTimeZoneList != null, E_SYSTEM, "It is failed to get supported timezone list.");
522                 SysTryReturnResult(NID_SYS, pSupportedTimeZoneList->Contains(value) == true, E_INVALID_ARG, "Specified timezone id[%S] is not valid", value.GetPointer());
523
524                 unique_ptr<char []> tzpath (_StringConverter::CopyToCharArrayN(value));
525                 SysTryReturnResult(NID_SYS, tzpath != null, E_SYSTEM, "It is failed to convert String to string");
526                 std::string tzStr(_LOCALE_TIMEZONE_ROOT_PATH);
527                 tzStr.append(tzpath.get());
528                 unique_ptr<char, charDeleter> cstrTzpath (strdup(tzStr.c_str()));
529                 int errorCode = sysman_set_timezone(cstrTzpath.get());
530                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set timezone");
531
532                 errorCode = vconf_set_str(VCONFKEY_SETAPPL_TIMEZONE_ID, cstrTzpath.get()+_LOCALE_TIMEZONE_ROOT_PATH_LENGTH);
533                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to set VCONFKEY_SETAPPL_TIMEZONE_ID vconf");
534
535                 errorCode = vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, -1);
536                 SysTryReturnResult(NID_SYS, errorCode == 0, E_SYSTEM, "It is failed to notify to system about time changing");
537         }
538         return r;
539 }
540
541 bool
542 _SettingLocaleProvider::HasKey(const Tizen::Base::String& key)
543 {
544         if(key == _LOCALE_COUNTRY || key == _LOCALE_LANGUAGE)
545         {
546                 return true;
547         }
548         else if(key == _LOCALE_DATE_FORMAT || key == _LOCALE_DATETIME_FORMAT || key == _LOCALE_TIME_FORMAT || key == _LOCALE_TIME_FORMAT_24HOUR || key == _LOCALE_WEEK_FORMAT_FIRSTDAY)
549         {
550                 return true;
551         }
552         else if(key == _LOCALE_TIMEZONE || key == _LOCALE_UPDATE_AUTO)
553         {
554                 return true;
555         }
556         else if(key == _LOCALE_DATE || key == _LOCALE_TIME || _LOCALE_DATETIME)
557         {
558                 return true;
559         }
560         return false;
561 }
562
563 void
564 _SettingLocaleProvider::SettingEventRuntimeInfo(runtime_info_key_e key, void* userData)
565 {
566         result r = E_SUCCESS;
567         String settingKey;
568
569         _SettingInfo* pSettingInfo = _SettingInfo::GetInstance();
570         SysTryReturnVoidResult(NID_SYS, pSettingInfo != null, E_SYSTEM, "_SettingInfo is not ready.");
571
572         if(key == RUNTIME_INFO_KEY_REGION)
573         {
574                 settingKey = _LOCALE_DATE_FORMAT;
575                 pSettingInfo->AnnounceSettingEvent(settingKey);
576                 settingKey = _LOCALE_DATETIME_FORMAT;
577                 pSettingInfo->AnnounceSettingEvent(settingKey);
578                 settingKey = _LOCALE_TIME_FORMAT;
579                 pSettingInfo->AnnounceSettingEvent(settingKey);
580                 settingKey = _LOCALE_COUNTRY;
581                 pSettingInfo->AnnounceSettingEvent(settingKey);
582         }
583         else if(key == RUNTIME_INFO_KEY_LANGUAGE)
584         {
585                 settingKey.Append(_LOCALE_LANGUAGE);
586                 pSettingInfo->AnnounceSettingEvent(settingKey);
587         }
588         else if(key == RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED)
589         {
590                 settingKey = _LOCALE_DATETIME_FORMAT;
591                 pSettingInfo->AnnounceSettingEvent(settingKey);
592                 settingKey = _LOCALE_TIME_FORMAT;
593                 pSettingInfo->AnnounceSettingEvent(settingKey);
594                 settingKey = _LOCALE_TIME_FORMAT_24HOUR;
595         }
596         r = pSettingInfo->AnnounceSettingEvent(settingKey);
597         SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to send the event[%ls].", settingKey.GetPointer());
598 }
599
600 void
601 _SettingLocaleProvider::SettingEventVConf(keynode_t* node, void* userData)
602 {
603         result r = E_SUCCESS;
604         String settingKey;
605
606         _SettingInfo* pSettingInfo = _SettingInfo::GetInstance();
607         SysTryReturnVoidResult(NID_SYS, pSettingInfo != null, E_SYSTEM, "_SettingInfo is not ready.");
608
609         if (strcmp(VCONFKEY_SETAPPL_WEEKOFDAY_FORMAT_INT, vconf_keynode_get_name(node)) == 0)
610         {
611                 settingKey.Append(_LOCALE_WEEK_FORMAT_FIRSTDAY);
612         }
613         else if (strcmp(VCONFKEY_SYSTEM_TIME_CHANGED, vconf_keynode_get_name(node)) == 0)
614         {
615                 settingKey = _LOCALE_DATETIME;
616                 pSettingInfo->AnnounceSettingEvent(settingKey);
617                 settingKey = _LOCALE_DATE;
618                 pSettingInfo->AnnounceSettingEvent(settingKey);
619                 settingKey = _LOCALE_TIME;
620         }
621         else if (strcmp(VCONFKEY_SETAPPL_TIMEZONE_ID, vconf_keynode_get_name(node)) == 0)
622         {
623                 settingKey.Append(_LOCALE_TIMEZONE);
624         }
625         else if (strcmp(VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, vconf_keynode_get_name(node)) == 0)
626         {
627                 settingKey.Append(_LOCALE_UPDATE_AUTO);
628         }
629         else
630         {
631                 return;
632         }
633
634         r = pSettingInfo->AnnounceSettingEvent(settingKey);
635         SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to send the event[%ls].", settingKey.GetPointer());
636 }
637
638 bool
639 _SettingLocaleProvider::IsValidLocaleString(const Tizen::Base::String& localeString, const icu::Locale& icuLocale)
640 {
641         int indexOfScript = -1;
642         int indexOfCountryCode = -1;
643
644         localeString.IndexOf(L"-", 0, indexOfScript);
645         localeString.IndexOf(L"_", 0, indexOfCountryCode);
646
647         SysTryReturnResult(NID_SYS, indexOfCountryCode == 3 || (indexOfScript == 3 && indexOfCountryCode == 8)
648                                 , E_INVALID_ARG, "localeString %ls is invalid.", localeString.GetPointer());
649
650         // Tizen locale format languageCode-scriptCode_countryCode (ex: aze-latn_AZ)
651         String languageCode;
652         String scriptCode;
653         String countryCode;
654
655         localeString.SubString(0, 3, languageCode);
656
657         if (indexOfScript == 3)
658         {
659                 localeString.SubString(4, 4, scriptCode);
660         }
661
662         int countryCodeLength = (localeString.Contains(L"419") == true) ? 3 : 2;
663         int countryCodeIndex = (indexOfCountryCode == 3) ? 4 : 9;
664
665         localeString.SubString(countryCodeIndex, countryCodeLength, countryCode);
666
667         // icu locale format languageCode_ScriptCode_countryCode (ex: az_Latn_AZ)
668         String icuLanguageCode(icuLocale.getISO3Language());
669         String icuScriptCode(icuLocale.getScript());
670         String icuCountryCode(icuLocale.getCountry());
671
672         if (!icuScriptCode.IsEmpty())
673         {
674                 icuScriptCode.ToLowerCase();
675         }
676
677         if (languageCode == icuLanguageCode && scriptCode == icuScriptCode && countryCode == icuCountryCode)
678         {
679                 return true;
680         }
681
682         return false;
683 }
684
685 bool
686 _SettingLocaleProvider::IsSupportedDisplayLanguageLocale(const char* localeId)
687 {
688         xmlDocPtr doc = null;
689         xmlNodePtr cur = null;
690
691         doc = xmlParseFile(_LANGUAGE_LIST_FILE_PATH);
692         SysTryCatch(NID_SYS, doc != null, , E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
693
694         cur = xmlDocGetRootElement(doc);
695         SysTryCatch(NID_SYS, cur != null, , E_EMPTY_BODY, "[E_EMPTY_BODY] It is empty document.");
696         SysTryCatch(NID_SYS, xmlStrcmp(cur->name, (const xmlChar *) "langlist") == 0, , E_INVALID_CONTENT, "[E_INVALID_CONTENT] The document is wrong type");
697
698         cur = cur->xmlChildrenNode;
699
700         for (xmlNodePtr cur_node = cur; cur_node; cur_node = cur_node->next)
701         {
702                 if (cur_node->type == XML_ELEMENT_NODE)
703                 {
704                         char* pLocId = (char*)xmlGetProp(cur_node, (const xmlChar *)"id");
705                         if (!strcmp(localeId, pLocId))
706                         {
707                                 xmlFreeDoc(doc);
708                                 return true;
709                         }
710                 }
711         }
712
713 CATCH:
714         if (doc)
715         {
716                 xmlFreeDoc(doc);
717         }
718         return false;
719 }
720
721 bool
722 _SettingLocaleProvider::IsSupportedRegionLocale(const char* localeId)
723 {
724         locale_t cLoc = newlocale(LC_ALL_MASK, localeId, null);
725         if (cLoc == (locale_t)null)
726         {
727                 return false;
728         }
729         freelocale(cLoc);
730         return true;
731 }
732
733 } }