Update change log and spec for wrt-plugins-tizen_0.4.15
[platform/framework/web/wrt-plugins-tizen.git] / src / Package / PackageManager.cpp
1 //
2 // Tizen Web Device API
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 #include <dlog.h>
19 #include <glib.h>
20
21 #include <JSTizenExceptionFactory.h>
22 #include <JSTizenException.h>
23 #include <GlobalContextManager.h>
24 #include <PlatformException.h>
25
26 // to get package name by appid
27 #include <app_manager.h>
28
29 // To get cert information from package
30 #include <package_manager.h>
31 #include <package_info.h>
32
33 // To get app size and installed time
34 #include <pkgmgr-info.h>
35
36 // To use ecore_thread
37 #include <Ecore.h>
38
39 #include "PackageManager.h"
40 #include "PackageInformation.h"
41 #include "JSPackageInformation.h"
42
43 using namespace WrtDeviceApis::Commons;
44 using namespace WrtDeviceApis::CommonsJavaScript;
45 using namespace DeviceAPI::Common;
46
47 using namespace std;
48
49 #ifdef __cplusplus
50 extern "C" {
51 int package_manager_client_destroy(package_manager_request_h request);
52 }
53 #endif
54
55 namespace DeviceAPI {
56 namespace Package {
57
58 PackageInfoCallbackData::PackageInfoCallbackData(JSContextRef globalCtx): 
59         CallbackUserData(globalCtx)
60 {
61     m_exceptionCode = WrtDeviceApis::Commons::ExceptionCodes::None;
62 }
63
64 PackageInfoCallbackData::~PackageInfoCallbackData()
65 {
66         // TODO: Should I clear pkgInfos?
67 }
68
69 vector<PackageInformation> PackageInfoCallbackData::getPackageInfoList()
70 {
71         return m_pkgInfos;
72 }
73
74
75 void PackageInfoCallbackData::addPackageInfo(PackageInformation pkgInfo)
76 {
77         m_pkgInfos.push_back(pkgInfo);
78 }
79
80
81 void PackageInfoCallbackData::setExceptionCode(ExceptionCodes::Enumeration exceptionCode)
82 {
83     m_exceptionCode = exceptionCode;
84 }
85
86 ExceptionCodes::Enumeration PackageInfoCallbackData::getExceptionCode() const
87 {
88         return m_exceptionCode;
89 }
90
91 PackageInfoEventCallback::PackageInfoEventCallback(CallbackUserData* oninstalled, CallbackUserData* onupdated, CallbackUserData* onuninstalled)
92 {
93         m_oninstalled = oninstalled;
94         m_onupdated = onupdated;
95         m_onuninstalled = onuninstalled;
96 }
97
98 PackageInfoEventCallback::~PackageInfoEventCallback()
99 {
100         if (m_oninstalled)
101                 delete m_oninstalled;
102
103         if (m_onupdated)
104                 delete m_onupdated;
105
106         if (m_onuninstalled)
107                 delete m_onuninstalled;
108 }
109
110 CallbackUserData* PackageInfoEventCallback::getOnInstalled()
111 {
112         return m_oninstalled;
113 }
114
115 CallbackUserData* PackageInfoEventCallback::getOnUpdated()
116 {
117         return m_onupdated;
118 }
119
120 CallbackUserData* PackageInfoEventCallback::getOnUninstalled()
121 {
122         return m_onuninstalled;
123 }
124
125
126 PackageInstallEventCallback::PackageInstallEventCallback(JSContextRef globalCtx, CallbackUserData* onprogress, CallbackUserData* oncomplete, CallbackUserData* onerror)
127 {
128         m_context = globalCtx;
129         m_onprogress = onprogress;
130         m_oncomplete = oncomplete;
131         m_onerror = onerror;
132         
133         m_request_handle = NULL;
134 }
135
136 PackageInstallEventCallback::~PackageInstallEventCallback()
137 {
138         if (m_request_handle != NULL) {
139                 LogDebug("destroy client handle");
140                 //package_manager_request_destroy(m_request_handle);
141                 package_manager_client_destroy(m_request_handle);
142         }
143         
144         if (m_onprogress)
145                 delete m_onprogress;
146
147         if (m_oncomplete)
148                 delete m_oncomplete;
149
150         if (m_onerror)
151                 delete m_onerror;
152 }
153
154 CallbackUserData* PackageInstallEventCallback::getOnProgress()
155 {
156         return m_onprogress;
157 }
158
159 CallbackUserData* PackageInstallEventCallback::getOnComplete()
160 {
161         return m_oncomplete;
162 }
163
164 CallbackUserData* PackageInstallEventCallback::getOnError()
165 {
166         return m_onerror;
167 }
168
169 JSContextRef PackageInstallEventCallback::getContext()
170 {
171         return m_context;
172 }
173
174 void PackageInstallEventCallback::setHandle(package_manager_request_h handle)
175 {
176         m_request_handle = handle;
177 }
178
179 package_manager_request_h PackageInstallEventCallback::getHandle()
180 {
181         return m_request_handle;
182 }
183
184 static int get_current_pkg_id(char** pkg_id)
185 {
186         LogDebug("get_current_pkg_id enter");
187         int parent_pid = getppid();
188         LogDebug("parent pid : " << parent_pid);
189         char* app_id = NULL;
190         app_info_h handle;
191
192         int ret = app_manager_get_app_id(parent_pid, &app_id);
193         if ((ret != APP_MANAGER_ERROR_NONE) || (app_id == NULL)) {
194                 LogDebug("Cannot get app id from pid : " << parent_pid);
195                 return ret;
196         } else {
197                 LogDebug("app_id : " << app_id);
198         }
199
200         ret = app_manager_get_app_info(app_id, &handle);
201         if (ret != APP_MANAGER_ERROR_NONE) {
202                 LogDebug("Fail to get appinfo by " << app_id);
203                 return ret;
204         }
205
206         ret = app_info_get_package(handle, pkg_id);
207         if ((ret != APP_MANAGER_ERROR_NONE) || (*pkg_id == NULL)) {
208                 LogDebug("Fail to get pkg_id by " << app_id);
209                 return ret;
210         }
211
212         ret = app_info_destroy(handle);
213         if (ret != APP_MANAGER_ERROR_NONE) {
214                 LogDebug("Fail to get destory appinfo");
215                 return ret;
216         }
217
218         return ret; 
219 }
220
221 static bool app_callback(package_info_app_component_type_e comp_type, const char *app_id, void *user_data)
222 {
223         //LogDebug("app_callback enter : " << app_id);
224         PackageInformation* pkgInfo = (PackageInformation*)user_data;
225         pkgInfo->m_appIds.push_back(app_id);
226         return true;
227 }
228
229 static PackageInformation* create_pkg_info(pkgmgrinfo_pkginfo_h handle)
230 {
231         //LogDebug("enter");
232
233         PackageInformation *pkgInfo = new PackageInformation();
234
235         char* id = NULL;
236         char* name = NULL;
237         char* iconPath = NULL;
238         char* version = NULL;
239         int totalSize = 0;
240         int dataSize = 0;
241         int lastModified = 0;
242         char* type = NULL;
243         char* author = NULL;
244         char* description = NULL;
245         vector<string> appIds;
246         int ret = 0;
247
248         ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &id);
249         if ((ret != PMINFO_R_OK) || (id == NULL)) {
250                 LogDebug("Fail to get id");
251         } else {
252                 pkgInfo->m_id = id;
253         }
254
255         ret = pkgmgrinfo_pkginfo_get_label(handle, &name);
256         if ((ret != PMINFO_R_OK) || (name == NULL)) {
257                 LogDebug("Fail to get labe");
258         } else {
259                 pkgInfo->m_name = name;
260         }
261
262         ret = pkgmgrinfo_pkginfo_get_icon(handle, &iconPath);
263         if ((ret != PMINFO_R_OK) || (iconPath == NULL)) {
264                 LogDebug("Fail to get iconPath");
265         } else {
266                 pkgInfo->m_iconPath = iconPath;
267         }
268
269         ret = pkgmgrinfo_pkginfo_get_version(handle, &version);
270         if ((ret != PMINFO_R_OK) || (version == NULL)) {
271                 LogDebug("Fail to get version");
272         } else {
273                 pkgInfo->m_version = version;
274         }
275
276         ret = pkgmgrinfo_pkginfo_get_total_size(handle, &totalSize);
277         if (ret != PMINFO_R_OK) {
278                 LogDebug("Fail to get totalSize");
279         } else {
280                 pkgInfo->m_totalSize = totalSize;
281         }
282
283         ret = pkgmgrinfo_pkginfo_get_data_size(handle, &dataSize);
284         if (ret != PMINFO_R_OK) {
285                 LogDebug("Fail to get dataSize");
286         } else {
287                 pkgInfo->m_dataSize = dataSize;
288         }
289
290         ret = pkgmgrinfo_pkginfo_get_installed_time(handle, &lastModified);
291         if (ret != PMINFO_R_OK) {
292                 LogDebug("Fail to get lastModified");
293         } else {
294                 pkgInfo->m_lastModified = lastModified;
295         }
296
297         ret = pkgmgrinfo_pkginfo_get_type(handle, &type);
298         if ((ret != PMINFO_R_OK) || (type == NULL)) {
299                 LogDebug("Fail to get type");
300         } else {
301                 pkgInfo->m_type = type;
302         }
303
304         ret = pkgmgrinfo_pkginfo_get_author_name(handle, &author);
305         if ((ret != PMINFO_R_OK) || (author == NULL)) {
306                 LogDebug("Fail to get author");
307         } else {
308                 pkgInfo->m_author = author;
309         }
310
311         ret = pkgmgrinfo_pkginfo_get_description(handle, &description);
312         if ((ret != PMINFO_R_OK) || (description == NULL)) {
313                 LogDebug("Fail to get description");
314         } else {
315                 pkgInfo->m_description = description;
316         }
317
318         package_info_h package_info;
319         
320         ret = package_manager_get_package_info(id, &package_info);
321         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
322                 LogDebug("Cannot create package info by : " << id);
323         }
324
325         ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_ALLAPP, app_callback, (void*)pkgInfo);
326         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
327                 LogDebug("failed while getting appids");
328         }
329
330         ret = package_info_destroy(package_info);
331         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
332                 LogDebug("Cannot destroy package info");
333         }       
334
335         // REMARK: do not destroy handle. because handle is comes from outside!!
336         return pkgInfo;
337 }
338
339 static gboolean getCompleteCB(void *data)
340 {
341         LogDebug("entered");
342
343         PackageInfoCallbackData *callback = (PackageInfoCallbackData *)data;
344         JSContextRef context = callback->getContext();
345
346         if (callback->getExceptionCode() == WrtDeviceApis::Commons::ExceptionCodes::None) {
347                 vector<PackageInformation> pkgInfoList = callback->getPackageInfoList();
348                 
349             JSObjectRef jsResult = JSCreateArrayObject(context, 0, NULL);
350             if (jsResult == NULL) {
351                         JSValueRef error = JSTizenExceptionFactory::makeErrorObject(callback->getContext(), JSTizenException::UNKNOWN_ERROR, "platform exception");
352                 callback->callErrorCallback(error);
353                         return false;
354             }
355
356             for (std::size_t i = 0; i < pkgInfoList.size(); ++i) {
357                 JSValueRef tmpVal = JSPackageInformation::createJSObject(context, &pkgInfoList[i]);
358                 if (!JSSetArrayElement(context, jsResult, i, tmpVal)) {
359                                 JSValueRef error = JSTizenExceptionFactory::makeErrorObject(callback->getContext(), JSTizenException::UNKNOWN_ERROR, "platform exception");
360                         callback->callErrorCallback(error);
361                                 return false;
362                 }
363             }
364
365                 callback->callSuccessCallback(jsResult);
366         } else {
367                 LogDebug("Fail!!");
368                 JSValueRef error = JSTizenExceptionFactory::makeErrorObject(callback->getContext(), JSTizenException::UNKNOWN_ERROR, "platform exception");
369                 callback->callErrorCallback(error);
370         }
371
372         // TODO: cleanup each packageInformation items
373     delete callback;
374         
375         return false;
376 }
377
378 static int get_package_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
379 {
380         //LogDebug("entered");
381         PackageInfoCallbackData *callback = (PackageInfoCallbackData *)user_data;
382         PackageInformation* pkgInfo = create_pkg_info(handle);
383         if (pkgInfo != NULL) {
384                 callback->addPackageInfo(*pkgInfo);
385                 delete pkgInfo;
386         } else {
387                 LogError("Fail to get pkgInfo");
388         }
389         return 0;
390 }
391
392 static void getThreadCB(void *data, Ecore_Thread *thread)
393 {
394         LogDebug("entered");
395
396         PackageInfoCallbackData *callback = (PackageInfoCallbackData *)data;
397         
398         int ret = pkgmgrinfo_pkginfo_get_list(get_package_list_cb, data);
399         if (ret != PMINFO_R_OK) {
400                 LogDebug("Fail to get package info");
401                 callback->setExceptionCode(WrtDeviceApis::Commons::ExceptionCodes::PlatformException);
402         }
403
404         // the operation of ecore_thread_run() is not normal. (the finish callback is not called from main thread.)
405         // so, add complete callback to gmainloop explicitly.
406         g_idle_add(getCompleteCB, data);
407 }
408
409 static void package_event_cb(const char *type,  const char *package,
410                         package_manager_event_type_e event_type,
411                         package_manager_event_state_e event_state,
412                         int progress,
413                         package_manager_error_e error,
414                         void *user_data)
415 {
416         LogDebug("event callback is called!!! : event_state " << event_state << " : package " << package << " : event_type " << event_type );
417         if (event_state == PACAKGE_MANAGER_EVENT_STATE_COMPLETED) {
418                 PackageInfoEventCallback *eventCB = (PackageInfoEventCallback *)user_data;
419
420                 switch(event_type) {
421                 case PACAKGE_MANAGER_EVENT_TYPE_INSTALL: {
422                         pkgmgrinfo_pkginfo_h handle;
423                         int ret = pkgmgrinfo_pkginfo_get_pkginfo(package, &handle);
424                         if (ret != PMINFO_R_OK) {
425                                 LogDebug("fail to find pkg info with given pkg : " << package);
426                                 // Do not throw exception. No one can handle exception because this code is called from async callback.
427                                 //throw NotFoundException("Can't find given package");
428                                 break;
429                         }
430
431                         PackageInformation* pkgInfo = create_pkg_info(handle);
432                         pkgmgrinfo_appinfo_destroy_appinfo(handle);
433
434                         CallbackUserData *callback = eventCB->getOnInstalled();
435                         if (callback) {
436                                 callback->callSuccessCallback(JSPackageInformation::createJSObject(callback->getContext(), pkgInfo));
437                         }
438                         break;
439                 }
440                 case PACAKGE_MANAGER_EVENT_TYPE_UNINSTALL: {
441                         LogDebug("uninstall : " << package);
442                         CallbackUserData *callback = eventCB->getOnUninstalled();
443                         if (callback) {
444                                 Converter converter(callback->getContext());
445                                 callback->callSuccessCallback(converter.toJSValueRef(package));
446                         }
447                         break;
448                 }
449                 case PACAKGE_MANAGER_EVENT_TYPE_UPDATE: {
450                         pkgmgrinfo_pkginfo_h handle;
451                         int ret = pkgmgrinfo_pkginfo_get_pkginfo(package, &handle);
452                         if (ret != PMINFO_R_OK) {
453                                 // Do not throw exception. No one can handle exception because this code is called from async callback.
454                                 //throw NotFoundException("Can't find given package");
455                                 break;
456                         }
457
458                         PackageInformation* pkgInfo = create_pkg_info(handle);
459                         pkgmgrinfo_appinfo_destroy_appinfo(handle);
460
461                         CallbackUserData *callback = eventCB->getOnUpdated();
462                         if (callback) {
463                                 callback->callSuccessCallback(JSPackageInformation::createJSObject(callback->getContext(), pkgInfo));
464                         }
465                         break;
466                 }
467                 default:
468                         LogDebug("Fail!! Unknown event type is entered : " << event_type);
469                         break;
470                 }
471         }
472 }
473
474
475 void install_request_cb(int id, const char *type, const char *package, 
476                                 package_manager_event_type_e event_type,
477                                 package_manager_event_state_e event_state,
478                                 int progress,
479                                 package_manager_error_e error,
480                                 void *user_data)
481 {
482         LogDebug("install_request_cb ");
483         PackageInstallEventCallback *callback = (PackageInstallEventCallback *)user_data;
484         JSContextRef context = callback->getContext();;
485
486         switch (event_state) {
487         case PACAKGE_MANAGER_EVENT_STATE_COMPLETED: {
488                 LogDebug("destroy client handle");
489                 if (callback->getOnComplete()) {
490                         Converter converter(context);
491                         callback->getOnComplete()->callSuccessCallback(converter.toJSValueRef(package));
492                 }
493
494                 // this api is not supported from platform.
495                 //package_manager_request_destroy(callback->getHandle());
496                 package_manager_client_destroy(callback->getHandle());
497
498                 //clean-up callback object
499                 delete callback;
500                 
501                 break;
502         }
503         case PACAKGE_MANAGER_EVENT_STATE_FAILED: {
504                 JSValueRef jsError = NULL;
505                 if (error == PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE) {
506                         jsError = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::NOT_FOUND_ERROR,"given package is not found");
507                 } else {
508                         jsError = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"platform exception");
509                 }
510
511                 if (callback->getOnError()) {
512                         callback->getOnError()->callSuccessCallback(jsError);
513                 }
514
515                 LogDebug("destroy client handle");
516                 // this api is not supported from platform.
517                 //package_manager_request_destroy(callback->getHandle());
518                 package_manager_client_destroy(callback->getHandle());
519
520                 //clean-up callback object
521                 delete callback;
522                 
523                 break;
524         }
525         case PACAKGE_MANAGER_EVENT_STATE_STARTED:
526         case PACAKGE_MANAGER_EVENT_STATE_PROCESSING: {
527                 if (callback->getOnProgress()) {
528                         Converter converter(context);
529                         JSValueRef args[2] = {converter.toJSValueRef(package), converter.toJSValueRef(progress)};
530                         callback->getOnProgress()->callSuccessCallback(2, args);
531                 }
532                 break;          
533         }
534         default:
535                 JSValueRef error = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"platform exception");
536                 if (callback->getOnError()) {
537                         callback->getOnError()->callSuccessCallback(error);
538                 }
539                 LogDebug("destroy client handle");
540                 // this api is not supported from platform.
541                 //package_manager_request_destroy(callback->getHandle());
542                 package_manager_client_destroy(callback->getHandle());
543
544                 //clean-up callback object
545                 delete callback;
546                 
547                 break;
548         }
549
550 }
551
552 void PackageManager::install(string pkgPath, PackageInstallEventCallback* callback)
553 {
554         LogDebug("install");
555         int ret = 0;
556         int id = 0;
557         package_manager_request_h request_h;
558         JSContextRef globalCtx = callback->getContext();
559         CallbackUserData* errCallback = callback->getOnError();
560
561         ret = package_manager_request_create(&request_h);
562         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
563                 if (errCallback) {
564                         JSValueRef error = 
565                                 JSTizenExceptionFactory::makeErrorObject(globalCtx, JSTizenException::UNKNOWN_ERROR, "Platform Error");
566                         errCallback->callSuccessCallback(error);
567                 }
568                 return;
569         }
570
571         ret = package_manager_request_install(request_h, pkgPath.c_str(), &id);
572         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
573                 LogDebug("error : " << pkgPath);
574                 if (errCallback) {
575                         JSValueRef error = 
576                                 JSTizenExceptionFactory::makeErrorObject(globalCtx, JSTizenException::NOT_FOUND_ERROR, "Not proper file");
577                         errCallback->callSuccessCallback(error);
578                 }
579                 return;
580         }
581
582         callback->setHandle(request_h);
583
584         ret = package_manager_request_set_event_cb(request_h, install_request_cb, callback);
585         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
586                 if (errCallback) {
587                         JSValueRef error = 
588                                 JSTizenExceptionFactory::makeErrorObject(globalCtx, JSTizenException::UNKNOWN_ERROR, "Platform Error");
589                         errCallback->callSuccessCallback(error);
590                 }
591                 return;
592         }
593 }
594
595 void PackageManager::uninstall(string pkgPath, PackageInstallEventCallback* callback)
596 {
597         LogDebug("uninstall");
598         int ret = 0;
599         int id = 0;
600         package_manager_request_h request_h;
601         JSContextRef globalCtx = callback->getContext();
602         CallbackUserData* errCallback = callback->getOnError();
603
604         ret = package_manager_request_create(&request_h);
605         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
606                 if (errCallback) {
607                         JSValueRef error = 
608                                 JSTizenExceptionFactory::makeErrorObject(globalCtx, JSTizenException::UNKNOWN_ERROR, "Platform Error");
609                         errCallback->callSuccessCallback(error);
610                 }
611                 //clean-up callback object
612                 delete callback;
613                 return;
614         }
615
616         ret = package_manager_request_uninstall(request_h, pkgPath.c_str(), &id);
617         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
618                 LogDebug("error : " << pkgPath);
619                 if (errCallback) {
620                         JSValueRef error = 
621                                 JSTizenExceptionFactory::makeErrorObject(globalCtx, JSTizenException::NOT_FOUND_ERROR, "Not proper file");
622                         // TODO: how can I handle about uninstallable package???
623                         errCallback->callSuccessCallback(error);
624                 }
625                 //clean-up callback object
626                 delete callback;
627                 return;
628         }
629
630         callback->setHandle(request_h);
631
632         ret = package_manager_request_set_event_cb(request_h, install_request_cb, callback);
633         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
634                 if (errCallback) {
635                         JSValueRef error = 
636                                 JSTizenExceptionFactory::makeErrorObject(globalCtx, JSTizenException::UNKNOWN_ERROR, "Platform Error");
637                         errCallback->callSuccessCallback(error);
638                 }
639                 //clean-up callback object
640                 delete callback;
641                 return;
642         }
643 }
644
645
646 PackageInformation* PackageManager::getPackageInfo(string pkgId)
647 {
648         if (pkgId.empty() || !pkgId.compare("null")) {
649                 char *pkg_id = NULL;
650
651                 int ret = get_current_pkg_id(&pkg_id);
652                 if((ret != APP_MANAGER_ERROR_NONE) || (pkg_id == NULL)) {
653                         LogError("Can not get app id from current pid (" << ret << ")");
654                         throw NotFoundException("Can't find given package");
655                 }
656                 pkgId = pkg_id;
657                 free(pkg_id);
658         }
659
660         pkgmgrinfo_pkginfo_h handle;
661         int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
662         if (ret != PMINFO_R_OK) {
663                 throw NotFoundException("Can't find given package");
664         }
665
666         PackageInformation* pkgInfo = create_pkg_info(handle);
667         pkgmgrinfo_appinfo_destroy_appinfo(handle);
668
669         return pkgInfo;
670 }
671
672
673 void PackageManager::getPackagesInfo(PackageInfoCallbackData *user_data)
674 {
675         LogDebug("entered");
676
677         // getting info of all package from other thread. the result callback will be called on main thread
678         ecore_thread_run(getThreadCB, NULL, NULL, user_data);
679 }
680
681
682 void PackageManager::setPackageInfoEventListener(PackageInfoEventCallback * eventCB)
683 {
684         LogDebug("enter");
685         int ret = 0;
686
687         if (m_manager_handle == NULL) {
688                 ret = package_manager_create(&m_manager_handle);
689                 if (ret != PACKAGE_MANAGER_ERROR_NONE) {
690                         throw UnknownException("Fail to create package manager handle");
691                 }
692         }
693         
694         ret = package_manager_set_event_cb(m_manager_handle, package_event_cb, eventCB);
695         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
696                 throw UnknownException("Fail to set event cb");
697         }
698 }
699
700 void PackageManager::unsetPackageInfoEventListener()
701 {
702         LogDebug("enter");
703         int ret = 0;
704
705         if (m_manager_handle == NULL) {
706                 LogDebug("no package manager handle registered");
707                 return;
708         }
709         
710         ret = package_manager_unset_event_cb(m_manager_handle);
711         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
712                 throw UnknownException("Fail to unset event cb");
713         }
714
715         ret = package_manager_destroy(m_manager_handle);
716         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
717                 throw UnknownException("Fail to destroy package manager handle");
718         } else {
719                 m_manager_handle = NULL;
720         }
721 }
722
723 PackageManager* PackageManager::getInstance(){
724         LogDebug("enter to getInstance()");
725     static PackageManager instance;
726     return &instance;
727 }
728
729 PackageManager::PackageManager()
730 {
731         LogDebug("Create PackageManager");
732 }
733
734 PackageManager::~PackageManager()
735 {
736         LogDebug("Destroy PackageManager");
737         if (m_manager_handle != NULL) {
738                 package_manager_destroy(m_manager_handle);
739         }       
740 }
741
742
743 // candidate apis
744 #if 0
745 void PackageManager::move(string pkgPath, string target, PackageInstallEventCallback* callback)
746 {
747         LogDebug("entered : " << pkgPath);
748         int ret = 0;
749         package_manager_move_type_e type = PACAKGE_MANAGER_REQUEST_MOVE_TO_INTERNAL;
750
751         if (target.compare("INTERNAL") == 0) {
752                 type = PACAKGE_MANAGER_REQUEST_MOVE_TO_INTERNAL;
753         } else {
754                 type = PACAKGE_MANAGER_REQUEST_MOVE_TO_EXTERNAL;
755         }
756         // compare current storage and target storage
757         
758         package_manager_request_h request_h;
759         
760         ret = package_manager_request_create(&request_h);
761         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
762                 ThrowMsg(PlatformException, "Unknow exception is occured!!");
763         }
764
765         ret = package_manager_request_move(request_h, pkgPath.c_str(), type);
766         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
767                 ThrowMsg(PlatformException, "Unknow exception is occured!!");
768         }
769
770         callback->setHandle(request_h);
771
772         ret = package_manager_request_set_event_cb(request_h, install_request_cb, callback);
773         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
774                 ThrowMsg(PlatformException, "Unknow exception is occured!!");
775         }
776 }
777
778 bool PackageManager::isInstalled(string pkgId)
779 {
780         LogDebug("pkgId = " << pkgId);
781         package_info_h handle;
782         int ret = 0;
783         
784         ret = package_manager_get_package_info(pkgId.c_str(), &handle);
785         if (ret == PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE) {
786                 LogError("No patched package: " << pkgId);
787                 return false;
788         } else if (ret == PACKAGE_MANAGER_ERROR_NONE) {
789                 // TODO: Should I exception handling while destory handle? what should I do for that time?
790                 package_info_destroy(handle);
791                 return true;
792         } else {
793                 ThrowMsg(PlatformException, "Unknow exception is occured!!");
794         }
795 }
796
797 string PackageManager::getPackageIdFromAppId(string appId)
798 {
799         LogDebug("appId = " << appId);
800         char *pkg_id = NULL;
801         string pkgId;
802         int ret = 0;
803         
804         ret = package_manager_get_package_id_by_app_id(appId.c_str(), &pkg_id);
805         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
806                 LogError("Error on get pkgId from appId : " << appId);
807                 ThrowMsg(NotFoundException, "Not found pkg");
808         }
809
810         pkgId = pkg_id;
811         if (pkg_id)
812                 free(pkg_id);
813
814         return pkgId;
815         
816 }
817 #endif
818
819
820 }
821 }