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