sync with tizen_2.0
[platform/framework/native/appfw.git] / src / locales / FLcl_LocaleManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19 * @file         FLcl_LocaleManagerImpl.cpp
20 * @brief        This is the implementation file for _LocaleManagerImpl class.
21 */
22 #include <unique_ptr.h>
23 #include <limits.h>
24 #include <runtime_info.h>
25 #include <unicode/calendar.h>
26 #include <unicode/timezone.h>
27
28 #include <FBaseSysLog.h>
29 #include <FBase_StringConverter.h>
30
31 #include "FLcl_LocaleImpl.h"
32 #include "FLcl_TimeZoneImpl.h"
33 #include "FLcl_LocaleManagerImpl.h"
34
35
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Utility;
38 using namespace Tizen::Base::Collection;
39
40 namespace Tizen { namespace Locales
41 {
42
43 static const int TIMEZONE_MAX = 224;
44 static const char* TimeZoneList[TIMEZONE_MAX] =
45 {
46         "Africa/Abidjan",
47         "Africa/Accra",
48         "Africa/Addis_Ababa",
49         "Africa/Algiers",
50         "Africa/Asmara",
51         "Africa/Bamako",
52         "Africa/Bangui",
53         "Africa/Bissau",
54         "Africa/Cairo",
55         "Africa/Casablanca",
56         "Africa/Conakry",
57         "Africa/Dakar",
58         "Africa/Dar_es_Salaam",
59         "Africa/Djibouti",
60         "Africa/Douala",
61         "Africa/Freetown",
62         "Africa/Gaborone",
63         "Africa/Harare",
64         "Africa/Johannesburg",
65         "Africa/Kampala",
66         "Africa/Khartoum",
67         "Africa/Kinshasa",
68         "Africa/Lagos",
69         "Africa/Luanda",
70         "Africa/Lubumbashi",
71         "Africa/Lusaka",
72         "Africa/Malabo",
73         "Africa/Maputo",
74         "Africa/Mogadishu",
75         "Africa/Monrovia",
76         "Africa/Nairobi",
77         "Africa/Ndjamena",
78         "Africa/Niamey",
79         "Africa/Nouakchott",
80         "Africa/Ouagadougou",
81         "Africa/Tripoli",
82         "Africa/Tunis",
83         "America/Anchorage",
84         "America/Antigua",
85         "America/Argentina/Buenos_Aires",
86         "America/Asuncion",
87         "America/Barbados",
88         "America/Belize",
89         "America/Bogota",
90         "America/Caracas",
91         "America/Cayenne",
92         "America/Chicago",
93         "America/Costa_Rica",
94         "America/Denver",
95         "America/Detroit",
96         "America/El_Salvador",
97         "America/Godthab",
98         "America/Guadeloupe",
99         "America/Guatemala",
100         "America/Guayaquil",
101         "America/Guyana",
102         "America/Halifax",
103         "America/Havana",
104         "America/Indiana/Indianapolis",
105         "America/Jamaica",
106         "America/Kentucky/Louisville",
107         "America/La_Paz",
108         "America/Lima",
109         "America/Los_Angeles",
110         "America/Managua",
111         "America/Marigot",
112         "America/Martinique",
113         "America/Mazatlan",
114         "America/Mexico_City",
115         "America/Montevideo",
116         "America/Montreal",
117         "America/New_York",
118         "America/Nome",
119         "America/Panama",
120         "America/Paramaribo",
121         "America/Phoenix",
122         "America/Port-au-Prince",
123         "America/Puerto_Rico",
124         "America/Recife",
125         "America/Regina",
126         "America/Santiago",
127         "America/Santo_Domingo",
128         "America/Sao_Paulo",
129         "America/St_Johns",
130         "America/St_Thomas",
131         "America/Tegucigalpa",
132         "America/Tijuana",
133         "America/Toronto",
134         "America/Tortola",
135         "America/Vancouver",
136         "America/Winnipeg",
137         "Asia/Aden",
138         "Asia/Almaty",
139         "Asia/Amman",
140         "Asia/Anadyr",
141         "Asia/Ashgabat",
142         "Asia/Baghdad",
143         "Asia/Bahrain",
144         "Asia/Baku",
145         "Asia/Bangkok",
146         "Asia/Beirut",
147         "Asia/Bishkek",
148         "Asia/Colombo",
149         "Asia/Damascus",
150         "Asia/Dhaka",
151         "Asia/Dubai",
152         "Asia/Dushanbe",
153         "Asia/Ho_Chi_Minh",
154         "Asia/Hong_Kong",
155         "Asia/Hovd",
156         "Asia/Irkutsk",
157         "Asia/Istanbul",
158         "Asia/Jakarta",
159         "Asia/Jayapura",
160         "Asia/Jerusalem",
161         "Asia/Kabul",
162         "Asia/Kamchatka",
163         "Asia/Karachi",
164         "Asia/Kathmandu",
165         "Asia/Kolkata",
166         "Asia/Krasnoyarsk",
167         "Asia/Kuala_Lumpur",
168         "Asia/Kuwait",
169         "Asia/Macau",
170         "Asia/Magadan",
171         "Asia/Makassar",
172         "Asia/Manila",
173         "Asia/Muscat",
174         "Asia/Novokuznetsk",
175         "Asia/Novosibirsk",
176         "Asia/Omsk",
177         "Asia/Phnom_Penh",
178         "Asia/Pyongyang",
179         "Asia/Qatar",
180         "Asia/Rangoon",
181         "Asia/Riyadh",
182         "Asia/Sakhalin",
183         "Asia/Seoul",
184         "Asia/Shanghai",
185         "Asia/Singapore",
186         "Asia/Taipei",
187         "Asia/Tashkent",
188         "Asia/Tbilisi",
189         "Asia/Tehran",
190         "Asia/Tokyo",
191         "Asia/Ulan_Bator",
192         "Asia/Vladivostok",
193         "Asia/Yakutsk",
194         "Asia/Yekaterinburg",
195         "Asia/Yerevan",
196         "Atlantic/Azores",
197         "Atlantic/Canary",
198         "Atlantic/Reykjavik",
199         "Atlantic/South_Georgia",
200         "Australia/Adelaide",
201         "Australia/Brisbane",
202         "Australia/Canberra",
203         "Australia/Darwin",
204         "Australia/Hobart",
205         "Australia/Melbourne",
206         "Australia/Perth",
207         "Australia/Sydney",
208         "CST6CDT",
209         "EST5EDT",
210         "Europe/Amsterdam",
211         "Europe/Athens",
212         "Europe/Belgrade",
213         "Europe/Berlin",
214         "Europe/Bratislava",
215         "Europe/Brussels",
216         "Europe/Bucharest",
217         "Europe/Budapest",
218         "Europe/Chisinau",
219         "Europe/Copenhagen",
220         "Europe/Dublin",
221         "Europe/Helsinki",
222         "Europe/Istanbul",
223         "Europe/Kaliningrad",
224         "Europe/Kiev",
225         "Europe/Lisbon",
226         "Europe/Ljubljana",
227         "Europe/London",
228         "Europe/Luxembourg",
229         "Europe/Madrid",
230         "Europe/Malta",
231         "Europe/Minsk",
232         "Europe/Moscow",
233         "Europe/Paris",
234         "Europe/Podgorica",
235         "Europe/Prague",
236         "Europe/Riga",
237         "Europe/Rome",
238         "Europe/Samara",
239         "Europe/San_Marino",
240         "Europe/Skopje",
241         "Europe/Sofia",
242         "Europe/Stockholm",
243         "Europe/Tallinn",
244         "Europe/Vaduz",
245         "Europe/Vienna",
246         "Europe/Vilnius",
247         "Europe/Volgograd",
248         "Europe/Warsaw",
249         "Europe/Zagreb",
250         "Europe/Zurich",
251         "Indian/Antananarivo",
252         "Indian/Chagos",
253         "Indian/Maldives",
254         "Indian/Mauritius",
255         "Indian/Reunion",
256         "MST7MDT",
257         "Pacific/Auckland",
258         "Pacific/Easter",
259         "Pacific/Fiji",
260         "Pacific/Galapagos",
261         "Pacific/Guam",
262         "Pacific/Honolulu",
263         "Pacific/Midway",
264         "Pacific/Noumea",
265         "Pacific/Pago_Pago",
266         "Pacific/Tahiti",
267         "Pacific/Tarawa",
268         "Pacific/Tongatapu",
269         "PST8PDT"
270 };
271
272 Locale
273 _LocaleManagerImpl::GetSystemLocale(void)
274 {
275         char* pRegionPtr;
276         if (runtime_info_get_value_string(RUNTIME_INFO_KEY_REGION, &pRegionPtr) == RUNTIME_INFO_ERROR_NONE)
277         {
278                 SetLastResult(E_SUCCESS);
279
280                 Locale ospLoc = _LocaleImpl(pRegionPtr).GetOspLocale();
281                 free(pRegionPtr);
282                 return ospLoc;
283         }
284
285         SetLastResult(E_SYSTEM);
286         return Locale(LANGUAGE_INVALID, COUNTRY_INVALID, null);
287 }
288
289 IList*
290 _LocaleManagerImpl::GetAvailableLocalesN(void)
291 {
292         result r = E_SUCCESS;
293         int count = 0;
294         const U_ICU_NAMESPACE::Locale* pIcuLocaleList = U_ICU_NAMESPACE::Locale::getAvailableLocales(count);
295         SysTryReturn(NID_LCL, count > 0, null, E_SYSTEM,
296                                 "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
297
298         std::unique_ptr<LinkedList, AllElementsDeleter> pAvailableLocaleList(new (std::nothrow) LinkedList());
299         SysTryReturn(NID_LCL, pAvailableLocaleList, null, E_OUT_OF_MEMORY,
300                                 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
301
302         for (int i = 0; i < count; i++)
303         {
304                 SysTryReturn(NID_LCL, (pIcuLocaleList + i) != null, null, E_SYSTEM,
305                                         "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
306
307                 Locale ospLocale = _LocaleImpl(*(pIcuLocaleList + i)).GetOspLocale();
308                 if (ospLocale.GetLanguageCode() != LANGUAGE_INVALID && ospLocale.GetCountryCode() != COUNTRY_INVALID)
309                 {                       
310                         Locale* pLocale = new (std::nothrow) Locale(ospLocale);
311                         SysTryReturn(NID_LCL, pLocale, null, E_OUT_OF_MEMORY,
312                                                 "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
313                         if (!pAvailableLocaleList->Contains(*pLocale))
314                         {
315                                 r = pAvailableLocaleList->Add(*pLocale);
316                                 if (IsFailed(r))
317                                 {
318                                         delete pLocale;
319                                         SetLastResult(E_SYSTEM);
320                                         return null;
321                                 }
322                         }
323                 }
324         }
325
326         SetLastResult(E_SUCCESS);
327         return pAvailableLocaleList.release();
328 }
329
330 String
331 _LocaleManagerImpl::GetSelectedLanguage(void)
332 {
333         char* pLanguagePtr;
334
335         int ret = runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &pLanguagePtr);
336         SysTryReturn(NID_LCL, ret == RUNTIME_INFO_ERROR_NONE, String(), E_SYSTEM,
337                         "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
338         String language(_LocaleImpl(pLanguagePtr).Get3LetterCountryCodeString());
339         free(pLanguagePtr);
340
341         return language;
342 }
343
344 IList*
345 _LocaleManagerImpl::GetAvailableLanguagesN(void)
346 {       
347         result r = E_SUCCESS;
348         std::unique_ptr<IList, AllElementsDeleter> pLocaleList (GetAvailableLocalesN());
349         std::unique_ptr<HashMap> pLanguageMap(new (std::nothrow) HashMap());
350
351         SysTryReturn(NID_LCL, pLanguageMap, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
352         
353         pLanguageMap->Construct();
354
355         for (int i = 0; i < pLocaleList->GetCount() ; i++)
356         {       
357                 Locale* pLocale = (Locale*)pLocaleList->GetAt(i);
358                 std::unique_ptr<String> pLanguageCode(new (std::nothrow) String(pLocale->GetLanguageCodeString()));
359                 SysTryReturn(NID_LCL, pLanguageCode, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));  
360                 
361                 if (!pLanguageMap->ContainsKey(*pLanguageCode))
362                 {
363                         std::unique_ptr<String> pDummyValue(new (std::nothrow) String());
364                         SysTryReturn(NID_LCL, pDummyValue, null, E_OUT_OF_MEMORY,"[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
365
366                         r = pLanguageMap->Add(*(pLanguageCode.get()), *(pDummyValue.get()));
367
368                         if (IsFailed(r))
369                         {
370                                 SetLastResult(E_UNSUPPORTED_OPERATION);
371                                 return null;                            
372                         }
373                         pLanguageCode.release();
374                         pDummyValue.release();
375                 }
376         }
377
378         IList* pAvailableLanguageList;
379         pAvailableLanguageList = pLanguageMap->GetKeysN();
380         SetLastResult(E_SUCCESS);
381         pLanguageMap->RemoveAll();
382         return pAvailableLanguageList;
383 }
384
385
386 IMap*
387 _LocaleManagerImpl::GetAvailableTimeZonesN(U_ICU_NAMESPACE::StringEnumeration* pIcuTZStrList)
388 {
389         SysTryReturn(NID_LCL, pIcuTZStrList, null, E_SYSTEM,
390                                 "[%s] The method cannot proceed due to a severe system error.",GetErrorMessage(E_SYSTEM));
391
392         std::unique_ptr<HashMap, AllElementsDeleter> pTimeZoneMap(new (std::nothrow) HashMap());
393
394         SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
395                         "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
396         pTimeZoneMap->Construct();
397         result r = E_SUCCESS;
398         int resultLength = -1;
399         UErrorCode ec = U_ZERO_ERROR;
400         const char* pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
401         IMap* pTZMap = GetAvailableTimeZonesN();
402         
403         r = GetLastResult();
404         SysTryReturn(NID_LCL, pTZMap, null, r, "[%s] Fail to get available time zone list", GetErrorMessage(r));
405
406         while (pIcuTZStr != null)
407         {
408                 String* pTimeZone = new (std::nothrow) String(pIcuTZStr);
409                 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
410                                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
411                 if (!pTimeZoneMap->ContainsKey(*pTimeZone) && pTZMap->ContainsKey(*pTimeZone))
412                 {
413                         String* pDummyValue = new  (std::nothrow) String();
414                         r = pTimeZoneMap->Add(*pTimeZone, *pDummyValue);
415                         if (IsFailed(r))
416                         {
417                                 delete pTimeZone;
418                                 delete pDummyValue;
419                                 pTZMap->RemoveAll();
420                                 SetLastResult(E_SYSTEM);
421                                 return null;
422                         }
423                 }
424
425                 pIcuTZStr = pIcuTZStrList->next(&resultLength, ec);
426         }
427         SetLastResult(E_SUCCESS);
428         pTZMap->RemoveAll();
429         return pTimeZoneMap.release();
430 }
431
432 IMap*
433 _LocaleManagerImpl::GetAvailableTimeZonesN(void)
434 {
435         std::unique_ptr<HashMap, AllElementsDeleter> pTimeZoneMap(new (std::nothrow) HashMap());
436
437         SysTryReturn(NID_LCL, pTimeZoneMap, null, E_OUT_OF_MEMORY,
438                         "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
439
440         result r = E_SUCCESS;
441         int index = 0;
442         
443         pTimeZoneMap->Construct();
444
445         do
446         {   
447                 String* pTimeZone = new (std::nothrow) String(TimeZoneList[index++]);
448                 SysTryReturn(NID_LCL, pTimeZone, null, E_OUT_OF_MEMORY,
449                                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
450
451                 if (!pTimeZoneMap->ContainsKey(*pTimeZone))
452                 {                       
453                         String* pDummyValue = new  (std::nothrow) String();
454
455                         r = pTimeZoneMap->Add(*pTimeZone, *pDummyValue);
456                         if (IsFailed(r))
457                         {   
458                                 delete pTimeZone;
459                                 delete pDummyValue;
460                                 SetLastResult(E_SYSTEM);
461                                 return null;
462                         }  
463                 } 
464         }while (index < TIMEZONE_MAX);
465
466         SetLastResult(E_SUCCESS);
467         return pTimeZoneMap.release();
468 }
469
470 IMap*
471 _LocaleManagerImpl::GetAvailableTimeZonesN(int rawOffset)
472 {
473         return GetAvailableTimeZonesN(U_ICU_NAMESPACE::TimeZone::createEnumeration(rawOffset * _TimeZoneImpl::ONE_MIN_IN_MILLISEC));
474 }
475
476
477 TimeZone
478 _LocaleManagerImpl::GetSystemTimeZone(void)
479 {
480         char tz[PATH_MAX + 1];
481         int len = readlink("/opt/etc/localtime", tz, PATH_MAX);
482         std::unique_ptr<U_ICU_NAMESPACE::TimeZone> pTzICU(null);
483         if (len > 20)
484         {
485                 tz[len] = '\0';
486                 pTzICU.reset(U_ICU_NAMESPACE::TimeZone::createTimeZone(tz + 20));
487         }
488         else
489         {
490                 pTzICU.reset(U_ICU_NAMESPACE::TimeZone::createDefault());
491         }
492
493         if (pTzICU.get())
494         {
495                 _TimeZoneImpl tzImpl(*pTzICU.get(), U_ICU_NAMESPACE::Calendar::getNow());
496                 return tzImpl.GetOspTimeZone();
497         }
498
499         return TimeZone(-1, "");
500 }
501
502 result
503 _LocaleManagerImpl::IsSupportedLocale(const Tizen::Locales::Locale& locale, bool& isSupportedLocale)
504 {
505         isSupportedLocale = _LocaleImpl::GetLocaleImpl(locale)->IsLocaleSupported();
506         return E_SUCCESS;
507 }
508
509 };
510 };      // Tizen::Locales