N_SE-44648 : fix window raise on submode
[platform/framework/native/appfw.git] / src / app / FApp_AppControlImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file                FApp_AppControlImpl.cpp
19  * @brief               This is the implementation for the Application Control class.
20  */
21
22 #include <new>
23 #include <typeinfo>
24 #include <unique_ptr.h>
25
26 #include <appsvc/appsvc.h>
27
28 #include <FAppAppControl.h>
29 #include <FAppAppManager.h>
30 #include <FAppPkgPackageAppInfo.h>
31 #include <FBaseColHashMap.h>
32 #include <FBaseSysLog.h>
33
34 #include <FBaseRt_LibraryImpl.h>
35 #include <FIo_DirectoryImpl.h>
36
37 #include "FApp_AppControlImpl.h"
38 #include "FApp_AppControlManager.h"
39 #include "FApp_AppArg.h"
40 #include "FApp_AppControlRegistry.h"
41 #include "FApp_AppMessageImpl.h"
42 #include "FApp_AppInfo.h"
43 #include "FAppPkg_PackageManagerImpl.h"
44 #include "FApp_Aul.h"
45 #include "FApp_AppControlEventArg.h"
46 #include "FApp_AppControlResponseEvent.h"
47 #include "FBaseRt_ThreadImpl.h"
48
49 using namespace Tizen::Base;
50 using namespace Tizen::Base::Collection;
51 using namespace Tizen::Base::Runtime;
52 using namespace Tizen::App;
53 using namespace Tizen::App::Package;
54 using namespace Tizen::Io;
55
56 namespace
57 {
58
59 static const int _REQ_ID_INVALID = -1;
60
61 }
62
63 namespace Tizen { namespace App
64 {
65
66 class IAppControlEventListener;
67 class IAppControlResponseListener;
68
69 const wchar_t TIZEN_OPERATION_MAIN[] = L"http://tizen.org/appcontrol/operation/main";
70
71 _AppControlImpl::_AppControlImpl(const AppControl& value)
72         : _appControl(value)
73         , _reqId(_REQ_ID_INVALID)
74         , _property(_APPCONTROL_PROPERTY_NONE)
75         , _processId(_REQ_ID_INVALID)
76 {
77         __appControlResponseEventList.Construct();
78 }
79
80 _AppControlImpl::~_AppControlImpl(void)
81 {
82         IEnumeratorT<int>* pEnum = __appControlResponseEventList.GetEnumeratorN();
83         IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = null;
84         if(pEnum != null)
85         {
86                 pResponseEventContainer = _AppControlManager::GetInstance()->GetAppControlResponseEventContainer();
87         }
88
89         while(pEnum->MoveNext() == E_SUCCESS)
90         {
91                 int reqId;
92                 pEnum->GetCurrent(reqId);
93                 if (pResponseEventContainer != null)
94                 {
95                         _AppControlResponseEvent* pResponseEvent = null;
96                         pResponseEventContainer->GetValue(reqId, pResponseEvent);
97                         delete pResponseEvent;
98
99                         pResponseEventContainer->Remove(reqId);
100                         SysLog(NID_APP, "pResponseEvent gets deleted. reqId(%d)", reqId);
101                 }
102         }
103         delete pEnum;
104 }
105
106 AppControl*
107 _AppControlImpl::CreateN(const String& path, const String& aId, const String& oId, const String& name, int prop)
108 {
109         SysTryReturn(NID_APP, !path.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] Path is empty.");
110         SysTryReturn(NID_APP, !aId.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] Provider Id is empty.");
111         SysTryReturn(NID_APP, !oId.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] Operation Id is empty.");
112
113         AppControl* pAc = new (std::nothrow) AppControl;
114         SysTryReturn(NID_APP, pAc != null, null, E_OUT_OF_MEMORY, "AppControl allocation failure.");
115
116         _AppControlImpl* pImpl = pAc->__pAppControlImpl;
117         SysTryReturn(NID_APP, pImpl != null, null, E_OUT_OF_MEMORY, "AppControlImpl instance must not be null.");
118
119         pImpl->_path = path;
120         pImpl->_provider = aId;
121         pImpl->_opId = oId;
122         // [FIXME] Proper App name setting
123         pImpl->_appName = name;
124         pImpl->_property = prop;
125
126         return pAc;
127 }
128
129 AppControl*
130 _AppControlImpl::CreateN(const AppId& appId, const String& operationId, bool changeAppId)
131 {
132         SysTryReturn(NID_APP, !appId.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] appId is empty.");
133
134         AppControl* pAc = new (std::nothrow) AppControl;
135         SysTryReturn(NID_APP, pAc != null, null, E_OUT_OF_MEMORY, "AppControl allocation failure.");
136
137         _AppControlImpl* pImpl = pAc->__pAppControlImpl;
138         SysTryReturn(NID_APP, pImpl != null, null, E_OUT_OF_MEMORY, "AppControlImpl instance must not be null.");
139
140         pImpl->_path = appId;
141         pImpl->_provider = appId;
142         pImpl->_opId = operationId;
143         //pImpl->_appName = appId;
144         pImpl->_property |= (_APPCONTROL_PROPERTY_OSP | _APPCONTROL_PROPERTY_PUBLIC);
145
146         if (changeAppId)
147         {
148                 pImpl->_property |= _APPCONTROL_PROPERTY_APPID_CHANGE;
149         }
150
151         return pAc;
152 }
153
154 AppControl*
155 _AppControlImpl::CreateN(const AppControl& ac)
156 {
157         const _AppControlImpl* pImpl = GetInstance(ac);
158         SysTryReturn(NID_APP, pImpl != null, null, E_INVALID_STATE, "AppControlImpl instance must not be null.");
159
160         return CreateN(pImpl->_path, pImpl->_provider, pImpl->_opId, pImpl->_appName, pImpl->_property);
161 }
162
163 const _AppControlImpl*
164 _AppControlImpl::GetInstance(const AppControl& ac)
165 {
166         return ac.__pAppControlImpl;
167 }
168
169 _AppControlImpl*
170 _AppControlImpl::GetInstance(AppControl& ac)
171 {
172         return ac.__pAppControlImpl;
173 }
174
175 result
176 _AppControlImpl::Start(const IList* pDataList, IAppControlEventListener* pListener)
177 {
178         SysLog(NID_APP, "Enter");
179         result r = E_SYSTEM;
180
181         if (_property & _APPCONTROL_PROPERTY_SLP)
182         {
183                 r = StartNative(pDataList, pListener);
184         }
185         else if (_property & _APPCONTROL_PROPERTY_OSP)
186         {
187                 r = StartOsp(pDataList, pListener);
188         }
189         else
190         {
191                 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] Invalid AppControl type(property %d)", _property);
192         }
193         SysLog(NID_APP, "Exit");
194
195         return r;
196 }
197
198 result
199 _AppControlImpl::Start(const String* pUriData, const String* pDataType, const IMap* pExtraData, IAppControlResponseListener* pListener)
200 {
201         SysLog(NID_APP, "Enter");
202         result r = E_SYSTEM;
203
204         if (_property & _APPCONTROL_PROPERTY_SLP)
205         {
206                 r = StartNative(pUriData, pDataType, pExtraData, pListener);
207         }
208         else if (_property & _APPCONTROL_PROPERTY_OSP)
209         {
210                 r = StartOsp(pUriData, pDataType, pExtraData, pListener);
211         }
212         else
213         {
214                 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] Invalid AppControl type(property %d)", _property);
215         }
216         SysLog(NID_APP, "Exit");
217
218         return r;
219 }
220
221 result
222 _AppControlImpl::FindAndStart(const String& operationId, const String* pUriPattern, const String* pDataType, const String* pCategory, const IMap* pExtraData, IAppControlResponseListener* pListener)
223 {
224         // [FIXME] valid argument size checking required
225         SysLog(NID_APP, "Enter");
226
227         std::unique_ptr<bundle, BundleDeleter> pBundle(bundle_create());
228         SysTryReturnResult(NID_APP, pBundle.get(), E_OUT_OF_MEMORY, "Bundle creation failure.");
229
230         _AppMessageImpl::SetOperation(pBundle.get(), operationId);
231
232         if (pUriPattern)
233         {
234                 _AppMessageImpl::SetUri(pBundle.get(), *pUriPattern);
235         }
236
237         if (pDataType)
238         {
239                 String mimeType = *pDataType;
240
241                 if ((*pDataType)[0] == L'.')
242                 {
243                         SysLog(NID_APP, "Extension to MIME conversion for %ls", pDataType->GetPointer());
244
245 #if 0
246                         String ext;
247                         pDataType->SubString(1, ext);
248
249                         result r = _AppControlManager::GetMimeFromExt(ext, mimeType);
250
251                         SysTryReturn(NID_APP, !IsFailed(r), null, r, "[%s] MIME type conversion failure for %ls.", GetErrorMessage(r), ext.GetPointer());
252
253                         pMimeType = &mimeType;
254
255                         SysLog(NID_APP, "Conversion : %ls -> %ls.", pDataType->GetPointer(), pMimeType->GetPointer());
256 #endif
257                 }
258
259                 _AppMessageImpl::SetMime(pBundle.get(), mimeType);
260         }
261
262         if (pCategory)
263         {
264                 _AppMessageImpl::SetCategory(pBundle.get(), *pCategory);
265         }
266
267         return StartImplicit(pBundle.get(), pExtraData, pListener);
268 }
269
270 result
271 _AppControlImpl::StartOsp(const IList* pDataList, IAppControlEventListener* pListener)
272 {
273         SysLog(NID_APP, "Enter");
274         result r = E_SUCCESS;
275
276         _AppArg* pArg = new (std::nothrow) _AppArg;
277         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
278
279         pArg->Construct(*this, pDataList);
280
281         _AppControlManager* pImpl = _AppControlManager::GetInstance();
282         int req = _REQ_ID_INVALID;
283
284         if (pListener)
285         {
286                 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCbLegacy, pListener, _property);
287                 req = reqObj.GetRequestNumber();
288
289                 _processId = pImpl->Launch(_path, pArg, req);
290
291                 if (_processId < 0)
292                 {
293                         reqObj.Invalidate();
294                         r = GetLastResult();
295                         SysLog(NID_APP, "[%s]Launching(%ls) is failed" , GetErrorMessage(r), _path.GetPointer());
296                         return r;
297                 }
298         }
299         else
300         {
301                 _processId = pImpl->Launch(_path, pArg);
302                 delete pArg;
303                 SysTryReturnResult(NID_APP, _processId >= 0, GetLastResult(), "Launching(%ls) is failed", _path.GetPointer());
304         }
305         SysLog(NID_APP, "Exit");
306
307         return r;
308 }
309
310 result
311 _AppControlImpl::StartOsp(const String* pUriData, const String* pMimeType, const IMap* pDataList, IAppControlResponseListener* pListener)
312 {
313         SysLog(NID_APP, "Enter");
314         result r = E_SUCCESS;
315
316         _AppArg* pArg = new (std::nothrow) _AppArg;
317         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
318
319         pArg->Construct(*this, pUriData, pMimeType, pDataList);
320
321         _AppControlManager* pImpl = _AppControlManager::GetInstance();
322         int req = _REQ_ID_INVALID;
323
324         if (pListener)
325         {
326                 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCb, pListener, _property);
327                 req = reqObj.GetRequestNumber();
328
329                 if (_ThreadImpl::GetCurrentThreadImpl()->GetThreadType() == THREAD_TYPE_EVENT_DRIVEN)
330                 {
331                         _AppControlResponseEvent* pAppControlResponseEvent = new (std::nothrow) _AppControlResponseEvent();
332                         if (pAppControlResponseEvent != null)
333                         {
334                                 r = pAppControlResponseEvent->Construct();
335                                 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::Construct() is failed", GetErrorMessage(r));
336
337                                 r = pAppControlResponseEvent->AddListener(*this, true);
338                                 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::AddListener() is failed", GetErrorMessage(r));
339
340                                 IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = pImpl->GetAppControlResponseEventContainer();
341                                 if (pResponseEventContainer != null)
342                                 {
343                                         pResponseEventContainer->Add(req, pAppControlResponseEvent);
344                                         __appControlResponseEventList.Add(req);
345                                         SysLog(NID_APP, "pResponseEvent gets added. reqId(%d)", req);
346                                 }
347                         }
348                 }
349
350                 _processId = pImpl->Launch(_path, pArg, req);           
351                 if (_processId < 0)
352                 {
353                         reqObj.Invalidate();
354                         r = GetLastResult();
355                         SysLog(NID_APP, "[%s]Launching(%ls) is failed" , GetErrorMessage(r), _path.GetPointer());
356                         return r;
357                 }
358         }
359         else
360         {
361                 _processId = pImpl->Launch(_path, pArg);
362                 delete pArg;
363                 SysTryReturnResult(NID_APP, _processId >= 0, GetLastResult(), "Launching(%ls) is failed", _path.GetPointer());
364         }
365         SysLog(NID_APP, "Exit");
366
367         return r;
368 }
369
370 result
371 _AppControlImpl::StartImplicit(bundle* pBundle, const IList* pDataList, IAppControlEventListener* pListener)
372 {
373         SysLog(NID_APP, "Enter");
374         result r = E_SUCCESS;
375
376         _AppArg* pArg = new (std::nothrow) _AppArg;
377         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
378
379         pArg->Construct(pBundle);
380
381         _AppMessageImpl::AddData(pArg->GetBundle(), pDataList);
382
383         _AppControlManager* pImpl = _AppControlManager::GetInstance();
384         int req = _REQ_ID_INVALID;
385
386         if (pListener)
387         {
388                 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCbLegacy, pListener, _APPCONTROL_PROPERTY_NONE);
389                 req = reqObj.GetRequestNumber();
390
391                 r = pImpl->LaunchAppImplicit(pArg, req);
392                 SysTryCatch(NID_APP, r == E_SUCCESS, reqObj.Invalidate(), r, "[%s] Propagating." , GetErrorMessage(r));
393         }
394         else
395         {
396                 r = pImpl->LaunchAppImplicit(pArg, -1);
397                 delete pArg;
398         }
399
400         // [FIXME] launch registration is not working correctly
401         SysLog(NID_APP, "Exit");
402
403 CATCH:
404         return r;
405 }
406
407 result
408 _AppControlImpl::StartImplicit(bundle* pBundle, const IMap* pData, IAppControlResponseListener* pListener)
409 {
410         SysLog(NID_APP, "Enter");
411         result r = E_SUCCESS;
412
413         _AppArg* pArg = new (std::nothrow) _AppArg;
414         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
415
416         pArg->Construct(pBundle);
417
418         _AppArg::AddStrMap(pArg->GetBundle(), pData);
419
420         _AppControlManager* pImpl = _AppControlManager::GetInstance();
421         int req = _REQ_ID_INVALID;
422
423         if (pListener)
424         {
425                 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCb, pListener, _APPCONTROL_PROPERTY_NONE);
426                 req = reqObj.GetRequestNumber();
427
428                 if (_ThreadImpl::GetCurrentThreadImpl()->GetThreadType() == THREAD_TYPE_EVENT_DRIVEN)
429                 {
430                         _AppControlResponseEvent* pAppControlResponseEvent = new (std::nothrow) _AppControlResponseEvent();
431
432                         if (pAppControlResponseEvent != null)
433                         {
434                                 r = pAppControlResponseEvent->Construct();
435                                 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::Construct() is failed", GetErrorMessage(r));
436
437                                 r = pAppControlResponseEvent->AddListener(*pImpl, true);
438                                 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::AddListener() is failed", GetErrorMessage(r));
439
440                                 IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = pImpl->GetAppControlResponseEventContainer();
441                                 if (pResponseEventContainer != null)
442                                 {
443                                         pResponseEventContainer->Add(req, pAppControlResponseEvent);
444                                         SysLog(NID_APP, "pResponseEvent gets added. reqId(%d)", req);
445                                 }
446                         }
447                 }
448                 r = pImpl->LaunchAppImplicit(pArg, req);
449                 SysTryCatch(NID_APP, r == E_SUCCESS, reqObj.Invalidate(), r, "[%s] Propagating." , GetErrorMessage(r));
450         }
451         else
452         {
453                 r = pImpl->LaunchAppImplicit(pArg, -1);
454                 delete pArg;
455         }
456         SysLog(NID_APP, "Exit");
457
458         // [FIXME] launch registration is not working correctly
459
460 CATCH:
461
462         return r;
463 }
464
465 result
466 _AppControlImpl::AppControlCbLegacy(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop, int reqId)
467 {
468         SysLog(NID_APP, "Result value %d", res);
469
470         SysTryReturnResult(NID_APP, data && pResArg && pArg, E_SYSTEM, "Invalid result (callback, result, arg) = (0x%x, 0x%x, 0x%x).",
471                                           data, pResArg,
472                                           pArg);
473
474         bundle* b = pResArg->GetBundle();
475         SysTryReturnResult(NID_APP, b != NULL, E_SYSTEM, "Invalid result bundle.");
476
477         IAppControlEventListener* pListener = static_cast<IAppControlEventListener*>(data);
478         SysTryReturnResult(NID_APP, pListener == null || typeid(pListener) == typeid(IAppControlEventListener*), E_SYSTEM, "Invalid result callback");
479
480         bundle* inb = pArg->GetBundle();
481         SysTryReturnResult(NID_APP, inb != NULL, E_SYSTEM, "Empty caller bundle.");
482
483         String oId;
484
485         AppId provider = pResArg->GetCalleeAppId();
486
487         const char* p = appsvc_get_operation(inb);
488         if (p)
489         {
490                 oId = p;
491         }
492
493         SysLog(NID_APP, "Invoking callback with (%ls, %ls)", provider.GetPointer(), oId.GetPointer());
494
495         if (prop & _APPCONTROL_PROPERTY_ALIAS)
496         {
497                 const _AppControlRegistry::_AppControlAliasEntry* pEntry = null;
498                 pEntry = _AppControlRegistry::GetInstance()->GetReverseAppControlAliasEntry(provider, oId);
499                 if (pEntry)
500                 {
501                         provider = pEntry->provider;
502                         oId = pEntry->operation;
503
504                         SysLog(NID_APP, "Legacy AppControl(%ls, %ls).", provider.GetPointer(), oId.GetPointer());
505                 }
506         }
507
508         if (prop & _APPCONTROL_PROPERTY_APPID_CHANGE)
509         {
510                 String tmp = _AppControlRegistry::GetInstance()->GetReverseAliasAppId(provider);
511                 if (!tmp.IsEmpty())
512                 {
513                         SysLog(NID_APP, "App change (%ls -> %ls).", provider.GetPointer(), tmp.GetPointer());
514
515                         provider = tmp;
516                 }
517         }
518
519         const bool isSubMode = _AppArg::IsSubMode(b);
520
521         std::unique_ptr<HashMap> pMap(pResArg->GetArgMapN());
522
523         ArrayList list(SingleObjectDeleter);
524         _AppArg::FillLegacyAppControlResult(list, res, pMap.get(), provider);
525
526         _AppControlManager::InvokeLegacyAppControlCompleteListener(*pListener, provider, oId, &list, isSubMode);
527
528         return E_SUCCESS;
529 }
530
531 result
532 _AppControlImpl::AppControlCb(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop, int reqId)
533 {
534         SysLog(NID_APP, "Result value : %d, property : 0x%x", res, prop);
535
536         SysTryReturnResult(NID_APP, data && pResArg && pArg, E_SYSTEM, "Invalid result (callback, result, arg) = (0x%x, 0x%x, 0x%x).",
537                                           data, pResArg,
538                                           pArg);
539
540         bundle* b = pResArg->GetBundle();
541         SysTryReturnResult(NID_APP, b != NULL, E_SYSTEM, "Invalid result bundle.");
542
543         IAppControlResponseListener* pListener = static_cast<IAppControlResponseListener*>(data);
544         SysTryReturnResult(NID_APP, pListener == null || typeid(pListener) == typeid(IAppControlResponseListener*), E_SYSTEM, "Invalid result callback");
545
546         bundle* inb = pArg->GetBundle();
547         SysTryReturnResult(NID_APP, inb != NULL, E_SYSTEM, "Empty caller bundle.");
548
549         String oId;
550
551         AppId provider = pResArg->GetCalleeAppId();
552
553         const char* p = appsvc_get_operation(inb);
554         if (p)
555         {
556                 oId = p;
557         }
558
559         SysLog(NID_APP, "Invoking callback with (%ls, %ls)", provider.GetPointer(), oId.GetPointer());
560
561         if (prop & _APPCONTROL_PROPERTY_ALIAS)
562         {
563                 const _AppControlRegistry::_AppControlAliasEntry* pEntry = null;
564                 pEntry = _AppControlRegistry::GetInstance()->GetReverseRuntimeAliasEntry(provider, oId);
565                 if (pEntry)
566                 {
567                         provider = pEntry->provider;
568                         oId = pEntry->operation;
569
570                         SysLog(NID_APP, "Original AppControl(%ls, %ls).", provider.GetPointer(), oId.GetPointer());
571                 }
572         }
573
574         if (prop & _APPCONTROL_PROPERTY_APPID_CHANGE)
575         {
576                 String tmp = _AppControlRegistry::GetInstance()->GetReverseAliasAppId(provider);
577                 if (!tmp.IsEmpty())
578                 {
579                         SysLog(NID_APP, "App change (%ls -> %ls).", provider.GetPointer(), tmp.GetPointer());
580
581                         provider = tmp;
582                 }
583         }
584
585         const bool isSubMode = _AppArg::IsSubMode(b);
586
587         std::unique_ptr<HashMap> pMap(pResArg->GetArgMapN());
588
589         AppCtrlResult ret = _AppControlManager::ConvertAppControlResultCode(res);
590
591         SysLog(NID_APP, "Result code : 0x%x.", ret);
592
593         // proper callback invokation
594         _AppControlResponseEvent* pResponseEvent = null;
595         _AppControlManager::GetInstance()->GetAppControlResponseEventContainer()->GetValue(reqId, pResponseEvent);
596
597         if (pResponseEvent != null)
598         {
599                 _AppControlResponseEventArg* pResponseEventArg = new (std::nothrow) _AppControlResponseEventArg(pListener, _APPCONTROL_RESPONSETYPE_COMPLETE, provider, oId, E_SUCCESS, ret, pMap.release(), reqId, isSubMode);
600                 pResponseEvent->Fire(*pResponseEventArg);
601                 SysLog(NID_APP, "OnAppControlCompleteResponseReceived, pResponseEvent is Fired");
602         }
603         else
604         {
605                 _AppControlManager::InvokeAppControlCompleteListener(*pListener, provider, oId, ret, pMap.get(), isSubMode);
606         }
607
608         return E_SUCCESS;
609 }
610
611 result
612 _AppControlImpl::StartNative(const IList* pDataList, IAppControlEventListener* pListener)
613 {
614         SysLog(NID_APP, "Enter");
615         _InProcessInfo* pInfo = _AppControlManager::GetInstance()->__inAppManager.FindItem(_reqId);
616         SysTryReturnResult(NID_APP, pInfo == null, E_IN_PROGRESS, "Request ID %d is already in progress.", _reqId);
617
618         int req = _REQ_ID_INVALID;
619         _LibraryImpl* pLib = null;
620
621         pLib = new (std::nothrow) _LibraryImpl;
622         SysTryReturnResult(NID_APP, pLib != null, E_OUT_OF_MEMORY, "Failed to allocate libraryimpl.");
623
624         unsigned long option = _LIBRARY_LOAD_OPTION_LAZY;
625         option |= _LIBRARY_LOAD_OPTION_NODELETE;
626
627         result r = pLib->Construct(_path, option);
628         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
629
630         if (pListener)
631         {
632                 _InProcessInfo* pItem = new (std::nothrow) _InProcessInfo(_provider, _opId, _property, true, *pLib, pListener);
633                 if (pItem)
634                 {
635                         req = _AppControlManager::GetInstance()->__inAppManager.InsertItem(pItem);
636                 }
637         }
638         r = InvokeStartAppControl(*pLib, req, _provider, _opId, pDataList);
639
640         if (pListener == null)
641         {
642                 delete pLib;
643         }
644
645         // after acquring request number, pLib should be managed from the list, not CATCH
646         if (IsFailed(r))
647         {
648                 _AppControlManager::GetInstance()->__inAppManager.RemoveItem(req);
649                 SysLog(NID_APP, "[%s] A system error has occurred.", GetErrorMessage(r));
650
651                 return r;
652         }
653
654         _reqId = req;
655
656         SysLog(NID_APP, "Exit");
657         return E_SUCCESS;
658
659 CATCH:
660         delete pLib;
661
662         switch (r)
663         {
664         case E_LIBRARY_NOT_FOUND:
665                 r = E_OBJ_NOT_FOUND;
666                 break;
667         default:
668                 r = E_SYSTEM;
669                 break;
670         }
671
672         return r;
673 }
674
675 result
676 _AppControlImpl::StartNative(const String* pUriData, const String* pMimeType, const IMap* pDataList, IAppControlResponseListener* pListener)
677 {
678         SysLog(NID_APP, "Enter");
679         _InProcessInfo* pInfo = _AppControlManager::GetInstance()->__inAppManager.FindItem(_reqId);
680         SysTryReturnResult(NID_APP, pInfo == null, E_IN_PROGRESS, "Request ID %d is already in progress.", _reqId);
681
682         int req = _REQ_ID_INVALID;
683         _LibraryImpl* pLib = null;
684
685         pLib = new (std::nothrow) _LibraryImpl;
686         SysTryReturnResult(NID_APP, pLib != null, E_OUT_OF_MEMORY, "Failed to allocate libraryimpl.");
687
688         unsigned long option = _LIBRARY_LOAD_OPTION_LAZY;
689         option |= _LIBRARY_LOAD_OPTION_NODELETE;
690
691         result r = pLib->Construct(_path, option);
692
693         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
694
695         if (pListener)
696         {
697                 _InProcessInfo* pItem = new (std::nothrow) _InProcessInfo(_provider, _opId, _property, false, *pLib, pListener);
698                 if (pItem)
699                 {
700                         req = _AppControlManager::GetInstance()->__inAppManager.InsertItem(pItem);
701                 }
702
703                 if (_ThreadImpl::GetCurrentThreadImpl()->GetThreadType() == THREAD_TYPE_EVENT_DRIVEN)
704                 {
705                         _AppControlResponseEvent* pAppControlResponseEvent = new (std::nothrow) _AppControlResponseEvent();
706
707                         if (pAppControlResponseEvent != null)
708                         {
709                                 r = pAppControlResponseEvent->Construct();
710                                 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::Construct() is failed", GetErrorMessage(r));
711
712                                 r = pAppControlResponseEvent->AddListener(*this, true);
713                                 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::AddListener() is failed", GetErrorMessage(r));
714
715                                 IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = _AppControlManager::GetInstance()->GetAppControlResponseEventContainer();
716                                 if (pResponseEventContainer != null)
717                                 {
718                                         int responseEventRequestId = RESPONSE_EVENT_REQID_MAGIC + req;
719                                         pResponseEventContainer->Add(responseEventRequestId, pAppControlResponseEvent);
720                                         __appControlResponseEventList.Add(responseEventRequestId);
721                                         SysLog(NID_APP, "pResponseEvent gets added. reqId(%d)", responseEventRequestId);
722                                 }
723                         }
724                 }
725         }
726         r = InvokeStartAppControl(*pLib, req, _provider, _opId, pUriData, pMimeType, pDataList);
727
728         if (pListener == null)
729         {
730                 delete pLib;
731         }
732
733         // after acquring request number, pLib should be managed from the list, not CATCH
734         if (IsFailed(r))
735         {
736                 _AppControlManager::GetInstance()->__inAppManager.RemoveItem(req);
737                 SysLog(NID_APP, "[%s] A system error has occurred.", GetErrorMessage(r));
738
739                 return r;
740         }
741
742         _reqId = req;
743         SysLog(NID_APP, "Exit");
744
745         return E_SUCCESS;
746
747 CATCH:
748         delete pLib;
749
750         switch (r)
751         {
752         case E_LIBRARY_NOT_FOUND:
753                 r = E_OBJ_NOT_FOUND;
754                 break;
755         default:
756                 r = E_SYSTEM;
757                 break;
758         }
759
760         return r;
761 }
762
763 result
764 _AppControlImpl::InvokeStartAppControl(_LibraryImpl& lib, int req, const String& appId, const String& oId, const IList* pList)
765 {
766         SysLog(NID_APP, "Legacy stuff for converting argument");
767
768         HashMap map(SingleObjectDeleter);
769         HashMap* pMap = null;
770         if (pList)
771         {
772                 map.Construct();
773
774                 _AppArg::FillMapFromList(&map, pList);
775
776                 pMap = &map;
777         }
778
779         return InvokeStartAppControl(lib, req, appId, oId, null, null, pMap);
780 }
781
782
783 result
784 _AppControlImpl::InvokeStartAppControl(_LibraryImpl& lib, int req, const String& appId, const String& oId, const String* pUri, const String* pMime, const IMap* pMap)
785 {
786         result (*pFunc)(int req, const String&, const String&, const String*, const String*, const IMap*) = null;
787
788         pFunc =
789                 reinterpret_cast<result (*)(int, const String&, const String&, const String*, const String*, const IMap*)>(lib.GetProcAddress(L"StartAppControl"));
790         SysTryReturnResult(NID_APP, pFunc != null, E_OBJ_NOT_FOUND, "Entry \"StartAppControl\" not found for %ls", appId.GetPointer());
791
792         const String* pActualUri = (pUri && !(pUri->IsEmpty())) ? pUri : null;
793         const String* pActualMime = (pMime && !(pMime->IsEmpty())) ? pMime : null;
794         return (*pFunc)(req, appId, oId, pActualUri, pActualMime, pMap);
795 }
796
797 static bool
798 IsValidAppControl(const String& appcontrolID)
799 {
800         return ((appcontrolID == L"osp.appcontrol.provider.audio")
801                 || (appcontrolID == L"osp.appcontrol.provider.bluetooth")
802                 || (appcontrolID == L"osp.appcontrol.provider.calendar")
803                 || (appcontrolID == L"osp.appcontrol.provider.camera")
804                 || (appcontrolID == L"osp.appcontrol.provider.contact")
805                 || (appcontrolID == L"osp.appcontrol.provider.certificatemanager")
806                 || (appcontrolID == L"osp.appcontrol.provider.email")
807                 || (appcontrolID == L"osp.appcontrol.provider.image")
808                 || (appcontrolID == L"osp.appcontrol.provider.media")
809                 || (appcontrolID == L"osp.appcontrol.provider.message")
810                 || (appcontrolID == L"osp.appcontrol.provider.video")
811                 || (appcontrolID == L"osp.appcontrol.provider.imageeditor")
812                 || (appcontrolID == L"osp.appcontrol.provider.allshare")
813                 || (appcontrolID == L"tizen.filemanager")
814                 || (appcontrolID == L"tizen.camera")
815                 || (appcontrolID == L"tizen.gallery")
816                 || (appcontrolID == L"tizen.imageviewer")
817                 || (appcontrolID == L"tizen.videoplayer")
818                 || (appcontrolID == L"tizen.memo")
819                 || (appcontrolID == L"tizen.contacts")
820                 || (appcontrolID == L"tizen.calendar")
821                 || (appcontrolID == L"tizen.todo")
822                 || (appcontrolID == L"tizen.email")
823                 || (appcontrolID == L"tizen.settings")
824                 || (appcontrolID == L"tizen.messages")
825                 || (appcontrolID == L"tizen.musicplayer")
826                 || (appcontrolID == L"tizen.bluetooth")
827                 || (appcontrolID == L"samsung.snote")
828                 || (appcontrolID == L"0pnxz8hbsr.MyFiles")
829                 || (appcontrolID == L"hdufar9ycj.Camera")
830                 || (appcontrolID == L"ijudt7w61q.Gallery")
831                 || (appcontrolID == L"jysyv9o1dc.ImageViewer")
832                 || (appcontrolID == L"npwf0scb88.VideoPlayer")
833                 || (appcontrolID == L"zunqjlsnce.Memo")
834                 || (appcontrolID == L"f9uev8hsyo.Contacts")
835                 || (appcontrolID == L"ph1vq2phrp.Calendar")
836                 || (appcontrolID == L"vxqbrefica.Email")
837                 || (appcontrolID == L"kto5jikgul.Settings")
838                 || (appcontrolID == L"8r4r5ddzzn.Messages")
839                 || (appcontrolID == L"dhrul6qzj3.MusicPlayer")
840                 || (appcontrolID == L"smemo-efl"));
841 }
842
843 result
844 _AppControlImpl::Stop(void)
845 {
846         const String appcontrolID(GetAppControlProviderId());
847         SysTryReturnResult(NID_APP, IsValidAppControl(appcontrolID), E_INVALID_OPERATION, "Invalid appcontrolID(%ls)", appcontrolID.GetPointer());
848
849         if (_property & _APPCONTROL_PROPERTY_SLP)
850         {       
851                 SysTryReturnResult(NID_APP, _reqId != _REQ_ID_INVALID, E_INVALID_OPERATION, "Invalid request ID .");
852
853                 _InProcessInfo* pInfo = _AppControlManager::GetInstance()->__inAppManager.FindItem(_reqId);
854                 SysTryReturnResult(NID_APP, pInfo != null, E_INVALID_OPERATION, "Request ID %d is not found.", _reqId);
855                 
856                 result (*pStop)(int req) = null;
857                 pStop = reinterpret_cast<result (*)(int)>(pInfo->pLib->GetProcAddress(L"TerminateAppControl"));
858                 SysTryReturnResult(NID_APP, pStop != null, E_SYSTEM, "No TerminateAppControl() function.");
859                 
860                 (*pStop)(_reqId);
861                 
862                 _AppControlManager::GetInstance()->__inAppManager.RemoveItem(_reqId);
863                 
864                 _reqId = _REQ_ID_INVALID;
865         }
866         else if (_property & _APPCONTROL_PROPERTY_OSP)
867         {
868                 _Aul::TerminateApplicationByPid(_processId);
869         }
870
871         return E_SUCCESS;
872 }
873
874 String
875 _AppControlImpl::GetAppName(void)
876 {
877         if (_appName.IsEmpty())
878         {
879                 AppId appId = GetAppId();
880                 AppId aliasAppId = _AppControlRegistry::GetInstance()->GetAliasAppId(appId);
881                 if (!aliasAppId.IsEmpty())
882                 {
883                         appId = aliasAppId;
884                 }
885
886                 std::unique_ptr<PackageAppInfo> pInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(appId));
887                 if (pInfo.get())
888                 {
889                         SysLog(NID_APP, "PackageInfo of appId(%ls) exists", appId.GetPointer());
890                         const String& name = pInfo->GetAppName();
891                         if (name == L"_AppControl")
892                         {
893                                 // workaround for special case: requery with actual appId
894                                 const PackageId& packageId = _PackageManagerImpl::GetPackageIdByAppId(appId);
895                                 const String& defaultName = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(packageId);
896
897                                 const String& convertedAppId = packageId + L'.' + defaultName;
898
899                                 std::unique_ptr<PackageAppInfo> pNewInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(convertedAppId));
900
901                                 if (pNewInfo.get())
902                                 {
903                                         _appName = pNewInfo->GetAppDisplayName();
904                                 }
905                                 else
906                                 {
907                                         SysLog(NID_APP, "No default applicaiton information, possible database error.");
908                                 }
909                         }
910                         else
911                         {
912                                 _appName = pInfo->GetAppDisplayName();
913                         }
914                 }
915                 else
916                 {
917                         SysLog(NID_APP, "PackageInfo of appId(%ls) does not exist", appId.GetPointer());
918                 }
919         }
920
921         return _appName;
922 }
923
924 String
925 _AppControlImpl::GetAppId(void) const
926 {
927         return (_property & _APPCONTROL_PROPERTY_OSP) ? _path : _provider;
928 }
929
930 const String&
931 _AppControlImpl::GetAppControlProviderId(void) const
932 {
933         return _provider;
934 }
935
936 const String&
937 _AppControlImpl::GetOperationId(void) const
938 {
939         return _opId;
940 }
941
942 IList*
943 _AppControlImpl::GetCategoryListN(void) const
944 {
945         AppId appId = GetAppId();
946         SysTryReturn(NID_APP, !appId.IsEmpty(), null, E_SYSTEM, "[E_SYSTEM] Empty appId.");
947
948         AppId aliasAppId = _AppControlRegistry::GetInstance()->GetAliasAppId(appId);
949         if (!aliasAppId.IsEmpty())
950         {
951                 appId = aliasAppId;
952         }
953
954         SysLog(NID_APP, "Acquiring category for app %ls.", appId.GetPointer());
955
956         std::unique_ptr<PackageAppInfo> pAppInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(appId));
957         SysTryReturn(NID_APP, pAppInfo.get() != null, null, E_SYSTEM, "[E_SYSTEM] Getting PackageAppInfo failed.");
958
959         return pAppInfo->GetAppCategoryListN();
960 }
961
962 void
963 _AppControlImpl::StopAppControlResponseListener(IAppControlResponseListener* pListener)
964 {
965         _AppControlManager::GetInstance()->__listenerList.Add(pListener);
966 }
967
968 void
969 _AppControlImpl::OnAppControlResponseEventReceivedN(const Tizen::Base::Runtime::IEventArg* arg)
970 {
971         const _AppControlResponseEventArg* pEventArg = dynamic_cast<const _AppControlResponseEventArg*>(arg);
972
973         if (pEventArg != null)
974         {
975                 IAppControlResponseListener* pResponseListener = pEventArg->GetListener();
976
977                 if(pResponseListener != null)
978                 {
979                         if(pEventArg->GetType() == _APPCONTROL_RESPONSETYPE_COMPLETE)
980                         {
981                                 _AppControlManager::InvokeAppControlCompleteListener(*pResponseListener, pEventArg->GetAppId(), pEventArg->GetOperationId(), pEventArg->GetAppControlResult(), pEventArg->GetExtraData(), pEventArg->IsSubMode());
982
983                                 _AppControlResponseEvent* pResponseEvent = null;
984                                 _AppControlManager::GetInstance()->GetAppControlResponseEventContainer()->GetValue(pEventArg->GetRequestId(), pResponseEvent);
985                                 _AppControlManager::GetInstance()->GetAppControlResponseEventContainer()->Remove(pEventArg->GetRequestId());
986                                 delete pResponseEvent;
987                                 SysLog(NID_APP, "pResponseEvent gets deleted, reqId(%d)", pEventArg->GetRequestId());
988                         }
989                         else
990                         {
991                                 SysLog(NID_APP, "Unexpected AppControlResponseType(%d)", pEventArg->GetType());
992                         }
993                 }
994                 else
995                 {
996                         SysLog(NID_APP, "Invalid ResponseListener");
997                 }
998         }
999         else
1000         {
1001                 SysLog(NID_APP, "Invalid AppControl arguments : arg(0x%x)", &arg);
1002         }
1003
1004 }
1005 }}    //Tizen::App