2 // Open Service Platform
\r
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
\r
5 // Licensed under the Apache License, Version 2.0 (the License);
\r
6 // you may not use this file except in compliance with the License.
\r
7 // You may obtain a copy of the License at
\r
9 // http://www.apache.org/licenses/LICENSE-2.0
\r
11 // Unless required by applicable law or agreed to in writing, software
\r
12 // distributed under the License is distributed on an "AS IS" BASIS,
\r
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
14 // See the License for the specific language governing permissions and
\r
15 // limitations under the License.
\r
19 * @file FUiIme_InputMethodManagerImpl.cpp
\r
20 * @brief This is the implementation file for the %_InputMethodManagerImpl class.
\r
22 * This implementation file contains definition of the %_InputMethodManagerImpl class.
\r
27 #include <unique_ptr.h>
\r
29 #include <isf_control.h>
\r
31 #include <FAppPkgPackageInfo.h>
\r
32 #include <FBaseColArrayList.h>
\r
33 #include <FBaseColTypes.h>
\r
34 #include <FBaseString.h>
\r
35 #include <FBaseSysLog.h>
\r
36 #include <FLclLocale.h>
\r
37 #include <FUiImeInputMethodInfo.h>
\r
39 #include <FApp_AppManagerImpl.h>
\r
40 #include <FBase_StringConverter.h>
\r
42 #include "FUiIme_InputMethodInfoImpl.h"
\r
43 #include "FUiIme_InputMethodManagerImpl.h"
\r
45 using namespace Tizen::App;
\r
46 using namespace Tizen::App::Package;
\r
47 using namespace Tizen::Base;
\r
48 using namespace Tizen::Base::Collection;
\r
49 using namespace Tizen::Locales;
\r
51 const AppId PRELOADED_IME_APPID = "sja4pgHCvq.Tizen";
\r
52 const char* PRELOADED_IME_UUID = "12aa3425-f88d-45f4-a509-cee8dfe904e3";
\r
53 const char* PRELOADED_IME_LANGUAGE = "eng-US";
\r
55 namespace Tizen { namespace Ui { namespace Ime {
\r
57 _InputMethodManagerImpl* _InputMethodManagerImpl::__pInputMethodManagerImpl = null;
\r
59 _InputMethodManagerImpl::_InputMethodManagerImpl(void)
\r
60 :__pInputMethodManager(null)
\r
61 ,__pInputMethodAppIdList(null)
\r
65 _InputMethodManagerImpl::~_InputMethodManagerImpl(void)
\r
67 __pInputMethodManagerImpl = null;
\r
69 delete __pInputMethodAppIdList;
\r
70 __pInputMethodAppIdList = null;
\r
72 __pInputMethodManager = null;
\r
76 _InputMethodManagerImpl::Construct(void)
\r
78 result r = E_SUCCESS;
\r
80 __pInputMethodAppIdList = new(std::nothrow) ArrayList(SingleObjectDeleter);
\r
81 SysTryReturnResult(NID_UI_IME, __pInputMethodAppIdList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
83 r = __pInputMethodAppIdList->Construct();
\r
84 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
89 delete __pInputMethodAppIdList;
\r
90 __pInputMethodAppIdList = null;
\r
95 _InputMethodManagerImpl*
\r
96 _InputMethodManagerImpl::GetInstance(InputMethodManager& inputMethodManager)
\r
98 result r = E_SUCCESS;
\r
100 if (!__pInputMethodManagerImpl)
\r
102 __pInputMethodManagerImpl = new(std::nothrow) _InputMethodManagerImpl();
\r
103 SysTryReturn(NID_UI_IME, __pInputMethodManagerImpl, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
105 r = __pInputMethodManagerImpl->Construct();
\r
106 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
108 __pInputMethodManagerImpl->__pInputMethodManager = &inputMethodManager;
\r
111 return __pInputMethodManagerImpl;
\r
114 delete __pInputMethodManagerImpl;
\r
115 __pInputMethodManagerImpl = null;
\r
121 _InputMethodManagerImpl::GetInputMethodInfoN(const char* pAppRootPath)
\r
123 SysLog(NID_UI_IME, "The root path of the application is %s.", pAppRootPath);
\r
125 result r = E_SUCCESS;
\r
127 // declare variables
\r
128 xmlDocPtr pXmlDoc = null;
\r
129 xmlNodePtr pXmlRootElement = null;
\r
130 InputMethodInfo* pInputMethodInfo = null;
\r
132 // get the manifest file path
\r
133 const char* MANIFEST_FILE_PATH = "/info/manifest.xml";
\r
135 int length = strlen(pAppRootPath) + strlen(MANIFEST_FILE_PATH) + 1;
\r
136 char manifestFilePath[length];
\r
137 memset(manifestFilePath, '\0', length);
\r
139 strncpy(manifestFilePath, pAppRootPath, strlen(pAppRootPath));
\r
140 strcat(manifestFilePath, MANIFEST_FILE_PATH);
\r
142 // get InputMethodInfo
\r
143 pXmlDoc = xmlParseFile(manifestFilePath);
\r
144 SysTryReturn(NID_UI_IME, pXmlDoc, null, E_SYSTEM, "[E_SYSTEM] A failure occurs from the underlying system.");
\r
146 pXmlRootElement = xmlDocGetRootElement(pXmlDoc);
\r
147 SysTryCatch(NID_UI_IME, pXmlRootElement, , E_SYSTEM, "[E_SYSTEM] A failure occurs from the underlying system.");
\r
149 pInputMethodInfo = new(std::nothrow) InputMethodInfo();
\r
150 SysTryCatch(NID_UI_IME, pInputMethodInfo, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
152 r = ParseInputMethodInfo(pXmlRootElement, pInputMethodInfo);
\r
153 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
157 xmlFreeDoc(pXmlDoc);
\r
161 xmlCleanupParser();
\r
163 return pInputMethodInfo;
\r
168 xmlFreeDoc(pXmlDoc);
\r
172 xmlCleanupParser();
\r
174 delete pInputMethodInfo;
\r
180 _InputMethodManagerImpl::ParseInputMethodInfo(const xmlNodePtr pXmlRootElement, InputMethodInfo* pInfo)
\r
182 SysTryReturnResult(NID_UI_IME, pXmlRootElement && pInfo, E_INVALID_ARG, "Invalid argument(s) is used. The pXmlRootElement or the pInfo is null.");
\r
184 result r = E_SUCCESS;
\r
186 _InputMethodInfoImpl* pInputMethodInfoImpl = _InputMethodInfoImpl::GetInstance(*pInfo);
\r
188 xmlNodePtr pItorNode = null;
\r
190 for (pItorNode = pXmlRootElement; pItorNode != null; pItorNode = pItorNode->next)
\r
192 if (pItorNode->type == XML_ELEMENT_NODE)
\r
194 if (!xmlStrcmp(pItorNode->name, reinterpret_cast<const xmlChar*>("Id")))
\r
196 xmlChar* pXmlChar = xmlNodeGetContent(pItorNode);
\r
199 pInputMethodInfoImpl->SetAppId(reinterpret_cast<char*>(pXmlChar));
\r
200 SysLog(NID_UI_IME, "The package ID is %s.", reinterpret_cast<char*>(pXmlChar));
\r
204 else if (!xmlStrcmp(pItorNode->name, reinterpret_cast<const xmlChar*>("Uuid")))
\r
206 xmlChar* pXmlChar = xmlNodeGetContent(pItorNode);
\r
209 pInputMethodInfoImpl->SetUuid(reinterpret_cast<char*>(pXmlChar));
\r
210 SysLog(NID_UI_IME, "The UUID is %s.", reinterpret_cast<char*>(pXmlChar));
\r
214 else if (!xmlStrcmp(pItorNode->name, reinterpret_cast<const xmlChar*>("DisplayName")))
\r
216 xmlChar* pXmlChar = xmlNodeGetContent(pItorNode);
\r
219 AppId appId = pInputMethodInfoImpl->GetAppId();
\r
220 appId += String(".");
\r
221 appId += String(reinterpret_cast<char*>(pXmlChar));
\r
222 pInputMethodInfoImpl->SetAppId(appId);
\r
224 pInputMethodInfoImpl->SetName(String(reinterpret_cast<char*>(pXmlChar)));
\r
225 SysLog(NID_UI_IME, "The name is %s.", reinterpret_cast<char*>(pXmlChar));
\r
229 else if (!xmlStrcmp(pItorNode->name, reinterpret_cast<const xmlChar*>("Language")))
\r
231 xmlChar* pXmlChar = xmlNodeGetContent(pItorNode);
\r
234 pInputMethodInfoImpl->AddLanguage(reinterpret_cast<char*>(pXmlChar));
\r
235 SysLog(NID_UI_IME, "The language is %s.", reinterpret_cast<char*>(pXmlChar));
\r
240 if (pItorNode->children)
\r
242 ParseInputMethodInfo(pItorNode->children, pInfo);
\r
251 _InputMethodManagerImpl::PackageManagerAppIdHandler(pkgmgrinfo_appinfo_h handle, void* pUserData)
\r
253 result r = E_SUCCESS;
\r
255 char* appId = NULL;
\r
256 pkgmgrinfo_appinfo_get_appid(handle, &appId);
\r
258 ArrayList* pInputMethodAppIdList = null;
\r
260 AppId* pAppId = new(std::nothrow) AppId(appId);
\r
261 SysTryReturn(NID_UI_IME, pAppId, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
263 pInputMethodAppIdList = static_cast<ArrayList*>(__pInputMethodManagerImpl->GetInputMethodAppIdList());
\r
264 r = pInputMethodAppIdList->Add(pAppId);
\r
265 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
267 SysLog(NID_UI_IME, "The application ID of the input method installed in the system is %s.", appId);
\r
278 _InputMethodManagerImpl::GetCurrentInputMethodInfoN(void) const
\r
280 InputMethodInfo* pInputMethodInfo = null;
\r
283 char* pUuid = null;
\r
284 length = scim::isf_control_get_active_ise(&pUuid);
\r
285 SysTryReturn(NID_UI_IME, (length != -1) && pUuid, null, E_SYSTEM,
\r
286 "[E_SYSTEM] A failure occurs from the underlying system. The uuid length of the current input method is %d", length);
\r
288 // need to implement
\r
292 return pInputMethodInfo;
\r
296 _InputMethodManagerImpl::GetInputMethodAppIdList(void) const
\r
298 return __pInputMethodAppIdList;
\r
302 _InputMethodManagerImpl::GetInputMethodInfoListN(void) const
\r
304 result r = E_SUCCESS;
\r
306 int ospImeCount = 0;
\r
308 ArrayList* pInputMethodInfoList = null;
\r
309 InputMethodInfo* pInputMethodInfo = null;
\r
310 _InputMethodInfoImpl* pInputMethodInfoImpl = null;
\r
312 char* pAppRootPath = null;
\r
314 // get preloaded IME info
\r
315 char** dpList = null;
\r
316 int preloadedImeCount = scim::isf_control_get_ise_list(&dpList);
\r
317 SysTryReturn(NID_UI_IME, (dpList != null) && (preloadedImeCount > 0), null, E_SYSTEM, "[E_SYSTEM] A failure occurs from the underlying system.");
\r
320 char* pName = null;
\r
321 char* pLanguage = null;
\r
322 scim::ISE_TYPE_T type;
\r
325 int preloadedImeIndex = -1;
\r
327 for (int i = 0; i < preloadedImeCount; i++)
\r
329 if (!strcmp(dpList[i], PRELOADED_IME_UUID))
\r
331 ret = scim::isf_control_get_ise_info(dpList[i], &pName, &pLanguage, type, option);
\r
332 SysTryCatch(NID_UI_IME, ret == 0, , E_SYSTEM, "[E_SYSTEM] A failure occurs from the underlying system.");
\r
334 preloadedImeCount = 1;
\r
335 preloadedImeIndex = i;
\r
340 // get osp IME info
\r
341 r = RequestInputMethodAppIdList();
\r
342 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
344 ospImeCount = __pInputMethodAppIdList->GetCount();
\r
346 // make a InputMethodInfo list
\r
347 pInputMethodInfoList = new(std::nothrow) ArrayList(SingleObjectDeleter);
\r
348 SysTryCatch(NID_UI_IME, pInputMethodInfoList, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
350 r = pInputMethodInfoList->Construct(preloadedImeCount + ospImeCount);
\r
351 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
353 // add preloaded IME info
\r
354 pInputMethodInfo = new(std::nothrow) InputMethodInfo();
\r
355 SysTryCatch(NID_UI_IME, pInputMethodInfo, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
357 pInputMethodInfoImpl = _InputMethodInfoImpl::GetInstance(*pInputMethodInfo);
\r
358 r = GetLastResult();
\r
359 SysTryCatch(NID_UI_IME, pInputMethodInfoImpl, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
361 pInputMethodInfoImpl->SetAppId(PRELOADED_IME_APPID);
\r
362 pInputMethodInfoImpl->SetUuid(dpList[preloadedImeIndex]);
\r
363 pInputMethodInfoImpl->SetName(String(pName));
\r
364 pInputMethodInfoImpl->AddLanguage(PRELOADED_IME_LANGUAGE);
\r
366 SysLog(NID_UI_IME, "The UUID of the preloaded IME application is %s.", dpList[preloadedImeIndex]);
\r
368 r = pInputMethodInfoList->Add(pInputMethodInfo);
\r
369 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
370 pInputMethodInfo = null;
\r
376 // add osp IME info
\r
377 for (int i = 0; i < ospImeCount; i++)
\r
379 AppId* pAppId = static_cast<AppId*>(__pInputMethodAppIdList->GetAt(i));
\r
380 r = GetLastResult();
\r
381 SysTryCatch(NID_UI_IME, pAppId, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
383 String appRootPath;
\r
384 r = _AppManagerImpl::GetAppRootPath(*pAppId, appRootPath);
\r
385 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
387 pAppRootPath = _StringConverter::CopyToCharArrayN(appRootPath.GetPointer());
\r
388 r = GetLastResult();
\r
389 SysTryCatch(NID_UI_IME, pAppRootPath, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
391 pInputMethodInfo = GetInputMethodInfoN(pAppRootPath);
\r
392 r = GetLastResult();
\r
393 SysTryCatch(NID_UI_IME, pInputMethodInfo, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
395 r = pInputMethodInfoList->Add(pInputMethodInfo);
\r
396 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
398 delete[] pAppRootPath;
\r
401 return pInputMethodInfoList;
\r
408 delete pInputMethodInfoList;
\r
409 delete pInputMethodInfo;
\r
410 delete[] pAppRootPath;
\r
416 _InputMethodManagerImpl::SetInputMethod(AppId id)
\r
418 result r = E_SUCCESS;
\r
420 std::unique_ptr<char[]> pLog(_StringConverter::CopyToCharArrayN(id.GetPointer()));
\r
421 SysLog(NID_UI_IME, "The application ID is %s.", pLog.get());
\r
423 if (id == PRELOADED_IME_APPID)
\r
425 char** dpList = null;
\r
426 int preloadedImeCount = scim::isf_control_get_ise_list(&dpList);
\r
427 SysTryReturnResult(NID_UI_IME, (dpList != null) && (preloadedImeCount > 0), E_SYSTEM, "A failure occurs from the underlying system.");
\r
429 for (int i = 0; i < preloadedImeCount; i++)
\r
431 if (!strcmp(dpList[i], PRELOADED_IME_UUID))
\r
433 scim::isf_control_set_active_ise_by_uuid(dpList[i]);
\r
443 String appRootPath;
\r
444 char* pAppRootPath = null;
\r
445 InputMethodInfo* pInputMethodInfo = null;
\r
446 _InputMethodInfoImpl* pInputMethodInfoImpl = null;
\r
448 r = _AppManagerImpl::GetAppRootPath(id, appRootPath);
\r
449 SysTryReturnResult(NID_UI_IME, r == E_SUCCESS, r, "Propagating.");
\r
451 pAppRootPath = _StringConverter::CopyToCharArrayN(appRootPath.GetPointer());
\r
452 r = GetLastResult();
\r
453 SysTryReturnResult(NID_UI_IME, pAppRootPath, r, "Propagating.");
\r
455 pInputMethodInfo = GetInputMethodInfoN(pAppRootPath);
\r
456 r = GetLastResult();
\r
457 SysTryCatch(NID_UI_IME, pInputMethodInfo, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
459 pInputMethodInfoImpl = _InputMethodInfoImpl::GetInstance(*pInputMethodInfo);
\r
460 scim::isf_control_set_active_ise_by_uuid(pInputMethodInfoImpl->GetUuid());
\r
464 delete[] pAppRootPath;
\r
465 delete pInputMethodInfo;
\r
471 _InputMethodManagerImpl::GetInputMethodLanguageListN(const char* pLanguageList) const
\r
473 SysTryReturn(NID_UI_IME, pLanguageList, null, E_INVALID_ARG, "Invalid argument(s) is used. The pLanguageList is null.");
\r
475 result r = E_SUCCESS;
\r
477 const char* pItor = pLanguageList;
\r
479 const int ISO_639_1_CODE_LENGTH = 5;
\r
480 char arrayLanguage[ISO_639_1_CODE_LENGTH + 1];
\r
481 memset(arrayLanguage, '\0', sizeof(arrayLanguage));
\r
483 const int LANGUAGE_CODE_LENGTH = 2;
\r
484 char arrayLanguageCode[LANGUAGE_CODE_LENGTH + 1];
\r
485 memset(arrayLanguageCode, '\0', sizeof(arrayLanguageCode));
\r
487 const int COUNTRY_CODE_LENGTH = 2;
\r
488 char arrayCountryCode[COUNTRY_CODE_LENGTH + 1];
\r
489 memset(arrayCountryCode, '\0', sizeof(arrayCountryCode));
\r
491 Locale* pLanguage = null;
\r
493 ArrayList* pInputMethodLanguageList = new(std::nothrow) ArrayList(SingleObjectDeleter);
\r
494 SysTryReturn(NID_UI_IME, pInputMethodLanguageList, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
496 r = pInputMethodLanguageList->Construct();
\r
497 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
499 while ( pItor != null)
\r
501 strncpy(arrayLanguage, pItor, ISO_639_1_CODE_LENGTH);
\r
503 strncpy(arrayLanguageCode, arrayLanguage, LANGUAGE_CODE_LENGTH);
\r
504 strncpy(arrayCountryCode, arrayLanguage + LANGUAGE_CODE_LENGTH + 1, COUNTRY_CODE_LENGTH);
\r
506 LanguageCode languageCode = Locale::TwoLetterLanguageCodeStringToLanguageCode(String(arrayLanguageCode));
\r
507 r = GetLastResult();
\r
508 SysTryCatch(NID_UI_IME, languageCode < LANGUAGE_MAX, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
510 CountryCode countryCode = Locale::StringToCountryCode(String(arrayCountryCode));
\r
511 r = GetLastResult();
\r
512 SysTryCatch(NID_UI_IME, countryCode < COUNTRY_MAX, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
514 pLanguage = new(std::nothrow) Locale(languageCode, countryCode);
\r
515 SysTryCatch(NID_UI_IME, pLanguage, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
\r
517 r = pInputMethodLanguageList->Add(pLanguage);
\r
518 SysTryCatch(NID_UI_IME, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
\r
521 memset(arrayLanguage, '\0', sizeof(arrayLanguage));
\r
522 memset(arrayLanguageCode, '\0', sizeof(arrayLanguageCode));
\r
523 memset(arrayCountryCode, '\0', sizeof(arrayCountryCode));
\r
526 pItor = strchr(pItor, ch);
\r
533 return pInputMethodLanguageList;
\r
537 delete pInputMethodLanguageList;
\r
543 _InputMethodManagerImpl::RequestInputMethodAppIdList(void) const
\r
545 result r = E_SUCCESS;
\r
547 __pInputMethodAppIdList->RemoveAll();
\r
550 pkgmgrinfo_appinfo_filter_h handle;
\r
551 ret = pkgmgrinfo_appinfo_filter_create(&handle);
\r
552 SysTryReturnResult(NID_UI_IME, ret == PMINFO_R_OK, E_SYSTEM, "A failure occurs from the underlying system.");
\r
554 ret = pkgmgrinfo_appinfo_filter_add_string(handle, PMINFO_APPINFO_PROP_APP_CATEGORY, "http://tizen.org/category/ime");
\r
555 SysTryCatch(NID_UI_IME, ret == PMINFO_R_OK, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A failure occurs from the underlying system.");
\r
557 ret = pkgmgrinfo_appinfo_filter_foreach_appinfo(handle, PackageManagerAppIdHandler, NULL);
\r
558 SysTryCatch(NID_UI_IME, ret == PMINFO_R_OK, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A failure occurs from the underlying system.");
\r
562 pkgmgrinfo_appinfo_filter_destroy(handle);
\r
567 }}} // Tizen::Ui::Ime
\r