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