2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FLcl_LocaleManagerImpl.cpp
20 * @brief This is the implementation file for _LocaleManagerImpl class.
22 #include <unique_ptr.h>
24 #include <runtime_info.h>
25 #include <unicode/calendar.h>
26 #include <unicode/timezone.h>
27 #include <libxml/parser.h>
28 #include <libxml/tree.h>
30 #include <FBaseSysLog.h>
31 #include <FBase_StringConverter.h>
33 #include "FLcl_LocaleImpl.h"
34 #include "FLcl_TimeZoneImpl.h"
35 #include "FLcl_LocaleManagerImpl.h"
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Utility;
40 using namespace Tizen::Base::Collection;
42 namespace Tizen { namespace Locales
44 static const char* LANGLIST_FILE_PATH ="/opt/data/setting/langlist.xml";
45 static const int TIMEZONE_MAX = 224;
46 static const char* TimeZoneList[TIMEZONE_MAX] =
60 "Africa/Dar_es_Salaam",
66 "Africa/Johannesburg",
87 "America/Argentina/Buenos_Aires",
98 "America/El_Salvador",
100 "America/Guadeloupe",
106 "America/Indiana/Indianapolis",
108 "America/Kentucky/Louisville",
111 "America/Los_Angeles",
114 "America/Martinique",
116 "America/Mexico_City",
117 "America/Montevideo",
122 "America/Paramaribo",
124 "America/Port-au-Prince",
125 "America/Puerto_Rico",
129 "America/Santo_Domingo",
133 "America/Tegucigalpa",
196 "Asia/Yekaterinburg",
200 "Atlantic/Reykjavik",
201 "Atlantic/South_Georgia",
202 "Australia/Adelaide",
203 "Australia/Brisbane",
204 "Australia/Canberra",
207 "Australia/Melbourne",
225 "Europe/Kaliningrad",
253 "Indian/Antananarivo",
275 _LocaleManagerImpl::GetSystemLocale(void)
278 if (runtime_info_get_value_string(RUNTIME_INFO_KEY_REGION, &pRegionPtr) == RUNTIME_INFO_ERROR_NONE)
280 SetLastResult(E_SUCCESS);
282 Locale ospLoc = _LocaleImpl(pRegionPtr).GetOspLocale();
287 SetLastResult(E_SYSTEM);
288 return Locale(LANGUAGE_INVALID, COUNTRY_INVALID, null);
292 _LocaleManagerImpl::GetAvailableLocalesN(void)
294 result r = E_SUCCESS;
296 const U_ICU_NAMESPACE::Locale* pIcuLocaleList = U_ICU_NAMESPACE::Locale::getAvailableLocales(count);
297 SysTryReturn(NID_LCL, count > 0, null, E_SYSTEM,
298 "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
300 std::unique_ptr<LinkedList, AllElementsDeleter> pAvailableLocaleList(new (std::nothrow) LinkedList());
301 SysTryReturn(NID_LCL, pAvailableLocaleList, null, E_OUT_OF_MEMORY,
302 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
304 for (int i = 0; i < count; i++)
306 SysTryReturn(NID_LCL, (pIcuLocaleList + i) != null, null, E_SYSTEM,
307 "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
309 Locale ospLocale = _LocaleImpl(*(pIcuLocaleList + i)).GetOspLocale();
310 if (_LocaleImpl::IsSupported(ospLocale))
312 Locale* pLocale = new (std::nothrow) Locale(ospLocale);
313 SysTryReturn(NID_LCL, pLocale, null, E_OUT_OF_MEMORY,
314 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
315 if (!pAvailableLocaleList->Contains(*pLocale))
317 r = pAvailableLocaleList->Add(*pLocale);
321 SetLastResult(E_SYSTEM);
328 SetLastResult(E_SUCCESS);
329 return pAvailableLocaleList.release();
333 _LocaleManagerImpl::GetSelectedLanguage(void)
337 int ret = runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &pLanguagePtr);
338 SysTryReturn(NID_LCL, ret == RUNTIME_INFO_ERROR_NONE, String(), E_SYSTEM,
339 "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
340 String language(_LocaleImpl(pLanguagePtr).GetLanguageCodeString(false));
347 _LocaleManagerImpl::GetAvailableLanguagesN(void)
352 std::unique_ptr<ArrayList, AllElementsDeleter> pAvailableLanguageList(new (std::nothrow) ArrayList());
353 SysTryCatch(NID_LCL, pAvailableLanguageList, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
355 doc = xmlParseFile(LANGLIST_FILE_PATH);
356 SysTryCatch(NID_LCL, doc != null, , E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] It is failed to get the langlist from the resource.");
358 cur = xmlDocGetRootElement(doc);
359 SysTryCatch(NID_LCL, cur != null, , E_EMPTY_BODY, "[E_EMPTY_BODY] It is empty document.");
360 SysTryCatch(NID_LCL, xmlStrcmp(cur->name, (const xmlChar *) "langlist") == 0, , E_INVALID_CONTENT, "[E_INVALID_CONTENT] The document is wrong type");
362 cur = cur->xmlChildrenNode;
364 pAvailableLanguageList->Construct();
366 for (xmlNodePtr cur_node = cur; cur_node; cur_node = cur_node->next)
368 if (cur_node->type == XML_ELEMENT_NODE)
370 char* pLocId = (char*)xmlGetProp(cur_node, (const xmlChar *)"id");
371 Locale loc = _LocaleImpl(pLocId).GetOspLocale();
372 std::unique_ptr<String> pLanguageLocaleID(new (std::nothrow) String(loc.GetLanguageCodeString()));
373 SysTryCatch(NID_LCL, pLanguageLocaleID, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed",GetErrorMessage(E_OUT_OF_MEMORY));
375 result r = pAvailableLanguageList->Add(pLanguageLocaleID.get());
376 SysTryCatch(NID_LCL, r == E_SUCCESS, null, E_SYSTEM,
377 "[%s] It is failed to add a locale string [%ls].", GetErrorMessage(E_SYSTEM), pLanguageLocaleID->GetPointer());
378 pLanguageLocaleID.release();
382 SetLastResult(E_SUCCESS);
389 return pAvailableLanguageList.release();
396 SysLog(NID_LCL, "It is calling fallback api.");
397 return GetAvailableLanguagesFallBackN();
402 _LocaleManagerImpl::GetAvailableLanguagesFallBackN(void)
404 std::unique_ptr<IList, AllElementsDeleter> pLocaleList (GetAvailableLocalesN());
405 std::unique_ptr<HashMap> pLanguageMap(new (std::nothrow) HashMap());
407 SysTryReturn(NID_LCL, pLanguageMap, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
409 pLanguageMap->Construct();
411 for (int i = 0; i < pLocaleList->GetCount() ; i++)
413 Locale* pLocale = (Locale*)pLocaleList->GetAt(i);
414 std::unique_ptr<String> pLanguageCode(new (std::nothrow) String(pLocale->GetLanguageCodeString()));
415 SysTryReturn(NID_LCL, pLanguageCode, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
417 if (!pLanguageMap->ContainsKey(*pLanguageCode))
419 std::unique_ptr<String> pDummyValue(new (std::nothrow) String());
420 SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
422 result r = pLanguageMap->Add(*(pLanguageCode.get()), *(pDummyValue.get()));
426 SetLastResult(E_SYSTEM);
429 pLanguageCode.release();
430 pDummyValue.release();
434 IList* pAvailableLanguageList;
435 pAvailableLanguageList = pLanguageMap->GetKeysN();
436 SetLastResult(E_SUCCESS);
437 pLanguageMap->RemoveAll();
438 return pAvailableLanguageList;
443 _LocaleManagerImpl::GetAvailableTimeZonesN(U_ICU_NAMESPACE::StringEnumeration* pIcuTZStrList)
445 SysTryReturn(NID_LCL, pIcuTZStrList, null, E_SYSTEM,
446 "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
448 std::unique_ptr<HashMap, AllElementsDeleter> pTimeZoneMap(new (std::nothrow) HashMap());
450 SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
451 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
452 pTimeZoneMap->Construct();
453 result r = E_SUCCESS;
454 int resultLength = -1;
455 UErrorCode ec = U_ZERO_ERROR;
456 const char* pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
457 IMap* pTZMap = GetAvailableTimeZonesN();
460 SysTryReturn(NID_LCL, pTZMap, null, r, "[%s] Fail to get available time zone list", GetErrorMessage(r));
462 while (pIcuTZStr != null)
464 String* pTimeZone = new (std::nothrow) String(pIcuTZStr);
465 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
466 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
467 if (!pTimeZoneMap->ContainsKey(*pTimeZone) && pTZMap->ContainsKey(*pTimeZone))
469 String* pDummyValue = new (std::nothrow) String();
470 r = pTimeZoneMap->Add(*pTimeZone, *pDummyValue);
476 SetLastResult(E_SYSTEM);
481 pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
483 SetLastResult(E_SUCCESS);
485 return pTimeZoneMap.release();
489 _LocaleManagerImpl::GetAvailableTimeZonesN(void)
491 std::unique_ptr<HashMap, AllElementsDeleter> pTimeZoneMap(new (std::nothrow) HashMap());
493 SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
494 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
496 result r = E_SUCCESS;
499 pTimeZoneMap->Construct();
503 String* pTimeZone = new (std::nothrow) String(TimeZoneList[index++]);
504 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
505 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
507 if (!pTimeZoneMap->ContainsKey(*pTimeZone))
509 String* pDummyValue = new (std::nothrow) String();
511 r = pTimeZoneMap->Add(*pTimeZone, *pDummyValue);
516 SetLastResult(E_SYSTEM);
520 }while (index < TIMEZONE_MAX);
522 SetLastResult(E_SUCCESS);
523 return pTimeZoneMap.release();
527 _LocaleManagerImpl::GetAvailableTimeZonesN(int rawOffset)
529 return GetAvailableTimeZonesN(U_ICU_NAMESPACE::TimeZone::createEnumeration(rawOffset * _TimeZoneImpl::ONE_MIN_IN_MILLISEC));
534 _LocaleManagerImpl::GetSystemTimeZone(void)
536 char tz[PATH_MAX + 1];
537 int len = readlink("/opt/etc/localtime", tz, PATH_MAX);
539 SysTryReturn(NID_LCL, len > 0, TimeZone(-1, ""), E_SYSTEM, "It is failed to get System Time Zone");
541 SysTryReturn(NID_LCL, len > 20, TimeZone(-1, ""), E_SYSTEM, "It is failed to get System Time Zone");
543 String tzId(tz + 20);
544 SysLog(NID_LCL, "System TimeZone id [%ls]", tzId.GetPointer());
546 result r = Tizen::Locales::TimeZone::GetTimeZone(tzId, timeZone);
547 SysTryReturn(NID_LCL, r == E_SUCCESS, TimeZone(-1, ""), r, "[%s] error occurs.", GetErrorMessage(r));
552 _LocaleManagerImpl::IsSupportedLocale(const Tizen::Locales::Locale& locale, bool& isSupportedLocale)
554 isSupportedLocale = _LocaleImpl::IsSupported(locale);