Update change log and spec for wrt-plugins-tizen_0.4.70
[framework/web/wrt-plugins-tizen.git] / src / Application / ApplicationManager.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 "ApplicationManager.h"
19
20 #include <cassert>
21 #include <sstream>
22 #include <Commons/Exception.h>
23 #include <Commons/EventReceiver.h>
24 #include <Commons/Regex.h>
25 #include <plugins-ipc-message/ipc_message_support.h>
26
27 #include "ApplicationInformation.h"
28 #include "ApplicationContext.h"
29 #include "ApplicationControlData.h"
30 #include "ApplicationControl.h"
31 #include "Application.h"
32
33 #include <app.h>
34
35 // to launch app by aul
36 #include <aul.h>
37
38 // to get package name by appid
39 #include <app_info.h>
40 #include <app_manager.h>
41
42 // To get cert information from package
43 #include <package_manager.h>
44 #include <package_info.h>
45
46 // To get app size and installed time
47 #include <pkgmgr-info.h>
48
49 // To get ppid
50 #include <unistd.h>
51
52 #include <TimeTracer.h>
53
54 #include <Logger.h>
55
56 namespace DeviceAPI {
57 namespace Application {
58
59
60 using namespace WrtDeviceApis;
61 using namespace WrtDeviceApis::Commons;
62
63 namespace {
64
65         typedef KeyMultiMap<ApplicationManager*, LaunchAppControlPendingEvent> LaunchAppControlPendingEventMap;
66         static LaunchAppControlPendingEventMap gLaunchAppControlPendingEventMap;
67
68         // Callback from 'app_manager_set_app_context_event_cb'
69         // Used by 'kill'
70         static void app_manager_app_context_event_callback(app_context_h app_context,
71                         app_context_event_e event, void *user_data)
72         {
73                 int ret = 0;
74
75                 if(event != APP_CONTEXT_EVENT_TERMINATED)
76                         return;
77
78                 int pid = 0;
79
80                 ret = app_context_get_pid(app_context, &pid);
81                 if(ret != APP_MANAGER_ERROR_NONE)
82                 {
83                         LoggerE("Fail to get pid of terminated app (" << ret << ")");
84                         return;
85                 }
86
87                 ApplicationManager* appManager = (ApplicationManager*)(user_data);
88                 appManager->invokeManualAnswerKill(pid);
89         }
90
91         // get package name by id
92         static char* getPackageByAppId(const char* appId)
93         {
94                 app_info_h handle;
95                 char* pkgName;
96                 int ret = 0;
97                 
98                 ret = app_manager_get_app_info(appId, &handle);
99                 if (ret < 0)
100                 {
101                         LoggerE("Fail to get appinfo");
102                         return NULL;
103                 }
104
105                 ret = app_info_get_package(handle, &pkgName);
106                 if (ret < 0)
107                 {
108                         LoggerE("Fail to get pkgName");
109                         pkgName = NULL;
110                 }
111
112                 ret = app_info_destroy(handle);
113                 if (ret < 0)
114                 {
115                         LoggerE("Fail to get destory appinfo");
116                         return NULL;
117                 }
118
119                 return pkgName;
120         }
121
122
123         // Callback of 'app_manager_foreach_app_context'
124         // Used by 'getAppsContext'
125         static bool app_manager_app_context_callback(app_context_h app_context, void *user_data)
126         {
127                 int ret = 0;
128
129                 char *app_id = NULL;
130                 int pid;
131
132                 std::string contextId;
133
134                 if (user_data == NULL)
135                 {
136                         return false;
137                 }
138
139                 ret = app_context_get_app_id(app_context, &app_id);
140                 if((ret != APP_MANAGER_ERROR_NONE) || (app_id == NULL))
141                 {
142                         LoggerE("Fail to get app id from context (" << ret << ")");
143                         return false;
144                 }
145
146                 ret = app_context_get_pid(app_context, &pid);
147                 if(ret != APP_MANAGER_ERROR_NONE)
148                 {
149                         LoggerE("Fail to get pid from context (" << ret << ")");
150                         if (app_id)
151                                 free(app_id);
152                         return false;
153                 }
154
155                 std::stringstream sstream;
156                 sstream << pid;
157                 contextId = sstream.str();
158
159                 ApplicationContextPtr appContext(new ApplicationContext());
160                 appContext->setAppId(app_id);
161                 appContext->setContextId(contextId);
162
163                 ApplicationContextArray* appContextArray = (ApplicationContextArray*)user_data;
164
165                 appContextArray->push_back(appContext);
166
167                 if (app_id)
168                         free(app_id);
169
170                 return true;
171         }
172
173         // Callback of 'service_send_launch_request'
174         // Used by 'launchAppControl'
175         static void service_reply_callback(service_h request, service_h reply,
176                         service_result_e result, void *user_data)
177         {
178                 LaunchAppControlPendingEventMap::DataKeyType key =
179                                 (LaunchAppControlPendingEventMap::DataKeyType)user_data;
180
181                 LaunchAppControlPendingEvent *pendingEvent = gLaunchAppControlPendingEventMap.getData(key);
182                 if(pendingEvent != NULL)
183                 {
184                         ApplicationManager *application = (ApplicationManager *)pendingEvent->getThisObject();
185                         EventApplicationLaunchAppControlReplyPtr event = pendingEvent->getEvent();
186                         application->invokeManualAnswerLaunchAppControl(request, reply, result, event);
187
188                         delete pendingEvent;
189                         pendingEvent = NULL;
190                         user_data = NULL;
191
192                         gLaunchAppControlPendingEventMap.eraseData(key);
193                 }
194         }
195
196         static bool package_cert_cb(package_info_h handle, package_cert_type_e cert_type, const char *cert_value, void *user_data)
197         {
198                 ApplicationCertPtr cert(new ApplicationCert());
199                 const char* certName = NULL;
200                 
201                 switch(cert_type) {
202                 case PACKAGE_INFO_AUTHOR_ROOT_CERT:
203                         certName = "AUTHOR_ROOT";
204                         break;
205                 case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT:
206                         certName = "AUTHOR_INTERMEDIATE";
207                         break;
208                 case PACKAGE_INFO_AUTHOR_SIGNER_CERT:
209                         certName = "AUTHOR_SIGNER";
210                         break;
211                 case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT:
212                         certName = "DISTRIBUTOR_ROOT";
213                         break;
214                 case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT:
215                         certName = "DISTRIBUTOR_INTERMEDIATE";
216                         break;
217                 case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT:
218                         certName = "DISTRIBUTOR_SIGNER";
219                         break;
220                 case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT:
221                         certName = "DISTRIBUTOR2_ROOT";
222                         break;
223                 case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT:
224                         certName = "DISTRIBUTOR2_INTERMEDIATE";
225                         break;
226                 case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT:
227                         certName = "DISTRIBUTOR2_SIGNER";
228                         break;
229                 default:
230                         LoggerE("Unknow Cert type!!!");
231                         break;
232                 }
233                 
234                 cert->setType(certName);
235                 cert->setValue(cert_value);
236
237                 ApplicationCertArray *certs = (ApplicationCertArray *)user_data;
238                 certs->push_back(cert);
239
240                 return true;
241         }
242
243         static std::string get_current_app_id()
244         {
245                 std::string appId = AppManagerWrapperSingleton::Instance().getCurrentAppId();
246                 return appId;
247         }
248         
249         static int category_cb(const char *category, void *user_data)
250         {
251                 if (category == NULL)
252                         return true;
253
254                 ApplicationInformation* appInfo = (ApplicationInformation*)user_data;
255                 appInfo->addCategories(category);
256                 return true;
257         }
258
259         static ApplicationInformationPtr create_app_info(pkgmgrinfo_appinfo_h handle)
260         {
261                 char* appId = NULL;
262                 char* name = NULL;
263                 char* iconPath = NULL;  
264                 bool noDisplay = false;
265                 char* pkgId = NULL;
266                 int ret = 0;
267         
268                 ApplicationInformationPtr appInfo(new ApplicationInformation());
269                 ret = pkgmgrinfo_appinfo_get_appid(handle, &appId);
270                 if (ret != PMINFO_R_OK) {
271                         LoggerD("Fail to get name");
272                 } else {
273                         appInfo->setAppId(appId);
274                 }
275
276                 ret = pkgmgrinfo_appinfo_get_label(handle, &name);
277                 if ((ret != PMINFO_R_OK) || (name == NULL)) {
278                         LoggerD("Fail to get name");
279                 } else {
280                         appInfo->setName(name);
281                 }
282
283                 ret = pkgmgrinfo_appinfo_get_icon(handle, &iconPath);
284                 if ((ret != PMINFO_R_OK) || (iconPath == NULL)) {
285                         LoggerD("Fail to get icon");
286                 } else {
287                         appInfo->setIconPath(iconPath);
288                 }
289
290                 ret = pkgmgrinfo_appinfo_is_nodisplay(handle, &noDisplay);
291                 if (ret != PMINFO_R_OK) {
292                         LoggerD("Fail to get nodisplay");
293                 } else {
294                         appInfo->setShow(!noDisplay);
295                 }
296
297                 ret = pkgmgrinfo_appinfo_foreach_category(handle, category_cb, (void*)appInfo.Get());
298                 if (ret != PMINFO_R_OK) {
299                         LoggerD("Fail to get categories");
300                 }
301
302                 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
303                 if ((ret != PMINFO_R_OK) || (pkgId == NULL)) {
304                         LoggerD("Fail to get pkg Id");
305                 } else {
306                         appInfo->setPackageId(pkgId);
307                 }
308
309                 char *version = NULL;
310                 int installed_time = 0;
311                 pkgmgrinfo_pkginfo_h pkginfo_h;
312
313                 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId, &pkginfo_h);
314                 if (ret != PMINFO_R_OK) {
315                         LoggerE("Fail to get package info");
316                 } else {
317                         ret = pkgmgrinfo_pkginfo_get_version(pkginfo_h, &version);
318                         if (ret != PMINFO_R_OK) {
319                                 LoggerE("Fail to get version");
320                         } else {
321                                 appInfo->setVersion(version);
322                         }
323
324                         ret = pkgmgrinfo_pkginfo_get_installed_time(pkginfo_h, &installed_time);
325                         if (ret != PMINFO_R_OK) {
326                                 LoggerE("Fail to get installed date");
327                         } else {
328                                 appInfo->setInstallDate(installed_time);
329                         }
330
331                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
332                 }
333
334                 // remark : attribute "total size" is set at first attribute access time for performance.
335                 return appInfo;
336         }
337         
338         
339         static int installed_app_info_cb(pkgmgrinfo_appinfo_h handle, void *user_data)
340         {
341                 ApplicationInformationPtr appInfo = create_app_info(handle);
342                 ApplicationInformationArray *appInfoArray = (ApplicationInformationArray*)user_data;
343                 appInfoArray->push_back(appInfo);
344                 return 0;
345         }
346
347         // Callback from 'service_foreach_app_matched'
348         // Used by 'findAppControl'
349         static bool service_app_matched_callback(service_h service, const char *appid, void *user_data)
350         {
351                 if(appid == NULL)
352                 {
353                         LoggerD("appid is NULL");
354                         return false;
355                 }
356                 //ApplicationInformationPtr appInfo(new ApplicationInformation(appid));
357                 pkgmgrinfo_appinfo_h handle;
358                 int ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
359                 if (ret != PMINFO_R_OK) {
360                         LoggerD("Fail to get appInfo from appId : " << appid);
361                 } else {
362                         ApplicationInformationPtr appInfo = create_app_info(handle);
363                         pkgmgrinfo_appinfo_destroy_appinfo(handle);
364
365                         ApplicationInformationArray *appInfos = (ApplicationInformationArray *)user_data;
366                         appInfos->push_back(appInfo);
367                 }
368
369                 return true;
370         }
371
372         static int app_meta_data_cb(const char *meta_key, const char *meta_value, void *user_data)
373         {
374                 if ((meta_key == NULL)  || (meta_value == NULL)) {
375                         LoggerE("meta_key or meta_value is null");
376                         return 0;
377                 }
378
379                 ApplicationMetaDataPtr metaData(new ApplicationMetaData());
380
381                 metaData->setKey(meta_key);
382                 metaData->setValue(meta_value);
383
384                 ApplicationMetaDataArray *metaDataArray = (ApplicationMetaDataArray *)user_data;
385                 metaDataArray->push_back(metaData);
386
387                 return 0;       
388         }
389 }
390
391 ApplicationManager::ApplicationManager() :
392         m_initialized(false)
393 {
394         
395 }
396
397 ApplicationManager::~ApplicationManager() 
398 {
399         if(m_installedApplicationsEmitters.size() != 0)
400         {
401                 AppManagerWrapperSingleton::Instance().unregisterAppListChangedCallbacks(this);
402                 WatchIdMap::iterator iter = m_watchIdMap.begin();
403                 for(; iter != m_watchIdMap.end(); iter++)
404                 {
405                         m_installedApplicationsEmitters.detach(iter->second);
406                 }
407         }
408
409         LaunchAppControlPendingEventMap::DataPtrListType dataPtrList =
410                         gLaunchAppControlPendingEventMap.getDataPtrList(this);
411
412         LaunchAppControlPendingEventMap::DataPtrListType::iterator iter = dataPtrList.begin();
413         for(; iter != dataPtrList.end(); iter++)
414         {
415                 delete *iter;
416         }
417
418         gLaunchAppControlPendingEventMap.eraseKey(this);
419
420         // unset context event callback which is registered by kill().
421         app_manager_unset_app_context_event_cb();
422 }
423
424 void ApplicationManager::launch(const EventApplicationLaunchPtr& event)
425 {
426         if (m_initialized == false) {
427                 initialize();
428         }
429
430         EventRequestReceiver<EventApplicationLaunch>::PostRequest(event);
431 }
432
433 void ApplicationManager::kill(const EventApplicationKillPtr& event)
434 {
435         if (m_initialized == false) {
436                 initialize();
437         }
438
439         EventRequestReceiver<EventApplicationKill>::PostRequest(event);
440 }
441
442 void ApplicationManager::launchAppControl(const EventApplicationLaunchAppControlPtr& event)
443 {
444         if (m_initialized == false) {
445                 initialize();
446         }
447
448         EventApplicationLaunchAppControlReplyPtr eventReply = event->getEventReply();
449         if(eventReply != NULL)
450                 EventRequestReceiver<EventApplicationLaunchAppControlReply>::PostRequest(eventReply);
451
452         EventRequestReceiver<EventApplicationLaunchAppControl>::PostRequest(event);
453 }
454
455 void ApplicationManager::findAppControl(const EventApplicationFindAppControlPtr& event)
456 {
457         if (m_initialized == false) {
458                 initialize();
459         }
460
461         EventRequestReceiver<EventApplicationFindAppControl>::PostRequest(event);
462 }
463
464 void ApplicationManager::getAppsContext(const EventApplicationGetAppsContextPtr& event)
465 {
466         if (m_initialized == false) {
467                 initialize();
468         }
469
470         EventRequestReceiver<EventApplicationGetAppsContext>::PostRequest(event);
471 }
472
473
474 void ApplicationManager::getAppsInfo(const EventApplicationGetAppsInfoPtr& event)
475 {
476         if (m_initialized == false) {
477                 initialize();
478         }
479
480         EventRequestReceiver<EventApplicationGetAppsInfo>::PostRequest(event);
481 }
482
483
484 void ApplicationManager::addAppInfoEventListener(const EventApplicationAddAppInfoEventListenerPtr& event)
485 {
486         if (m_initialized == false) {
487                 initialize();
488         }
489
490         EventRequestReceiver<EventApplicationAddAppInfoEventListener>::PostRequest(event);
491 }
492
493 void ApplicationManager::removeAppInfoEventListener(const EventApplicationRemoveAppInfoEventListenerPtr& event)
494 {
495         if (m_initialized == false) {
496                 initialize();
497         }
498
499         EventRequestReceiver<EventApplicationRemoveAppInfoEventListener>::PostRequest(event);
500 }
501
502
503 void ApplicationManager::invokeManualAnswerLaunchAppControl(service_h request, service_h reply,
504                 service_result_e result,
505                 EventApplicationLaunchAppControlReplyPtr &event)
506 {
507         if (event == NULL) {
508                 return;
509         }
510
511         if(result == SERVICE_RESULT_SUCCEEDED)
512         {
513                 // create new service object to store result.
514                 ApplicationControlDataArrayPtr appControlDataArray(new ApplicationControlDataArray());
515
516                 int result = service_foreach_extra_data(reply, service_extra_data_callback, appControlDataArray.Get());
517                 if( result == SERVICE_ERROR_NONE)
518                 {
519                         event->setAppControlDataArray(appControlDataArray);
520                 }
521                 else
522                 {
523                         event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
524                 }
525         }
526         else if(result == SERVICE_RESULT_FAILED || result == SERVICE_RESULT_CANCELED)
527         {
528                 event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
529         }
530
531         EventRequestReceiver<EventApplicationLaunchAppControlReply>::ManualAnswer(event);
532 }
533
534 void ApplicationManager::invokeManualAnswerKill(int pid)
535 {
536         DPL::Mutex::ScopedLock lock(&m_killMapLock);
537
538         std::map<int, EventApplicationKillPtr>::iterator it = m_killEventMap.find(pid);
539         if (it == m_killEventMap.end()) {
540                 return;
541         }
542
543         EventApplicationKillPtr event = it->second;
544         m_killEventMap.erase(it);
545
546         EventRequestReceiver<EventApplicationKill>::ManualAnswer(event);
547 }
548
549
550 bool ApplicationManager::service_extra_data_callback(service_h service, const char *key, void* user_data)
551 {
552         int ret = 0;
553
554         ApplicationControlDataArray* appControlDataArray = (ApplicationControlDataArray*)user_data;
555
556         bool isArray = false;
557         ret = service_is_extra_data_array(service, key, &isArray);
558         if (ret != SERVICE_ERROR_NONE)
559         {
560                 LoggerE("service_is_extra_data_array passes error");
561                 // fail to checking. go to next extra data.
562                 return true;
563         }
564
565         std::string keyStr(key);
566
567         if(isArray)
568         {
569                 int length = 0;
570                 char **value = NULL;
571
572                 ret = service_get_extra_data_array(service, key, &value, &length);
573                 switch(ret)
574                 {
575                 case SERVICE_ERROR_NONE: {
576                         std::vector<std::string> valArray;
577                         LoggerI("value length : " << length);
578                         for (int i = 0; i < length; i++)
579                         {
580                                 if(value[i])
581                                 {
582                                         valArray.push_back(value[i]);
583                                 }
584                         }
585
586                         ApplicationControlDataPtr appControlData(new ApplicationControlData());
587                         appControlData->setKey(keyStr);
588                         appControlData->setValue(valArray);
589                         appControlDataArray->push_back(appControlData);
590
591                         for (int i = 0; i < length; i++)
592                         {
593                                 if (value[i])
594                                         free(value[i]);
595                         }
596                         if (value)
597                                 free(value);
598                         break;
599                 }
600                 case SERVICE_ERROR_INVALID_PARAMETER:
601                         LoggerE("service_get_extra_data retuns SERVICE_ERROR_INVALID_PARAMETER");
602                         break;
603                 case SERVICE_ERROR_KEY_NOT_FOUND:
604                         LoggerE("service_get_extra_data retuns SERVICE_ERROR_KEY_NOT_FOUND");
605                         break;
606                 case SERVICE_ERROR_OUT_OF_MEMORY:
607                         LoggerE("service_get_extra_data retuns SERVICE_ERROR_OUT_OF_MEMORY");
608                         break;
609                 default:
610                         LoggerE("service_get_extra_data retuns Error");
611                         break;
612                 }                       
613         }
614         else // (!isArray)
615         {
616                 char *value = NULL;
617
618                 ret = service_get_extra_data(service, key, &value);
619                 switch (ret)
620                 {
621                 case SERVICE_ERROR_NONE:
622                 {
623                         if(value == NULL)
624                         {
625                                 LoggerE("service_get_extra_data returns NULL");
626                                 break;
627                         }
628
629                         std::vector<std::string> valArray;
630                         valArray.push_back(value);
631
632                         ApplicationControlDataPtr appControlData(new ApplicationControlData());
633                         appControlData->setKey(keyStr);
634                         appControlData->setValue(valArray);
635                         appControlDataArray->push_back(appControlData);
636
637                         if (value)
638                                 free(value);
639
640                         break;
641                 }
642                 case SERVICE_ERROR_INVALID_PARAMETER:
643                         LoggerE("service_get_extra_data retuns SERVICE_ERROR_INVALID_PARAMETER");
644                         break;
645                 case SERVICE_ERROR_KEY_NOT_FOUND:
646                         LoggerE("service_get_extra_data retuns SERVICE_ERROR_KEY_NOT_FOUND");
647                         break;
648                 case SERVICE_ERROR_OUT_OF_MEMORY:
649                         LoggerE("service_get_extra_data retuns SERVICE_ERROR_OUT_OF_MEMORY");
650                         break;
651                 default:
652                         LoggerE("service_get_extra_data retuns Error");
653                         break;
654                 }
655         }
656         
657         return true;
658 }
659
660
661 ApplicationPtr ApplicationManager::getCurrentApplication()
662 {
663         std::string appId = get_current_app_id();
664
665         //ApplicationInformationPtr appinfo(new ApplicationInformation(appId));
666         pkgmgrinfo_appinfo_h handle;
667         TIME_TRACER_ITEM_BEGIN("(getCurrentApplication)pkgmgrinfo_appinfo_get_appinfo", 0);
668         int ret = pkgmgrinfo_appinfo_get_appinfo(appId.c_str(), &handle);
669         TIME_TRACER_ITEM_END("(getCurrentApplication)pkgmgrinfo_appinfo_get_appinfo", 0);
670         if (ret != PMINFO_R_OK) {
671                 LoggerE("Fail to get appInfo");
672                 ThrowMsg(UnknownException, "pkgmgrinfo_appinfo_get_appinfo error : unknown error");
673         }
674         ApplicationInformationPtr appInfo = create_app_info(handle);
675         pkgmgrinfo_appinfo_destroy_appinfo(handle);
676
677
678         ApplicationPtr app(new Application());
679         app->setAppInfo(appInfo);
680
681         LoggerD("set appinfo to application");
682         {
683                 //int pid = getpid();
684                 int pid = getppid();
685                 std::stringstream sstr;
686                 sstr << pid;
687                 app->setContextId(sstr.str());
688         }
689
690         return app;
691 }
692
693
694 ApplicationContextPtr ApplicationManager::getAppContext(const std::string id)
695 {
696         int ret = 0;
697
698         std::string contextId = id;
699         std::string appId;
700
701         int selfpid = getppid();
702
703         if(contextId.empty())
704         {
705                 std::stringstream sstr;
706                 sstr << selfpid;
707                 contextId = sstr.str();
708
709                 appId = get_current_app_id();
710         }
711         else
712         {
713                 int pid = 0;
714                 std::stringstream(contextId) >> pid;
715                 if (pid <= 0)
716                 {
717                         LoggerE("Given contextId is wrong");
718                         ThrowMsg(NotFoundException, "Given contextId is wrong");
719                 }
720
721                 if(pid == selfpid)
722                 {
723                         std::stringstream sstr;
724                         sstr << selfpid;
725                         contextId = sstr.str();
726
727                         appId = get_current_app_id();
728                 }
729                 else
730                 {
731                         char *app_id = NULL;
732
733                         TIME_TRACER_ITEM_BEGIN("(getAppContext)app_manager_get_app_id", 0);
734                         ret = app_manager_get_app_id(pid, &app_id);
735                         TIME_TRACER_ITEM_END("(getAppContext)app_manager_get_app_id", 0);
736                         if(ret != APP_MANAGER_ERROR_NONE)
737                         {
738                                 if(app_id)
739                                         free(app_id);
740
741                                 switch(ret)
742                                 {
743                                 case APP_MANAGER_ERROR_NO_SUCH_APP:
744                                 case APP_MANAGER_ERROR_INVALID_PARAMETER:
745                                         LoggerE("app_manager_get_app_id error : no such app");
746                                         ThrowMsg(NotFoundException, "app_manager_get_app_id error : no such app");
747                                         break;
748                                 default:
749                                         LoggerE("app_manager_get_app_id error (" << ret << ")");
750                                         ThrowMsg(UnknownException, "app_manager_get_app_id error : unknown error");
751                                         break;
752                                 }
753                         }
754
755                         appId = app_id;
756
757                         if(app_id)
758                                 free(app_id);
759                 }
760         }
761
762         ApplicationContextPtr appContext(new ApplicationContext());
763         appContext->setAppId(appId);
764         appContext->setContextId(contextId);
765
766         return appContext;
767 }
768
769
770 ApplicationInformationPtr ApplicationManager::getAppInfo(const std::string id)
771 {
772         std::string appId = id;
773         // in case of no argument, get application information of current.
774         if (appId.empty())
775         {
776                 appId = get_current_app_id();
777         }
778
779         pkgmgrinfo_appinfo_h handle;
780         TIME_TRACER_ITEM_BEGIN("(getAppInfo)pkgmgrinfo_appinfo_get_appinfo", 0);
781         int ret = pkgmgrinfo_appinfo_get_appinfo(appId.c_str(), &handle);
782         TIME_TRACER_ITEM_END("(getAppInfo)pkgmgrinfo_appinfo_get_appinfo", 0);
783         if (ret != PMINFO_R_OK) {
784                 ThrowMsg(NotFoundException, "Can not get appinfo");
785         }
786
787         ApplicationInformationPtr appInfo = create_app_info(handle);
788
789         pkgmgrinfo_appinfo_destroy_appinfo(handle);
790
791         return appInfo;
792 }
793
794
795 ApplicationCertArrayPtr ApplicationManager::getAppCerts(const std::string id)
796 {
797         std::string appId = id;
798
799         // in case of no argument, get application information of current.
800         if (appId.empty())
801         {
802                 appId = get_current_app_id();
803         }
804
805         TIME_TRACER_ITEM_BEGIN("(getAppCerts)getPackageByAppId", 0);
806         char* package = getPackageByAppId(appId.c_str());
807         TIME_TRACER_ITEM_END("(getAppCerts)getPackageByAppId", 0);
808         if (package == NULL)
809         {
810                 LoggerE("Can not get package");
811                 ThrowMsg(NotFoundException, "Can not get package");
812         }
813
814         package_info_h pkg_info;
815         int result = 0;
816
817         TIME_TRACER_ITEM_BEGIN("(getAppCerts)package_manager_get_package_info", 0);
818         result = package_manager_get_package_info(package, &pkg_info);
819         TIME_TRACER_ITEM_END("(getAppCerts)package_manager_get_package_info", 0);
820         if (result != PACKAGE_MANAGER_ERROR_NONE)
821         {
822                 ThrowMsg(UnknownException, "Can not get package info");
823         }       
824
825         ApplicationCertArrayPtr certArray(new ApplicationCertArray());
826
827         TIME_TRACER_ITEM_BEGIN("(getAppCerts)package_info_foreach_cert_info", 0);
828         result = package_info_foreach_cert_info(pkg_info, package_cert_cb, (void*)certArray.Get());
829         TIME_TRACER_ITEM_END("(getAppCerts)package_info_foreach_cert_info", 0);
830         if ((result != PACKAGE_MANAGER_ERROR_NONE) && (result != PACKAGE_MANAGER_ERROR_IO_ERROR))
831         {
832                 package_info_destroy(pkg_info);
833                 ThrowMsg(UnknownException, "Can not get package cert info");
834         }
835
836         TIME_TRACER_ITEM_BEGIN("(getAppCerts)package_info_destroy", 0);
837         result = package_info_destroy(pkg_info);
838         TIME_TRACER_ITEM_END("(getAppCerts)package_info_destroy", 0);
839         if (result != PACKAGE_MANAGER_ERROR_NONE)
840         {
841                 LoggerE("Failed to destroy package_info");
842         }
843
844         return certArray;
845 }
846
847 std::string ApplicationManager::getAppSharedURI(const std::string id)
848 {
849 #define TIZENAPIS_APP_FILE_SCHEME               "file://"
850 #define TIZENAPIS_APP_SLASH                             "/"
851 #define TIZENAPIS_APP_SHARED                    "shared"
852
853         std::string appId;
854
855         if (id.empty()) {
856                 appId = get_current_app_id();
857         } else {
858                 appId = id;
859         }
860
861         app_info_h handle;
862         char* pkg_name = NULL;
863         TIME_TRACER_ITEM_BEGIN("(getAppSharedURI)app_manager_get_app_info", 0);
864         int ret = app_manager_get_app_info(appId.c_str(), &handle);
865         TIME_TRACER_ITEM_END("(getAppSharedURI)app_manager_get_app_info", 0);
866         if (ret != APP_ERROR_NONE) {
867                 LoggerD("Fail to get appinfo");
868                 //throw NotFoundException("Fail to get appinfo");
869                 ThrowMsg(NotFoundException, "Fail to get appinfo");
870         }
871
872         TIME_TRACER_ITEM_BEGIN("(getAppSharedURI)app_info_get_package", 0);
873         ret = app_info_get_package(handle, &pkg_name);
874         TIME_TRACER_ITEM_END("(getAppSharedURI)app_info_get_package", 0);
875         if ((ret != APP_ERROR_NONE) || (pkg_name == NULL)) {
876                 LoggerD("Fail to get pkg_name");
877                 //throw NotFoundException("Fail to get pkg_name");
878                 ThrowMsg(NotFoundException, "Fail to get pkg_name");
879         }
880
881         app_info_destroy(handle);
882
883         pkgmgrinfo_pkginfo_h pkginfo_h;
884         char* root_path = NULL;
885
886         TIME_TRACER_ITEM_BEGIN("(getAppSharedURI)pkgmgrinfo_pkginfo_get_pkginfo", 0);
887         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &pkginfo_h);
888         TIME_TRACER_ITEM_END("(getAppSharedURI)pkgmgrinfo_pkginfo_get_pkginfo", 0);
889         if (ret != PMINFO_R_OK) {
890                 free(pkg_name);
891                 //throw UnknownException("Fail to get pkginfo");
892                 ThrowMsg(UnknownException, "Fail to get pkginfo");
893         }
894
895         TIME_TRACER_ITEM_BEGIN("(getAppSharedURI)pkgmgrinfo_pkginfo_get_root_path", 0);
896         ret = pkgmgrinfo_pkginfo_get_root_path(pkginfo_h, &root_path);
897         TIME_TRACER_ITEM_END("(getAppSharedURI)pkgmgrinfo_pkginfo_get_root_path", 0);
898         if ((ret != PMINFO_R_OK) || (root_path == NULL)) {
899                 LoggerE("Fail to get root path");
900                 free(pkg_name);
901                 //throw UnknownException("Fail to get rotpath");
902                 ThrowMsg(UnknownException, "Fail to get rotpath");
903         }
904
905         std::string sharedURI = TIZENAPIS_APP_FILE_SCHEME + std::string(root_path) + TIZENAPIS_APP_SLASH + TIZENAPIS_APP_SHARED + TIZENAPIS_APP_SLASH;
906         free(pkg_name);
907
908         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
909
910         return sharedURI;
911 }
912
913 ApplicationMetaDataArrayPtr ApplicationManager::getAppMetaData(const std::string id)
914 {
915         std::string appId = id;
916
917         // in case of no argument, get application information of current.
918         if (appId.empty())
919         {
920                 appId = get_current_app_id();
921         }
922
923         int ret = 0;
924         pkgmgrinfo_appinfo_h handle;
925
926         TIME_TRACER_ITEM_BEGIN("(getAppMetaData)pkgmgrinfo_appinfo_get_appinfo", 0);
927         ret = pkgmgrinfo_appinfo_get_appinfo(appId.c_str(), &handle);
928         TIME_TRACER_ITEM_END("(getAppMetaData)pkgmgrinfo_appinfo_get_appinfo", 0);
929         
930         if (ret != PMINFO_R_OK) {
931                 ThrowMsg(NotFoundException, "Cannot found application with given appId");
932         }
933
934         ApplicationMetaDataArrayPtr metaDataArray(new ApplicationMetaDataArray());
935
936         TIME_TRACER_ITEM_BEGIN("(getAppMetaData)pkgmgrinfo_appinfo_foreach_metadata", 0);
937         ret = pkgmgrinfo_appinfo_foreach_metadata(handle, app_meta_data_cb, (void*)metaDataArray.Get());
938         TIME_TRACER_ITEM_END("(getAppMetaData)pkgmgrinfo_appinfo_foreach_metadata", 0);
939         
940         if (ret != PMINFO_R_OK) {
941                 LoggerE("pkgmgrinfo_appinfo_metadata_filter_foreach() failed");
942                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
943                 ThrowMsg(UnknownException, "fail to get custom tag");
944         }
945
946         pkgmgrinfo_appinfo_destroy_appinfo(handle);
947
948         return metaDataArray;
949 }
950
951 void ApplicationManager::OnRequestReceived(const EventApplicationLaunchPtr& event)
952 {
953         Try
954         {
955                 int ret;
956                 int retry = 0;
957
958                 std::string appId = event->getAppId();
959                 if(appId.empty())
960                 {
961                         LoggerE("App id is mandatory field.");
962                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
963                         return;
964                 }
965
966                 // if the application is running, send raise event to the app instead of reset the application.
967                 // give a second chance to launch application to avoid platform issue.
968                 // this retry code will be removed after platform code change.
969                 while (retry < 3) {
970                         ret = aul_open_app(appId.c_str());
971                         if (ret >= 0) {
972                                 break;
973                         }
974                         // delay 300ms for each retry
975                         usleep(300 * 1000);
976                         retry++;
977                         LoggerD("retry launch request : " << retry);
978                 }
979
980                 if (ret < 0) {
981                         switch (ret)
982                         {
983                         case AUL_R_EINVAL:
984                         case AUL_R_ERROR:       
985                                 LoggerE("returns Not Found error");
986                                 event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);                            
987                                 break;
988                         case AUL_R_ECOMM:
989                                 LoggerE("returns internal IPC error");
990                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);                            
991                                 break;
992                         default:
993                                 LoggerE("returns Unknown error");
994                                 event->setExceptionCode(Commons::ExceptionCodes::UnknownException);                             
995                                 break;
996                         }
997                 } else {
998                         LoggerD("Success to launch.");
999                 }
1000         }
1001         Catch (WrtDeviceApis::Commons::Exception)
1002         {
1003                 LoggerE("Error on launch : " << _rethrown_exception.GetMessage());
1004                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1005         }
1006 }
1007
1008 // Because of platform issue, some termination event is not come to app_manager_set_app_context_event_cb().
1009 // To prevent blocking issue by wating callback function, add termination checking code.
1010 // this function check whether callback is called or not after 3 sec. if callback is not called,
1011 // calls callback function forcibily.
1012 // After fixing platform issue, below code should be removed
1013
1014 typedef struct {
1015         ApplicationManager* appManager;
1016         int pid;
1017         EventApplicationKillPtr event;
1018 } KILL_DATA_T;
1019
1020 gboolean check_terminate_callback (gpointer user_data)
1021 {
1022         //EventApplicationKillPtr event = (EventApplicationKillPtr)data;
1023         KILL_DATA_T* data = (KILL_DATA_T*)user_data;
1024
1025         char * appId = NULL;
1026         if (app_manager_get_app_id(data->pid, &appId) == APP_MANAGER_ERROR_NONE) {
1027                 // if context is still alive, error callback should be called.
1028                 data->event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1029         }
1030
1031         data->appManager->invokeManualAnswerKill(data->pid);
1032
1033         return false;
1034 }
1035
1036
1037 void ApplicationManager::OnRequestReceived(const EventApplicationKillPtr& event)
1038 {
1039         Try
1040         {
1041                 int ret;
1042                 std::string contextId = event->getContextId();
1043
1044                 if(contextId.empty())
1045                 {
1046                         LoggerE("Context id is mandatory");
1047                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1048                         return;
1049                 }
1050
1051                 int pid;
1052                 std::stringstream(contextId) >> pid;
1053                 if(pid <= 0)
1054                 {
1055                         LoggerE("Given context id is wrong");
1056                         event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1057                         return;
1058                 }
1059
1060                 // if kill request is come for current context, throw InvalidValueException by spec
1061                 if (pid == getppid())
1062                 {
1063                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1064                         return;
1065                 }
1066
1067                 char *appIdCStr = NULL;
1068                 ret = app_manager_get_app_id(pid, &appIdCStr);
1069                 if (ret != APP_MANAGER_ERROR_NONE)
1070                 {
1071                         LoggerE("Error while getting app id (" << ret << ")");
1072                         event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1073                         return;
1074                 }
1075
1076                 std::string appId = appIdCStr;
1077                 free(appIdCStr);
1078
1079                 app_context_h appContext;
1080                 ret = app_manager_get_app_context (appId.c_str(), &appContext);
1081                 if (ret != APP_MANAGER_ERROR_NONE)
1082                 {
1083                         LoggerE("Error while getting app context (" << ret << ")");
1084                         event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1085                         return;
1086                 }
1087
1088                 // TODO thread
1089                 ret = app_manager_set_app_context_event_cb(app_manager_app_context_event_callback, this);
1090                 if (ret != APP_MANAGER_ERROR_NONE)
1091                 {
1092                         LoggerE("Error while registering app context event (" << ret << ")");
1093                         event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
1094                         return;
1095                 }
1096
1097                 ret = app_manager_terminate_app(appContext);
1098                 if (ret != APP_MANAGER_ERROR_NONE)
1099                 {
1100                         LoggerE("Error while terminating app (" << ret << ")");
1101                         event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
1102                         return;
1103                 }
1104
1105                 // Because of platform issue, some termination event is not come to app_manager_set_app_context_event_cb().
1106                 // To prevent blocking issue by wating callback function, add termination checking code.
1107                 // this function check whether callback is called or not after 3 sec. if callback is not called,
1108                 // calls callback function forcibily.
1109                 // After fixing platform issue, below code should be removed
1110                 {
1111                         KILL_DATA_T *data = new KILL_DATA_T;
1112                         data->pid = pid;
1113                         data->appManager = this;
1114                         data->event = event;
1115                         g_timeout_add(3000, check_terminate_callback, (void*)data);
1116                 }
1117
1118                 DPL::Mutex::ScopedLock lock(&m_killMapLock);
1119                 m_killEventMap[pid] = event;
1120                 event->switchToManualAnswer();
1121         }
1122         Catch (WrtDeviceApis::Commons::Exception)
1123         {
1124                 LoggerE("Error on kill : " << _rethrown_exception.GetMessage());
1125                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1126         }
1127 }
1128
1129 void ApplicationManager::OnRequestReceived(const EventApplicationLaunchAppControlPtr& event)
1130 {
1131         Try
1132         {
1133                 int ret = 0;
1134                 int retry = 0;
1135
1136                 ApplicationControlPtr appControl = event->getAppControl();
1137                 if(appControl == NULL)
1138                 {
1139                         LoggerE("appControl is mandatory");
1140                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1141                         return;
1142                 }
1143
1144                 std::string operation = appControl->getOperation();
1145                 if(operation.empty())
1146                 {
1147                         LoggerE("operation is madatory");
1148                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1149                         return;
1150                 }
1151
1152                 std::string appId = event->getAppId();
1153
1154                 service_h service;
1155                 service_create(&service);
1156
1157                 if (!appId.empty())
1158                 {
1159                         service_set_app_id(service, appId.c_str());
1160
1161                         // get resolved app id for aliased app id cannot be used to app_manager_get_app_info()
1162                         char* resolved_app_id = NULL;
1163                         service_get_app_id(service, &resolved_app_id);
1164
1165                         // Application exist checking. if specific application is not exist, return Not Found Exception.
1166                         app_info_h info_h;
1167                         if (app_manager_get_app_info(resolved_app_id, &info_h) != APP_MANAGER_ERROR_NONE) {
1168                                 event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1169                                 if (resolved_app_id) {
1170                                         free(resolved_app_id);
1171                                 }
1172                                 service_destroy(service);
1173                                 return;
1174                         }
1175
1176                         app_info_destroy(info_h);
1177                         if (resolved_app_id) {
1178                                 free(resolved_app_id);
1179                         }
1180                 }
1181
1182                 const char* windowId = IPCMessageSupport::sendMessageToUiProcess("tizen://getWindowHandle", NULL);
1183                 if (windowId != NULL)
1184                 {
1185                         service_set_window(service, atoi(windowId));
1186                 }
1187
1188                 service_set_operation(service, operation.c_str() );
1189
1190                 std::string uri = appControl->getUri();
1191                 if (!uri.empty())
1192                 {
1193                         service_set_uri(service, uri.c_str() );
1194                 }
1195
1196                 std::string mime = appControl->getMime();
1197                 if (!mime.empty())
1198                 {
1199                         service_set_mime(service, mime.c_str() );
1200                 }
1201
1202                 std::string category = appControl->getCategory();
1203                 if (!category.empty())
1204                 {
1205                         service_set_category(service, category.c_str() );
1206                 }
1207
1208                 std::vector<ApplicationControlDataPtr> appControlDataArray = appControl->getAppControlDataArray();
1209
1210                 if(!appControlDataArray.empty())
1211                 {
1212                         LoggerI(" data size     : " << appControlDataArray.size());
1213
1214                         ApplicationControlDataArray::iterator iter;
1215                         for(iter = appControlDataArray.begin(); iter != appControlDataArray.end(); iter++)
1216                         {
1217                                 ApplicationControlDataPtr appControlData = *iter;
1218
1219                                 std::string key = appControlData->getKey();
1220
1221                                 if(key.empty())
1222                                 {
1223                                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1224                                         continue;
1225                                 }
1226
1227                                 std::vector<std::string> valueArray = appControlData->getValue();
1228                                 size_t size = valueArray.size();
1229
1230                                 const char **arr = (const char**)calloc(sizeof(char*), size);
1231
1232                                 for (size_t j = 0; j < size; j++)
1233                                 {
1234                                         arr[j] = valueArray.at(j).c_str();
1235                                 }
1236
1237                                 // @20121207-wscho: roll-back to return extra-data instead of extra-data array when the value size is one.
1238                                 const char *keyCStr = key.c_str();
1239                                 if (size == 1) {
1240                                         service_add_extra_data(service, keyCStr, arr[0]);
1241                                 } else {
1242                                         service_add_extra_data_array(service, keyCStr, arr, size);
1243                                 }
1244
1245                                 if (arr)
1246                                         free(arr);
1247                         }
1248                 }
1249
1250                 LaunchAppControlPendingEvent *pendingEvent = NULL;
1251                 LaunchAppControlPendingEventMap::DataKeyType key = 0;
1252
1253                 EventApplicationLaunchAppControlReplyPtr eventReply = event->getEventReply();
1254                 if(eventReply)
1255                 {
1256                         pendingEvent = new LaunchAppControlPendingEvent((void*)this, eventReply);
1257                         key = gLaunchAppControlPendingEventMap.insert(this, pendingEvent);
1258                 }
1259
1260                 // give a second chance to launch application to avoid platform issue.
1261                 // this retry code will be removed after platform code change.
1262                 while (retry < 3) {
1263                         ret = service_send_launch_request(service, service_reply_callback, (void *)key);
1264                         if (ret != SERVICE_ERROR_LAUNCH_REJECTED) {
1265                                 break;
1266                         }
1267                         // delay 300ms for each retry
1268                         usleep(300 * 1000);
1269                         retry++;
1270                         LoggerD("retry launch request : " << retry);
1271                 }
1272
1273                 service_destroy(service);
1274
1275                 if(ret != SERVICE_ERROR_NONE)
1276                 {
1277                         switch (ret)
1278                         {
1279                         case SERVICE_ERROR_INVALID_PARAMETER:
1280                                 LoggerE("service_send_launch_request returns SERVICE_ERROR_INVALID_PARAMETER");
1281                                 event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1282                                 break;
1283                         case SERVICE_ERROR_OUT_OF_MEMORY:
1284                                 LoggerE("service_send_launch_request returns SERVICE_ERROR_OUT_OF_MEMORY");
1285                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1286                                 break;
1287                         case SERVICE_ERROR_LAUNCH_REJECTED:
1288                                 LoggerE("service_send_launch_request returns SERVICE_ERROR_LAUNCH_REJECTED!!!");
1289                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1290                                 break;
1291                         case SERVICE_ERROR_APP_NOT_FOUND:
1292                                 LoggerE("service_send_launch_request returns SERVICE_ERROR_APP_NOT_FOUND");
1293                                 event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1294                                 break;
1295                         default:
1296                                 LoggerE("service_send_launch_request returns UNKNOWN ERROR!!!");
1297                                 event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
1298                                 break;
1299                         }
1300
1301                         if(pendingEvent)
1302                         {
1303                                 gLaunchAppControlPendingEventMap.eraseData(key);
1304
1305                                 delete pendingEvent;
1306                                 pendingEvent = NULL;
1307
1308                                 eventReply->cancelRequest();
1309                                 EventRequestReceiver<EventApplicationLaunchAppControlReply>::ManualAnswer(eventReply);
1310                         }
1311                 }
1312         }
1313         Catch (WrtDeviceApis::Commons::Exception)
1314         {
1315                 LoggerE("Error on launchAppControl : " << _rethrown_exception.GetMessage());
1316                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1317         }
1318 }
1319
1320 void ApplicationManager::OnRequestReceived(const EventApplicationLaunchAppControlReplyPtr& event)
1321 {
1322         event->switchToManualAnswer();
1323 }
1324
1325 void ApplicationManager::OnRequestReceived(const EventApplicationFindAppControlPtr& event)
1326 {
1327         Try
1328         {
1329                 ApplicationControlPtr appControl = event->getAppControl();
1330                 if(appControl == NULL)
1331                 {
1332                         LoggerE("appControl is NULL");
1333                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1334                         return;
1335                 }
1336
1337                 std::string operation = appControl->getOperation();
1338                 if(operation.empty())
1339                 {
1340                         LoggerE("operation is madatory");
1341                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1342                         return;
1343                 }
1344
1345                 service_h service;
1346                 service_create(&service);
1347
1348                 service_set_operation(service, operation.c_str() );
1349
1350                 std::string uri = appControl->getUri();
1351                 if (!uri.empty())
1352                 {
1353                         service_set_uri(service, uri.c_str() );
1354                 }
1355
1356                 std::string mime = appControl->getMime();
1357                 if (!mime.empty())
1358                 {
1359                         service_set_mime(service, mime.c_str() );
1360                 }
1361
1362                 std::string category = appControl->getCategory();
1363                 if (!category.empty())
1364                 {
1365                         service_set_category(service, category.c_str() );
1366                 }
1367
1368                 std::vector<ApplicationControlDataPtr> appControlDataArray = appControl->getAppControlDataArray();
1369
1370                 if(!appControlDataArray.empty())
1371                 {
1372                         LoggerD(" data size     : " << appControlDataArray.size());
1373
1374                         ApplicationControlDataArray::iterator iter;
1375                         for(iter = appControlDataArray.begin(); iter != appControlDataArray.end(); iter++)
1376                         {
1377                                 ApplicationControlDataPtr appControlData = *iter;
1378
1379                                 std::string key = appControlData->getKey();
1380
1381                                 if(key.empty())
1382                                 {
1383                                         event->setExceptionCode(Commons::ExceptionCodes::InvalidArgumentException);
1384                                         continue;
1385                                 }
1386
1387                                 std::vector<std::string> valueArray = appControlData->getValue();
1388                                 size_t size = valueArray.size();
1389
1390                                 const char **arr = (const char**)calloc(sizeof(char*), size);
1391
1392                                 for (size_t j = 0; j < size; j++)
1393                                 {
1394                                         arr[j] = valueArray.at(j).c_str();
1395                                 }
1396
1397                                 // @20121207-wscho: roll-back to return extra-data instead of extra-data array when the value size is one.
1398                                 const char *keyCStr = key.c_str();
1399                                 if (size == 1) {
1400                                         service_add_extra_data(service, keyCStr, arr[0]);
1401                                 } else {
1402                                         service_add_extra_data_array(service, keyCStr, arr, size);
1403                                 }
1404
1405                                 if (arr)
1406                                         free(arr);
1407                         }
1408                 }
1409
1410                 ApplicationInformationArrayPtr appInfos(new ApplicationInformationArray());
1411
1412                 int result = service_foreach_app_matched(service, service_app_matched_callback, (void *)appInfos.Get());
1413                 if (result != SERVICE_ERROR_NONE)
1414                 {
1415                         LoggerE("service_foreach_app_matched error (" << result << ")");
1416                         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1417                         service_destroy(service);
1418                         return;
1419                 }
1420
1421                 service_destroy(service);
1422
1423                 event->setAppInfos(appInfos);
1424         }
1425         Catch (WrtDeviceApis::Commons::Exception)
1426         {
1427                 LoggerE("Error on findAppControl : " << _rethrown_exception.GetMessage());
1428                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1429         }
1430 }
1431
1432
1433 void ApplicationManager::OnRequestReceived(const EventApplicationGetAppsContextPtr& event)
1434 {
1435         Try
1436         {
1437                 int ret = 0;
1438
1439                 ApplicationContextArrayPtr appContextArray = event->getAppContextArray();
1440                 ret = app_manager_foreach_app_context(app_manager_app_context_callback, appContextArray.Get());
1441                 if(ret != APP_MANAGER_ERROR_NONE)
1442                 {
1443                         LoggerE("app_manager_foreach_app_context error (" << ret << ")");
1444                         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1445                 }
1446         }
1447         Catch (WrtDeviceApis::Commons::Exception)
1448         {
1449                 LoggerE("Error on  : " << _rethrown_exception.GetMessage());
1450                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1451         }
1452 }
1453
1454
1455
1456 void ApplicationManager::OnRequestReceived(const EventApplicationGetAppsInfoPtr& event)
1457 {
1458         Try
1459         {
1460                 int ret = 0;
1461                 ApplicationInformationArrayPtr appInfoArray = event->getAppInfoArray();
1462                 ret = pkgmgrinfo_appinfo_get_installed_list(installed_app_info_cb, (void*)appInfoArray.Get());
1463                 if (ret != PMINFO_R_OK) {
1464                         LoggerE("Error on getAppsInfo : ");
1465                         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1466                 }
1467         }
1468         Catch (WrtDeviceApis::Commons::Exception)
1469         {
1470                 LoggerE("Error on getAppsInfo : " << _rethrown_exception.GetMessage());
1471                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1472         }
1473 }
1474
1475
1476 void ApplicationManager::OnRequestReceived(const EventApplicationAddAppInfoEventListenerPtr& event)
1477 {
1478         Try
1479         {
1480                 EventApplicationAppInfoEventListenerEmitterPtr emitter = event->getEmitter();
1481
1482                 if(m_installedApplicationsEmitters.size() == 0)
1483                 {
1484                         LoggerD("First time registering event listener to this application object.");
1485
1486                         // Below can throw Exception
1487                         AppManagerWrapperSingleton::Instance().registerAppListChangedCallbacks(this);
1488                 }
1489
1490                 m_installedApplicationsEmitters.attach(emitter);
1491
1492                 long watchId = AppManagerWrapperSingleton::Instance().getWatchIdAndInc();
1493
1494                 m_watchIdMap[watchId] = emitter->getId();
1495
1496                 event->setWatchId(watchId);
1497         }
1498         Catch (WrtDeviceApis::Commons::Exception)
1499         {
1500                 LoggerE("Error on addAppInfoEventListener : " << _rethrown_exception.GetMessage());
1501                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1502         }
1503 }
1504
1505 void ApplicationManager::OnRequestReceived(const EventApplicationRemoveAppInfoEventListenerPtr& event)
1506 {
1507         Try
1508         {
1509                 long watchId = event->getWatchId();
1510
1511                 if(m_watchIdMap.find(watchId) == m_watchIdMap.end()) {
1512                         ThrowMsg(NotFoundException, "No watchId : " << watchId);
1513                 }
1514
1515                 EventApplicationAppInfoEventListenerEmitter::IdType emitterId = m_watchIdMap[watchId];
1516
1517                 bool success = m_installedApplicationsEmitters.detach(emitterId);
1518                 if(!success)
1519                         ThrowMsg(NotFoundException, "No watchId : " << watchId);
1520
1521                 if(m_installedApplicationsEmitters.size() == 0)
1522                 {
1523                         LoggerD("No more event listener on this application object.");
1524
1525                         AppManagerWrapperSingleton::Instance().unregisterAppListChangedCallbacks(this);
1526                 }
1527         }
1528         Catch (WrtDeviceApis::Commons::NotFoundException)
1529         {
1530                 LoggerE("Not found : " << _rethrown_exception.GetMessage());
1531                 event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1532         }
1533         Catch (WrtDeviceApis::Commons::Exception)
1534         {
1535                 LoggerE("Error on removeAppInfoEventListener : " << _rethrown_exception.GetMessage());
1536                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
1537         }
1538 }
1539
1540
1541
1542 void ApplicationManager::onAppManagerEventInstalled(const char *appId)
1543 {
1544         EventApplicationAppInfoEventListenerPtr event(new EventApplicationAppInfoEventListener());
1545
1546         pkgmgrinfo_appinfo_h handle;
1547         int ret = pkgmgrinfo_appinfo_get_appinfo(appId, &handle);
1548         if (ret != PMINFO_R_OK) {
1549                 event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1550         } else {
1551                 ApplicationInformationPtr appInfo = create_app_info(handle);
1552                 event->setAppInfo(appInfo);
1553                 pkgmgrinfo_appinfo_destroy_appinfo(handle); 
1554         }
1555
1556         event->setType(EventApplicationAppInfoEventListener::OnInstalled);      
1557         m_installedApplicationsEmitters.emit(event);
1558 }
1559
1560 void ApplicationManager::onAppManagerEventUninstalled(const char *appId)
1561 {
1562         EventApplicationAppInfoEventListenerPtr event(new EventApplicationAppInfoEventListener());
1563
1564         ApplicationInformationPtr appInfo(new ApplicationInformation(appId));
1565
1566         event->setType(EventApplicationAppInfoEventListener::OnUninstalled);
1567         event->setAppInfo(appInfo);
1568         m_installedApplicationsEmitters.emit(event);
1569 }
1570
1571 void ApplicationManager::onAppManagerEventUpdated(const char *appId)
1572 {
1573         EventApplicationAppInfoEventListenerPtr event(new EventApplicationAppInfoEventListener());
1574
1575         pkgmgrinfo_appinfo_h handle;
1576         int ret = pkgmgrinfo_appinfo_get_appinfo(appId, &handle);
1577         if (ret != PMINFO_R_OK) {
1578                 event->setExceptionCode(Commons::ExceptionCodes::NotFoundException);
1579         } else {
1580                 ApplicationInformationPtr appInfo = create_app_info(handle);
1581                 event->setAppInfo(appInfo);
1582                 pkgmgrinfo_appinfo_destroy_appinfo(handle); 
1583         }
1584
1585         event->setType(EventApplicationAppInfoEventListener::OnUpdated);        
1586         m_installedApplicationsEmitters.emit(event);
1587 }
1588
1589 void ApplicationManager::initialize() 
1590 {
1591         if (!m_initialized) {
1592                 DPL::Mutex::ScopedLock lock(&m_initializationMutex);
1593                 if (!m_initialized) {
1594                         
1595                 }
1596         }
1597 }
1598
1599 }
1600 }