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