Merge "fix a decfect locale for france locale" into tizen_2.1
[platform/framework/native/appfw.git] / src / app / FApp_AppControlManager.cpp
1 //
2 // Open Service Platform
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 /**
19  * @file        FApp_AppControlManager.cpp
20  * @brief       This is the implementation for the _AppControlManager class.
21  */
22
23 #include <stdint.h>
24 #include <cstdio>
25 #include <unique_ptr.h>
26
27 #include <appsvc/appsvc.h>
28 #include <aul/aul.h>
29 #include <bundle.h>
30 #include <content/mime_type.h>
31
32 #include <FBaseInteger.h>
33 #include <FBaseObject.h>
34 #include <FBaseString.h>
35 #include <FBaseColIListT.h>
36 #include <FBaseColArrayList.h>
37 #include <FBaseErrors.h>
38 #include <FAppAppControl.h>
39 #include <FAppAppManager.h>
40 #include <FAppIAppControlListener.h>
41 #include <FAppIAppControlResponseListener.h>
42 #include <FAppIAppFrame.h>
43 #include <FAppSqlDataControl.h>
44 #include <FAppMapDataControl.h>
45 #include <FAppPkgPackageInfo.h>
46
47 #include <FBaseSysLog.h>
48 #include <FBase_StringConverter.h>
49 #include <FBaseRt_LibraryImpl.h>
50 #include <FIo_DataControlResultSetImpl.h>
51
52 #include "FApp_AppArg.h"
53 #include "FApp_AppControlEventArg.h"
54 #include "FApp_AppControlRegistry.h"
55 #include "FApp_AppControlImpl.h"
56 #include "FApp_AppImpl.h"
57 #include "FApp_AppInfo.h"
58 #include "FApp_AppManagerEventArg.h"
59 #include "FApp_Aul.h"
60 #include "FApp_AppControlManager.h"
61 #include "FApp_AppManagerProxy.h"
62 #include "FApp_ConditionManagerProxy.h"
63 #include "FApp_IAppManagerEventListener.h"
64 #include "FApp_MapDataControlImpl.h"
65 #include "FApp_SqlDataControlImpl.h"
66 #include "FAppPkg_PackageManagerImpl.h"
67 #include "FAppPkg_PackageInfoImpl.h"
68 #include "FApp_AppMessageImpl.h"
69 #include "FApp_AppManagerImpl.h"
70
71 using namespace Tizen::App::Package;
72 using namespace Tizen::Base;
73 using namespace Tizen::Base::Collection;
74 using namespace Tizen::Base::Runtime;
75 using namespace Tizen::Base::Utility;
76 using namespace Tizen::Io;
77
78 //extern const char* _DATACONTROL_RESULTSET_DIR;
79
80 namespace Tizen { namespace App
81 {
82
83 const wchar_t TIZEN_OPERATION_PICK[] = L"http://tizen.org/appcontrol/operation/pick";
84 const wchar_t SELECTOR_NOTI_KEY[] = L"__APP_SVC_CALLER_NOTI__";
85 const int _MAX_PACKAGE_ID_LENGTH = 10;
86 const int _MAX_DATA_ARGUMENT_LENGTH = 32768; // 32KB
87
88 _InProcessInfo::~_InProcessInfo(void)
89 {
90         delete pLib;
91 }
92
93 _LaunchInfo::~_LaunchInfo(void)
94 {
95         delete pArg;
96 }
97
98
99 _AppControlManager::_AppControlManager(void)
100 {
101         SysLog(NID_APP, "");
102
103         // AppControl event handling is expected to be performed in the main thread.
104         __appControlEvent.Construct();
105         __appControlEvent.AddListener(*dynamic_cast<_IAppControlSysEventListener*>(this));
106         __listenerList.Construct();
107 }
108
109 _AppControlManager::~_AppControlManager(void)
110 {
111         SysLog(NID_APP, "");
112         __appControlEvent.RemoveListener(*dynamic_cast<_IAppControlSysEventListener*>(this));
113 }
114
115 _AppControlManager*
116 _AppControlManager::GetInstance(void)
117 {
118         static _AppControlManager inst;
119
120         return &inst;
121 }
122
123 result
124 _AppControlManager::GetMimeFromExt(const String& ext, String& out)
125 {
126         std::unique_ptr<char[]> pExtension(_StringConverter::CopyToCharArrayN(ext));
127         SysTryReturnResult(NID_APP, pExtension != null, E_OUT_OF_MEMORY, "String allocation failure.");
128
129         char* mime = NULL;
130         mime_type_get_mime_type(pExtension.get(), &mime);
131
132         SysTryReturnResult(NID_APP, mime != NULL, E_UNSUPPORTED_FORMAT, "MIME type conversion failure for %ls.", ext.GetPointer());
133
134         out = mime;
135         free(mime);
136
137         return E_SUCCESS;
138 }
139
140 void
141 _AppControlManager::OnAppControlEventReceivedN(int reqId, _AppArg* pAppArg, int res)
142 {
143         SysLog(NID_APP, "Received request Id %d, arg 0x%x", reqId, pAppArg);
144
145         //_AppArg::Print(b);
146         // get launch info from request Id
147         _LaunchInfo* pInfo = __launchManager.FindItem(reqId);
148         SysTryReturnVoidResult(NID_APP, pInfo != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] request Id %d not found with response %d", reqId,
149                                         res);
150
151         // invoke callback
152         if (pInfo->launchCb)
153         {
154                 if (pInfo->magic == LAUNCH_INFO_MAGIC)
155                 {
156                         SysLog(NID_APP, "Invoking callback 0x%x", pInfo->launchCb);
157                         //pAppArg->Print();
158
159                         if (pInfo->pUserData && (!__listenerList.Contains(pInfo->pUserData)))
160                         {
161                                 (*pInfo->launchCb)(pInfo->pUserData, pInfo->pArg, pAppArg, static_cast<service_result_e>(res), pInfo->property);
162                         }
163                 }
164                 else
165                 {
166                         SysLogException(NID_APP, E_SYSTEM, "Corrupted data structure.");
167                 }
168         }
169
170         // clean up argument
171         __launchManager.RemoveItem(reqId);
172 }
173
174
175 // callback for out-of-process AppControl start event
176 void
177 _AppControlManager::OnAppControlEventReceivedN(int reqId, const AppId& appId, const String& operationId)
178 {
179         SysLog(NID_APP, "Received request Id %d, appId %ls, operationId %ls", reqId, appId.GetPointer(), operationId.GetPointer());
180
181         // get launch info from request Id
182         _LaunchInfo* pInfo = __launchManager.FindItem(reqId);
183         SysTryReturnVoidResult(NID_APP, pInfo != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] request Id %d not found.", reqId);
184
185         // at least listener
186         IAppControlResponseListener* pListener = static_cast<IAppControlResponseListener*>(pInfo->pUserData);
187         SysTryReturnVoidResult(NID_APP, typeid(pListener) == typeid(IAppControlResponseListener*), E_SYSTEM, "[E_SYSTEM] Invalid result callback.");
188
189         if (pListener)
190         {
191                 result r = E_SUCCESS;
192                 AppId actualAppId = appId;
193                 if (appId == L'c')
194                 {
195                         actualAppId.Clear();
196                         r = E_OPERATION_CANCELED;
197                 }
198                 SysLog(NID_APP, "Invoking callback 0x%x.", pListener);
199                 pListener->OnAppControlStartResponseReceived(actualAppId, operationId, r);
200         }
201         else
202         {
203                 SysLog(NID_APP, "No listener registered.");
204         }
205 }
206
207
208 // callback for in-process event handling
209 void
210 _AppControlManager::OnAppControlEventReceivedN(int reqId, int res, const IMap* pArgs)
211 {
212         SysLog(NID_APP, "Received request Id %d, args 0x%x", reqId, pArgs);
213
214         // process proper callback
215         _InProcessInfo* pInfo = __inAppManager.FindItem(reqId);
216         SysTryReturnVoidResult(NID_APP, pInfo != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] request Id %d not found with args 0x%x", reqId,
217                                         pArgs);
218
219         if (pInfo->pListener)
220         {
221                 String aId = pInfo->providerId;
222                 String oId = pInfo->operationId;
223
224                 SysLog(NID_APP, "Invoking callback 0x%x for (%ls, %ls).", pInfo->pListener, aId.GetPointer(), oId.GetPointer());
225
226                 if (pInfo->property & _APPCONTROL_PROPERTY_ALIAS)
227                 {
228                         _AppControlRegistry::_AppControlAliasEntry* pEntry = null;
229                         pEntry = _AppControlRegistry::GetInstance()->GetReverseAppControlAliasEntry(aId, oId);
230                         if (pEntry)
231                         {
232                                 aId = pEntry->provider;
233                                 oId = pEntry->operation;
234
235                                 SysLog(NID_APP, "Legacy AppControl name (%ls, %ls).", aId.GetPointer(), oId.GetPointer());
236                         }
237                 }
238
239                 if (pInfo->isLegacy)
240                 {
241                         IAppControlEventListener* pListener = dynamic_cast<IAppControlEventListener*>(pInfo->pListener);
242                         if (pListener)
243                         {
244                                 ArrayList list(SingleObjectDeleter);
245                                 _AppArg::FillLegacyAppControlResult(list, res, pArgs, aId);
246
247                                 pListener->OnAppControlCompleted(aId, oId, &list);
248                         }
249                         else
250                         {
251                                 SysLog(NID_APP, "Wrong AppControl listener type.");
252                         }
253                 }
254                 else
255                 {
256                         IAppControlResponseListener* pListener = dynamic_cast<IAppControlResponseListener*>(pInfo->pListener);
257                         if (pListener && (!__listenerList.Contains(pInfo->pListener)))
258                         {
259                                 SysLog(NID_APP, "OSP_AC OnAppControlCompleteResponseReceived");
260                                 pListener->OnAppControlCompleteResponseReceived(aId, oId, static_cast<AppCtrlResult>(res), pArgs);
261                         }
262                         else
263                         {
264                                 SysLog(NID_APP, "Wrong AppControl listener type.");
265                         }
266                 }
267         }
268         else
269         {
270                 SysLogException(NID_APP, E_SYSTEM, "Invalid AppControl listener.");
271         }
272
273         // call TerminateAppControl
274         result (* pFunc)(int req) = null;
275         pFunc = reinterpret_cast<result (*)(int)>(pInfo->pLib->GetProcAddress(L"TerminateAppControl"));
276         if (pFunc)
277         {
278                 (*pFunc)(pInfo->reqId);
279         }
280         else
281         {
282                 SysLogException(NID_APP, E_SYSTEM, "No TerminateAppControl() function.");
283         }
284
285         // remove from list and unload dll
286         __inAppManager.RemoveItem(reqId);
287 }
288
289
290 result
291 _AppControlManager::SendAppControlEvent(IEventArg& arg)
292 {
293         return __appControlEvent.FireAsync(arg);
294 }
295
296 // generic launch callback
297 static void
298 LaunchResultCb(bundle* b, int request_code, appsvc_result_val res, void* data)
299 {
300         SysLog(NID_APP, "SLP callee result: %d", res);
301
302         _AppControlManager* pImpl = static_cast<_AppControlManager*>(data);
303         if (pImpl == null)
304         {
305                 return;
306         }
307
308         _AppArg* pAppArg = new (std::nothrow) _AppArg;
309         SysTryReturnVoidResult(NID_APP, pAppArg != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] AppControl event argument creation failure.");
310
311         _AppControlEventArg* pArg = null;
312         result r = pAppArg->Construct(b);
313         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] AppControl event argument creation failure.", GetErrorMessage(r));
314
315         // save callee appId ASAP
316         pAppArg->SaveCalleeAppId();
317
318         pArg = new (std::nothrow) _AppControlEventArg(request_code, pAppArg, res);
319         SysTryCatch(NID_APP, pArg != null, r = E_OUT_OF_MEMORY, r, "[E_OUT_OF_MEMORY] AppControl event argument creation failure.");
320
321         //_AppArg::Print(b);
322         pImpl->SendAppControlEvent(*pArg);
323
324         return;
325
326 CATCH:
327         delete pAppArg;
328 }
329
330
331 result
332 _AppControlManager::SendAppControlStartResponse(int req, const char* pValue, const char* pOp)
333 {
334         _AppControlStartEventArg* pArg = new (std::nothrow) _AppControlStartEventArg(req, AppId(pValue), String(pOp));
335         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "AppControl start event creation failure.");
336
337         SendAppControlEvent(*pArg);
338
339         return E_SUCCESS;
340 }
341
342
343 result
344 _AppControlManager::LaunchPkg(_AppMessageImpl& msg, const char* pkg_name, const char* op, const char* mime, const char* uri, AppSvcResFn pCb, void* data)
345 {
346         bundle* kb = msg.GetBundle();
347         SysTryReturnResult(NID_APP, kb != NULL, E_OUT_OF_MEMORY, "Bundle allocation failure.");
348
349         if (pkg_name)
350         {
351                 appsvc_set_pkgname(kb, pkg_name);
352         }
353
354         appsvc_set_operation(kb, (op) ? op : APPSVC_OPERATION_DEFAULT);
355
356         if (mime)
357         {
358                 appsvc_set_mime(kb, mime);
359         }
360
361         if (uri)
362         {
363                 appsvc_set_uri(kb, uri);
364         }
365
366         if (_AppImpl::GetInstance() != null)
367         {
368                 const long handle = _AppImpl::GetInstance()->GetWindowHandle();
369                 _AppArg::UpdateWindowHandle(kb, handle);
370         }
371
372         SysLog(NID_APP, "MIME(%s), URI(%s).", appsvc_get_mime(kb), appsvc_get_uri(kb));
373         int pid = appsvc_run_service(kb, 0, reinterpret_cast<appsvc_res_fn>(pCb), this);
374
375         result r = E_SUCCESS;
376         if (pid < 0)
377         {
378                 switch (pid)
379                 {
380                 case APPSVC_RET_EILLACC:
381                         r = E_ILLEGAL_ACCESS;
382                         break;
383                 default:
384                         r = E_SYSTEM;
385                         break;
386                 }
387                 SysLog(NID_APP, "[%s]Launching service %s failure", GetErrorMessage(r), pkg_name);
388         }
389
390         return r;
391 }
392 int
393 _AppControlManager::Launch(_AppMessageImpl& msg, const char* pkg_name, const char* op, const char* mime, const char* uri, AppSvcResFn pCb, void* data)
394 {
395         bundle* kb = msg.GetBundle();
396         SysTryReturn(NID_APP, kb != NULL, -1, E_OUT_OF_MEMORY, "Bundle allocation failure.");
397
398         if (pkg_name)
399         {
400                 appsvc_set_pkgname(kb, pkg_name);
401         }
402
403         appsvc_set_operation(kb, (op) ? op : APPSVC_OPERATION_DEFAULT);
404
405         if (mime)
406         {
407                 appsvc_set_mime(kb, mime);
408         }
409
410         if (uri)
411         {
412                 appsvc_set_uri(kb, uri);
413         }
414
415         if (_AppImpl::GetInstance() != null)
416         {
417                 const long handle = _AppImpl::GetInstance()->GetWindowHandle();
418                 _AppArg::UpdateWindowHandle(kb, handle);
419         }
420
421         SysLog(NID_APP, "MIME(%s), URI(%s).", appsvc_get_mime(kb), appsvc_get_uri(kb));
422         int pid = appsvc_run_service(kb, 0, reinterpret_cast<appsvc_res_fn>(pCb), this);
423
424         result r = E_SUCCESS;
425         if (pid < 0)
426         {
427                 switch (pid)
428                 {
429                 case APPSVC_RET_EILLACC:
430                         r = E_ILLEGAL_ACCESS;
431                         break;
432                 default:
433                         r = E_SYSTEM;
434                         break;
435                 }
436                 SysLog(NID_APP, "[%s]Launching service %s failure", GetErrorMessage(r), pkg_name);
437         }
438         SetLastResult(r);
439
440         return pid;
441 }
442
443
444 result
445 _AppControlManager::LaunchPkg(const char* pkg_name, const char* op, const char* mime, const char* uri, AppSvcResFn pCb, void* data)
446 {
447         _AppMessageImpl msg;
448
449         return LaunchPkg(msg, pkg_name, op, mime, uri, pCb, data);
450 }
451
452 result
453 _AppControlManager::LaunchAppWithCondition(const AppId& appId, const String& condition, IList* pArrayArgs)
454 {
455         result r = E_SUCCESS;
456         _AppArg * pArg = new (std::nothrow) _AppArg();
457         SysTryCatch(NID_APP, pArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
458
459         r = pArg->ConstructForAppLaunchCondition(condition, pArrayArgs);
460         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] ConstructForAppLaunchCondition(%ls, .. ) fails", GetErrorMessage(r), condition.GetPointer());
461
462         r = _AppControlManager::LaunchApp(appId, pArg);
463 CATCH:
464         delete pArg;
465         return r;
466 }
467
468 result
469 _AppControlManager::LaunchApp(const AppId& appId, _AppArg* pArg, int req)
470 {
471         SysTryReturnResult(NID_APP, pArg != null, E_INVALID_ARG, "Invalid launch argument");
472         SysLog(NID_APP, "AppId: %ls.", appId.GetPointer());
473
474         String actualAppId = appId;
475         if (appId.GetLength() == 10)
476         {
477                 const String& name = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(appId);
478
479                 if (!name.IsEmpty())
480                 {
481                         actualAppId.Append(L'.');
482                         actualAppId.Append(name);
483                 }
484         }
485
486         pArg->UpdateRequestId(req);
487
488         if (_AppImpl::GetInstance() != null)
489         {
490                 const long handle = _AppImpl::GetInstance()->GetWindowHandle();
491                 pArg->UpdateWindowHandle(handle);
492         }
493
494         int pid = -1;
495         bundle* kb = NULL;
496         String tempId;
497         actualAppId.SubString(0, 10, tempId);
498         tempId += L'.';
499         tempId += L"_AppControl";
500
501         // [INFO] Ugly solution for submode support
502         pArg->UpdateAppId(tempId);
503         kb = pArg->GetBundle();
504
505         bundle_raw* dataBuf = null;
506         int dataLen = 0;
507         int res = bundle_encode(kb, &dataBuf, &dataLen);
508         bundle_free_encoded_rawdata(&dataBuf);
509         SysTryReturnResult(NID_APP, res == 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
510         SysTryReturnResult(NID_APP, dataLen <= _MAX_DATA_ARGUMENT_LENGTH, E_MAX_EXCEEDED,
511                         "The data length (%d) exceeds the maximum limit.", dataLen);
512         
513         pid = appsvc_run_service(kb, req, LaunchResultCb, this);
514         if (pid > 0)
515         {
516                 SysLog(NID_APP, "Submode launch successful");
517                 return E_SUCCESS;
518         }
519
520         pArg->UpdateAppId(actualAppId);
521
522         // retry for possible failure
523         int count = 0;
524         const int TRY_COUNT = 3;
525         const int TRY_SLEEP_TIME = 65;
526         do
527         {
528                 kb = pArg->GetBundle();
529                 pid = appsvc_run_service(kb, req, LaunchResultCb, this);
530                 if (pid > 0)
531                 {
532                         SysLog(NID_APP, "Application(%d) launched with reqId(%d) and arg(0x%x).", pid, req, pArg);
533                         return E_SUCCESS;
534                 }
535                 count++;
536                 SysLog(NID_APP, "Waiting %dth time.", count);
537                 Thread::Sleep(TRY_SLEEP_TIME);
538         }
539         while (count < TRY_COUNT);
540
541         result r = E_SUCCESS;
542         switch (pid)
543         {
544         case APPSVC_RET_EILLACC:
545                 r = E_ILLEGAL_ACCESS;
546                 break;
547         default:
548                 r = E_SYSTEM;
549                 break;
550         }
551
552         SysLogException(NID_APP, r, "[%s] Launching service failure for %ls", GetErrorMessage(r), appId.GetPointer());
553
554         return r;
555 }
556
557 int
558 _AppControlManager::Launch(const AppId& appId, _AppArg* pArg, int req)
559 {
560         SysTryReturn(NID_APP, pArg != null, -1, E_INVALID_ARG, "[E_INVALID_ARG] Invalid launch argument");
561         SysLog(NID_APP, "AppId: %ls.", appId.GetPointer());
562
563         String actualAppId = appId;
564         if (appId.GetLength() == 10)
565         {
566                 const String& name = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(appId);
567
568                 if (!name.IsEmpty())
569                 {
570                         actualAppId.Append(L'.');
571                         actualAppId.Append(name);
572                 }
573         }
574
575         pArg->UpdateRequestId(req);
576
577         if (_AppImpl::GetInstance() != null)
578         {
579                 const long handle = _AppImpl::GetInstance()->GetWindowHandle();
580                 pArg->UpdateWindowHandle(handle);
581         }
582
583         int pid = -1;
584         bundle* kb = NULL;
585         String tempId;
586         actualAppId.SubString(0, 10, tempId);
587         tempId += L'.';
588         tempId += L"_AppControl";
589
590         // [INFO] Ugly solution for submode support
591         pArg->UpdateAppId(tempId);
592         kb = pArg->GetBundle();
593         
594         pid = appsvc_run_service(kb, req, LaunchResultCb, this);
595         if (pid > 0)
596         {
597                 SysLog(NID_APP, "Submode launch successful");
598                 return pid;
599         }
600
601         pArg->UpdateAppId(actualAppId);
602
603         // retry for possible failure
604         int count = 0;
605         const int TRY_COUNT = 3;
606         const int TRY_SLEEP_TIME = 65;
607         do
608         {
609                 kb = pArg->GetBundle();
610                 pid = appsvc_run_service(kb, req, LaunchResultCb, this);
611                 if (pid > 0)
612                 {
613                         SysLog(NID_APP, "Application(%d) launched with reqId(%d) and arg(0x%x).", pid, req, pArg);
614                         return pid;
615                 }
616                 count++;
617                 SysLog(NID_APP, "Waiting %dth time.", count);
618                 Thread::Sleep(TRY_SLEEP_TIME);
619         }
620         while (count < TRY_COUNT);
621
622         result r = E_SUCCESS;
623         switch (pid)
624         {
625         case APPSVC_RET_EILLACC:
626                 r = E_ILLEGAL_ACCESS;
627                 break;
628         default:
629                 r = E_SYSTEM;
630                 break;
631         }
632
633         SysLogException(NID_APP, r, "[%s] Launching service failure for %ls", GetErrorMessage(r), appId.GetPointer());
634
635         SetLastResult(r);
636
637         return pid;
638 }
639
640 result
641 _AppControlManager::LaunchAppImplicit(_AppArg* pArg, int req)
642 {
643         SysTryReturnResult(NID_APP, pArg != null, E_INVALID_ARG, "Invalid launch argument");
644
645         result r = E_SUCCESS;
646         bundle* kb = pArg->GetBundle();
647
648         if (req >= 0)
649         {
650                 pArg->UpdateRequestId(req);
651                 _AppMessageImpl::AddData(kb, SELECTOR_NOTI_KEY, _AppInfo::GetApplicationId());
652         }
653
654         int pid = appsvc_run_service(kb, req, LaunchResultCb, this);
655         if (pid > 0)
656         {
657                 char pkgname[255] = {0, };
658                 aul_app_get_pkgname_bypid(pid, pkgname, 255);
659
660                 if (strncmp(pkgname, APP_SELECTOR, strlen(APP_SELECTOR)) != 0)
661                 {
662                         const char* pOperation = appsvc_get_operation(kb);
663
664                         SysLog(NID_APP, "Starting application without selector : (%s, %s).", pkgname, pOperation);
665
666                         SendAppControlStartResponse(req, pkgname, pOperation);
667                 }
668         }
669         else
670         {
671                 switch (pid)
672                 {
673                         case APPSVC_RET_EINVAL:
674                                 r = E_OBJ_NOT_FOUND;
675                                 break;
676                         case APPSVC_RET_ENOMATCH:
677                                 r = E_OBJ_NOT_FOUND;
678                                 break;
679                         case APPSVC_RET_EILLACC:
680                                 r = E_ILLEGAL_ACCESS;
681                                 break;
682                         case APPSVC_RET_ERROR:
683                                 // fall through
684                         case APPSVC_RET_ELAUNCH:
685                                 // fall through
686                         default:
687                                 r = E_SYSTEM;
688                                 break;
689                 }
690         }
691
692         SysLog(NID_APP, "[%s] Application(%d) launched with reqId(%d) and arg(0x%x).", GetErrorMessage(r), pid, req, pArg);
693
694         return r;
695 }
696
697 void
698 _AppControlManager::FinishAppControl(int reqId, int res, const IMap* pMap)
699 {
700         _NativeAppControlEventArg* pArg = new (std::nothrow) _NativeAppControlEventArg(reqId, res, pMap);
701         SysTryReturnVoidResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Return argument allocation failure.");
702
703         SendAppControlEvent(*pArg);
704 }
705
706 const _AppArg*
707 _AppControlManager::FindResultRequest(int reqId) const
708 {
709         const _ResultInfo* pInfo = __resultManager.FindItem(reqId);
710         return (pInfo) ? &(pInfo->arg) : null;
711 }
712
713 int
714 _AppControlManager::AddLaunchRequest(_AppArg* pArg, LaunchCbType pCb, void* pData, int prop)
715 {
716         SysTryReturn(NID_APP, pArg != null, -1, E_INVALID_ARG, "[E_INVALID_ARG] Empty argument.");
717
718         _LaunchInfo* pItem = new (std::nothrow) _LaunchInfo(pArg, pCb, pData, prop);
719         SysTryReturn(NID_APP, pItem != null, -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Empty argument.");
720
721         SysLog(NID_APP, "Registering callback 0x%x, 0x%x", pCb, pData);
722
723         return __launchManager.InsertItem(pItem);
724 }
725
726 void
727 _AppControlManager::RemoveLaunchRequest(int req)
728 {
729         __launchManager.RemoveItem(req);
730 }
731 int
732 _AppControlManager::GetLaunchRequestCount(void)
733 {
734         return __launchManager.GetCount();
735 }
736
737 result
738 _AppControlManager::RegisterRequest(service_s* service, int& req, _AppHandler& handler)
739 {
740         bundle* b = _AppArg::GetBundleFromSvc(service);
741
742         _AppArg* pArg = new (std::nothrow) _AppArg();
743         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "rrayList creation failure.");
744         pArg->Construct(b);
745
746         result r = E_SUCCESS;
747
748         // ownership is transfered to RequestManager
749         _ResultInfo* pItem = new (std::nothrow) _ResultInfo(*pArg);
750         SysTryCatch(NID_APP, pItem != null, , r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Empty argument.");
751
752         req = __resultManager.InsertItem(pItem);
753         SysTryCatch(NID_APP, req != -1, , r = E_INVALID_STATE, "[E_INVALID_STATE] Invalid argument handling state.");
754
755         handler = _AppArg::GetHandler(b);
756
757         return E_SUCCESS;
758
759 CATCH:
760         delete pArg;
761
762         return r;
763 }
764
765
766 bool
767 _AppControlManager::IsAllowedAppControl(const wchar_t aTable[][2][64], int count, const String& aId, const String& oId)
768 {
769         for (int i = 0; i < count; i++)
770         {
771                 if (aId == aTable[i][0] && oId == aTable[i][1])
772                 {
773                         SysLog(NID_APP, "Found entry (%ls, %ls)", aTable[i][0], aTable[i][1]);
774                         return true;
775                 }
776         }
777
778         return false;
779 }
780
781 }} // Tizen::App