2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FApp_AppControlImpl.cpp
20 * @brief This is the implementation for the Application Control class.
25 #include <unique_ptr.h>
27 #include <appsvc/appsvc.h>
29 #include <FAppAppControl.h>
30 #include <FAppAppManager.h>
31 #include <FAppPkgPackageAppInfo.h>
32 #include <FAppIAppControlEventListener.h>
33 #include <FAppIAppControlResponseListener.h>
34 #include <FBaseColHashMap.h>
35 #include <FBaseSysLog.h>
37 #include <FBaseRt_LibraryImpl.h>
38 #include <FIo_DirectoryImpl.h>
40 #include "FApp_AppControlImpl.h"
41 #include "FApp_AppControlManager.h"
42 #include "FApp_AppArg.h"
43 #include "FApp_AppImpl.h"
44 #include "FApp_AppControlRegistry.h"
45 #include "FApp_AppMessageImpl.h"
46 #include "FApp_AppInfo.h"
47 #include "FAppPkg_PackageManagerImpl.h"
49 #include "FApp_AppControlEventArg.h"
50 #include "FApp_AppControlResponseEvent.h"
51 #include "FBaseRt_ThreadImpl.h"
53 using namespace Tizen::Base;
54 using namespace Tizen::Base::Collection;
55 using namespace Tizen::Base::Runtime;
56 using namespace Tizen::App;
57 using namespace Tizen::App::Package;
58 using namespace Tizen::Io;
63 static const int _REQ_ID_INVALID = -1;
67 namespace Tizen { namespace App
70 const wchar_t TIZEN_OPERATION_MAIN[] = L"http://tizen.org/appcontrol/operation/main";
71 const char TIZEN_APPCONTROL_DATA_LEGACY[] = "http://tizen.org/appcontrol/data/legacyresult";
73 _AppControlImpl::_AppControlImpl(const AppControl& value)
75 , _reqId(_REQ_ID_INVALID)
76 , _property(_APPCONTROL_PROPERTY_NONE)
77 , _processId(_REQ_ID_INVALID)
79 __appControlResponseEventList.Construct();
82 _AppControlImpl::~_AppControlImpl(void)
84 IEnumeratorT<int>* pEnum = __appControlResponseEventList.GetEnumeratorN();
85 IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = null;
88 pResponseEventContainer = _AppControlManager::GetInstance()->GetAppControlResponseEventContainer();
91 while(pEnum->MoveNext() == E_SUCCESS)
94 pEnum->GetCurrent(reqId);
95 if (pResponseEventContainer != null)
97 _AppControlResponseEvent* pResponseEvent = null;
98 pResponseEventContainer->GetValue(reqId, pResponseEvent);
99 delete pResponseEvent;
101 pResponseEventContainer->Remove(reqId);
102 SysLog(NID_APP, "pResponseEvent gets deleted. reqId(%d)", reqId);
109 _AppControlImpl::CreateN(const String& path, const String& aId, const String& oId, const String& name, int prop)
111 SysTryReturn(NID_APP, !path.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] Path is empty.");
112 SysTryReturn(NID_APP, !aId.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] Provider Id is empty.");
113 SysTryReturn(NID_APP, !oId.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] Operation Id is empty.");
115 AppControl* pAc = new (std::nothrow) AppControl;
116 SysTryReturn(NID_APP, pAc != null, null, E_OUT_OF_MEMORY, "AppControl allocation failure.");
118 _AppControlImpl* pImpl = pAc->__pAppControlImpl;
119 SysTryReturn(NID_APP, pImpl != null, null, E_OUT_OF_MEMORY, "AppControlImpl instance must not be null.");
122 pImpl->_provider = aId;
124 // [FIXME] Proper App name setting
125 pImpl->_appName = name;
126 pImpl->_property = prop;
132 _AppControlImpl::CreateN(const AppId& appId, const String& operationId, bool changeAppId)
134 SysTryReturn(NID_APP, !appId.IsEmpty(), null, E_INVALID_ARG, "[E_INVALID_ARG] appId is empty.");
136 AppControl* pAc = new (std::nothrow) AppControl;
137 SysTryReturn(NID_APP, pAc != null, null, E_OUT_OF_MEMORY, "AppControl allocation failure.");
139 _AppControlImpl* pImpl = pAc->__pAppControlImpl;
140 SysTryReturn(NID_APP, pImpl != null, null, E_OUT_OF_MEMORY, "AppControlImpl instance must not be null.");
142 pImpl->_path = appId;
143 pImpl->_provider = appId;
144 pImpl->_opId = operationId;
145 //pImpl->_appName = appId;
146 pImpl->_property |= (_APPCONTROL_PROPERTY_OSP | _APPCONTROL_PROPERTY_PUBLIC);
150 pImpl->_property |= _APPCONTROL_PROPERTY_APPID_CHANGE;
157 _AppControlImpl::CreateN(const AppControl& ac)
159 const _AppControlImpl* pImpl = GetInstance(ac);
160 SysTryReturn(NID_APP, pImpl != null, null, E_INVALID_STATE, "AppControlImpl instance must not be null.");
162 return CreateN(pImpl->_path, pImpl->_provider, pImpl->_opId, pImpl->_appName, pImpl->_property);
165 const _AppControlImpl*
166 _AppControlImpl::GetInstance(const AppControl& ac)
168 return ac.__pAppControlImpl;
172 _AppControlImpl::GetInstance(AppControl& ac)
174 return ac.__pAppControlImpl;
178 _AppControlImpl::Start(const IList* pDataList, IAppControlEventListener* pListener)
180 SysLog(NID_APP, "Enter");
183 if (_property & _APPCONTROL_PROPERTY_SLP)
185 r = StartNative(pDataList, pListener);
187 else if (_property & _APPCONTROL_PROPERTY_OSP)
189 r = StartOsp(pDataList, pListener);
193 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] Invalid AppControl type(property %d)", _property);
195 SysLog(NID_APP, "Exit");
201 _AppControlImpl::Start(const String* pUriData, const String* pDataType, const IMap* pExtraData, IAppControlResponseListener* pListener)
203 SysLog(NID_APP, "Enter");
206 if (_property & _APPCONTROL_PROPERTY_SLP)
208 r = StartNative(pUriData, pDataType, pExtraData, pListener);
210 else if (_property & _APPCONTROL_PROPERTY_OSP)
212 r = StartOsp(pUriData, pDataType, pExtraData, pListener);
216 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] Invalid AppControl type(property %d)", _property);
218 SysLog(NID_APP, "Exit");
224 _AppControlImpl::FindAndStart(const String& operationId, const String* pUriPattern, const String* pDataType, const String* pCategory, const IMap* pExtraData, IAppControlResponseListener* pListener)
226 // [FIXME] valid argument size checking required
227 SysLog(NID_APP, "Enter");
229 std::unique_ptr<bundle, BundleDeleter> pBundle(bundle_create());
230 SysTryReturnResult(NID_APP, pBundle.get(), E_OUT_OF_MEMORY, "Bundle creation failure.");
232 _AppMessageImpl::SetOperation(pBundle.get(), operationId);
236 _AppMessageImpl::SetUri(pBundle.get(), *pUriPattern);
241 String mimeType = *pDataType;
243 if ((*pDataType)[0] == L'.')
245 SysLog(NID_APP, "Extension to MIME conversion for %ls", pDataType->GetPointer());
249 pDataType->SubString(1, ext);
251 result r = _AppControlManager::GetMimeFromExt(ext, mimeType);
253 SysTryReturn(NID_APP, !IsFailed(r), null, r, "[%s] MIME type conversion failure for %ls.", GetErrorMessage(r), ext.GetPointer());
255 pMimeType = &mimeType;
257 SysLog(NID_APP, "Conversion : %ls -> %ls.", pDataType->GetPointer(), pMimeType->GetPointer());
261 _AppMessageImpl::SetMime(pBundle.get(), mimeType);
266 _AppMessageImpl::SetCategory(pBundle.get(), *pCategory);
269 return StartImplicit(pBundle.get(), pExtraData, pListener);
273 _AppControlImpl::StartOsp(const IList* pDataList, IAppControlEventListener* pListener)
275 SysLog(NID_APP, "Enter");
276 result r = E_SUCCESS;
278 _AppArg* pArg = new (std::nothrow) _AppArg;
279 SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
281 pArg->Construct(*this, pDataList);
283 _AppControlManager* pImpl = _AppControlManager::GetInstance();
284 int req = _REQ_ID_INVALID;
288 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCbLegacy, pListener, _property);
289 req = reqObj.GetRequestNumber();
291 _processId = pImpl->Launch(_path, pArg, req);
297 SysLog(NID_APP, "[%s]Launching(%ls) is failed" , GetErrorMessage(r), _path.GetPointer());
303 _processId = pImpl->Launch(_path, pArg);
305 SysTryReturnResult(NID_APP, _processId >= 0, GetLastResult(), "Launching(%ls) is failed", _path.GetPointer());
307 SysLog(NID_APP, "Exit");
313 _AppControlImpl::StartOsp(const String* pUriData, const String* pMimeType, const IMap* pDataList, IAppControlResponseListener* pListener)
315 SysLog(NID_APP, "Enter");
316 result r = E_SUCCESS;
318 _AppArg* pArg = new (std::nothrow) _AppArg;
319 SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
321 pArg->Construct(*this, pUriData, pMimeType, pDataList);
323 _AppControlManager* pImpl = _AppControlManager::GetInstance();
324 int req = _REQ_ID_INVALID;
328 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCb, pListener, _property);
329 req = reqObj.GetRequestNumber();
331 if (_ThreadImpl::GetCurrentThreadImpl()->GetThreadType() == THREAD_TYPE_EVENT_DRIVEN)
333 _AppControlResponseEvent* pAppControlResponseEvent = new (std::nothrow) _AppControlResponseEvent();
334 if (pAppControlResponseEvent != null)
336 r = pAppControlResponseEvent->Construct();
337 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::Construct() is failed", GetErrorMessage(r));
339 r = pAppControlResponseEvent->AddListener(*this, true);
340 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::AddListener() is failed", GetErrorMessage(r));
342 IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = pImpl->GetAppControlResponseEventContainer();
343 if (pResponseEventContainer != null)
345 pResponseEventContainer->Add(req, pAppControlResponseEvent);
346 __appControlResponseEventList.Add(req);
347 SysLog(NID_APP, "pResponseEvent gets added. reqId(%d)", req);
352 _processId = pImpl->Launch(_path, pArg, req);
357 SysLog(NID_APP, "[%s]Launching(%ls) is failed" , GetErrorMessage(r), _path.GetPointer());
363 _processId = pImpl->Launch(_path, pArg);
365 SysTryReturnResult(NID_APP, _processId >= 0, GetLastResult(), "Launching(%ls) is failed", _path.GetPointer());
367 SysLog(NID_APP, "Exit");
373 _AppControlImpl::StartImplicit(bundle* pBundle, const IList* pDataList, IAppControlEventListener* pListener)
375 SysLog(NID_APP, "Enter");
376 result r = E_SUCCESS;
378 _AppArg* pArg = new (std::nothrow) _AppArg;
379 SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
381 pArg->Construct(pBundle);
383 _AppMessageImpl::AddData(pArg->GetBundle(), pDataList);
385 _AppControlManager* pImpl = _AppControlManager::GetInstance();
386 int req = _REQ_ID_INVALID;
390 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCbLegacy, pListener, _APPCONTROL_PROPERTY_NONE);
391 req = reqObj.GetRequestNumber();
393 r = pImpl->LaunchAppImplicit(pArg, req);
394 SysTryCatch(NID_APP, r == E_SUCCESS, reqObj.Invalidate(), r, "[%s] Propagating." , GetErrorMessage(r));
398 r = pImpl->LaunchAppImplicit(pArg, -1);
402 // [FIXME] launch registration is not working correctly
403 SysLog(NID_APP, "Exit");
410 _AppControlImpl::StartImplicit(bundle* pBundle, const IMap* pData, IAppControlResponseListener* pListener)
412 SysLog(NID_APP, "Enter");
413 result r = E_SUCCESS;
415 _AppArg* pArg = new (std::nothrow) _AppArg;
416 SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Argument allocation failure.");
418 pArg->Construct(pBundle);
420 _AppArg::AddStrMap(pArg->GetBundle(), pData);
422 _AppControlManager* pImpl = _AppControlManager::GetInstance();
423 int req = _REQ_ID_INVALID;
427 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pImpl, pArg, AppControlCb, pListener, _APPCONTROL_PROPERTY_NONE);
428 req = reqObj.GetRequestNumber();
430 if (_ThreadImpl::GetCurrentThreadImpl()->GetThreadType() == THREAD_TYPE_EVENT_DRIVEN)
432 _AppControlResponseEvent* pAppControlResponseEvent = new (std::nothrow) _AppControlResponseEvent();
434 if (pAppControlResponseEvent != null)
436 r = pAppControlResponseEvent->Construct();
437 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::Construct() is failed", GetErrorMessage(r));
439 r = pAppControlResponseEvent->AddListener(*pImpl, true);
440 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::AddListener() is failed", GetErrorMessage(r));
442 IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = pImpl->GetAppControlResponseEventContainer();
443 if (pResponseEventContainer != null)
445 pResponseEventContainer->Add(req, pAppControlResponseEvent);
446 SysLog(NID_APP, "pResponseEvent gets added. reqId(%d)", req);
450 r = pImpl->LaunchAppImplicit(pArg, req);
451 SysTryCatch(NID_APP, r == E_SUCCESS, reqObj.Invalidate(), r, "[%s] Propagating." , GetErrorMessage(r));
455 r = pImpl->LaunchAppImplicit(pArg, -1);
458 SysLog(NID_APP, "Exit");
460 // [FIXME] launch registration is not working correctly
468 _AppControlImpl::AppControlCbLegacy(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop, int reqId)
470 SysLog(NID_APP, "Result value %d", res);
472 SysTryReturnResult(NID_APP, data && pResArg && pArg, E_SYSTEM, "Invalid result (callback, result, arg) = (0x%x, 0x%x, 0x%x).",
476 bundle* b = pResArg->GetBundle();
477 SysTryReturnResult(NID_APP, b != NULL, E_SYSTEM, "Invalid result bundle.");
479 IAppControlEventListener* pListener = static_cast<IAppControlEventListener*>(data);
480 SysTryReturnResult(NID_APP, typeid(pListener) == typeid(IAppControlEventListener*), E_SYSTEM, "Invalid result callback");
482 bundle* inb = pArg->GetBundle();
483 SysTryReturnResult(NID_APP, inb != NULL, E_SYSTEM, "Empty caller bundle.");
487 AppId provider = pResArg->GetCalleeAppId();
489 const char* p = appsvc_get_operation(inb);
495 SysLog(NID_APP, "Invoking callback with (%ls, %ls)", provider.GetPointer(), oId.GetPointer());
497 if (prop & _APPCONTROL_PROPERTY_ALIAS)
499 const _AppControlRegistry::_AppControlAliasEntry* pEntry = null;
500 pEntry = _AppControlRegistry::GetInstance()->GetReverseAppControlAliasEntry(provider, oId);
503 provider = pEntry->provider;
504 oId = pEntry->operation;
506 SysLog(NID_APP, "Legacy AppControl name (%ls, %ls).", provider.GetPointer(), oId.GetPointer());
510 if (prop & _APPCONTROL_PROPERTY_APPID_CHANGE)
512 String tmp = _AppControlRegistry::GetInstance()->GetReverseAliasAppId(provider);
515 SysLog(NID_APP, "AppId change (%ls -> %ls).", provider.GetPointer(), tmp.GetPointer());
521 std::unique_ptr<HashMap> pMap(pResArg->GetArgMapN());
523 ArrayList list(SingleObjectDeleter);
524 _AppArg::FillLegacyAppControlResult(list, res, pMap.get(), provider);
526 // proper callback invokation
527 pListener->OnAppControlCompleted(provider, oId, &list);
533 _AppControlImpl::AppControlCb(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop, int reqId)
535 SysLog(NID_APP, "Result value : %d, property : 0x%x", res, prop);
537 SysTryReturnResult(NID_APP, data && pResArg && pArg, E_SYSTEM, "Invalid result (callback, result, arg) = (0x%x, 0x%x, 0x%x).",
541 bundle* b = pResArg->GetBundle();
542 SysTryReturnResult(NID_APP, b != NULL, E_SYSTEM, "Invalid result bundle.");
544 IAppControlResponseListener* pListener = static_cast<IAppControlResponseListener*>(data);
545 SysTryReturnResult(NID_APP, typeid(pListener) == typeid(IAppControlResponseListener*), E_SYSTEM, "Invalid result callback");
547 bundle* inb = pArg->GetBundle();
548 SysTryReturnResult(NID_APP, inb != NULL, E_SYSTEM, "Empty caller bundle.");
552 AppId provider = pResArg->GetCalleeAppId();
554 const char* p = appsvc_get_operation(inb);
560 SysLog(NID_APP, "Invoking callback with (%ls, %ls)", provider.GetPointer(), oId.GetPointer());
562 if (prop & _APPCONTROL_PROPERTY_ALIAS)
564 SysLog(NID_APP, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
565 const _AppControlRegistry::_AppControlAliasEntry* pEntry = null;
566 pEntry = _AppControlRegistry::GetInstance()->GetReverseRuntimeAliasEntry(provider, oId);
569 provider = pEntry->provider;
570 oId = pEntry->operation;
572 SysLog(NID_APP, "Original AppControl name (%ls, %ls).", provider.GetPointer(), oId.GetPointer());
574 SysLog(NID_APP, "CCCCCCCCCCCCCCCCCCCCCCCCCCCCC 0x%x", pEntry);
577 if (prop & _APPCONTROL_PROPERTY_APPID_CHANGE)
579 String tmp = _AppControlRegistry::GetInstance()->GetReverseAliasAppId(provider);
582 SysLog(NID_APP, "AppId change (%ls -> %ls).", provider.GetPointer(), tmp.GetPointer());
588 std::unique_ptr<HashMap> pMap(pResArg->GetArgMapN());
590 AppCtrlResult ret = APP_CTRL_RESULT_FAILED;
591 // to prevent enum overflow;
595 case SERVICE_RESULT_SUCCEEDED:
596 ret = APP_CTRL_RESULT_SUCCEEDED;
598 case SERVICE_RESULT_FAILED:
599 ret = APP_CTRL_RESULT_CANCELED;
601 case SERVICE_RESULT_CANCELED:
602 ret = APP_CTRL_RESULT_ABORTED;
604 case APPSVC_OSP_RES_FAIL:
605 ret = APP_CTRL_RESULT_FAILED;
607 case APPSVC_OSP_RES_TERMINATE:
608 ret = APP_CTRL_RESULT_TERMINATED;
611 ret = APP_CTRL_RESULT_FAILED;
615 SysLog(NID_APP, "Result code : 0x%x.", ret);
617 // proper callback invokation
618 _AppControlResponseEvent* pResponseEvent = null;
619 _AppControlManager::GetInstance()->GetAppControlResponseEventContainer()->GetValue(reqId, pResponseEvent);
621 if (pResponseEvent != null)
623 _AppControlResponseEventArg* pResponseEventArg = new (std::nothrow) _AppControlResponseEventArg(pListener, _APPCONTROL_RESPONSETYPE_COMPLETE, provider, oId, E_SUCCESS, ret, pMap.get(), reqId);
624 pResponseEvent->Fire(*pResponseEventArg);
625 SysLog(NID_APP, "OnAppControlCompleteResponseReceived, pResponseEvent is Fired");
629 pListener->OnAppControlCompleteResponseReceived(provider, oId, ret, pMap.get());
630 SysLog(NID_APP, "OnAppControlCompleteResponseReceived, Called");
637 _AppControlImpl::StartNative(const IList* pDataList, IAppControlEventListener* pListener)
639 SysLog(NID_APP, "Enter");
640 _InProcessInfo* pInfo = _AppControlManager::GetInstance()->__inAppManager.FindItem(_reqId);
641 SysTryReturnResult(NID_APP, pInfo == null, E_IN_PROGRESS, "Request ID %d is already in progress.", _reqId);
643 int req = _REQ_ID_INVALID;
644 _LibraryImpl* pLib = null;
646 pLib = new (std::nothrow) _LibraryImpl;
647 SysTryReturnResult(NID_APP, pLib != null, E_OUT_OF_MEMORY, "Failed to allocate libraryimpl.");
649 unsigned long option = _LIBRARY_LOAD_OPTION_LAZY;
650 option |= _LIBRARY_LOAD_OPTION_NODELETE;
652 result r = pLib->Construct(_path, option);
653 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
657 _InProcessInfo* pItem = new (std::nothrow) _InProcessInfo(_provider, _opId, _property, true, *pLib, pListener);
660 req = _AppControlManager::GetInstance()->__inAppManager.InsertItem(pItem);
663 r = InvokeStartAppControl(*pLib, req, _provider, _opId, pDataList);
665 if (pListener == null)
670 // after acquring request number, pLib should be managed from the list, not CATCH
673 SetLastResult(E_SYSTEM);
674 _AppControlManager::GetInstance()->__inAppManager.RemoveItem(req);
675 SysLog(NID_APP, "[E_SYSTEM] A system error has occurred with %s.", GetErrorMessage(r));
682 SysLog(NID_APP, "Exit");
690 case E_LIBRARY_NOT_FOUND:
702 _AppControlImpl::StartNative(const String* pUriData, const String* pMimeType, const IMap* pDataList, IAppControlResponseListener* pListener)
704 SysLog(NID_APP, "Enter");
705 _InProcessInfo* pInfo = _AppControlManager::GetInstance()->__inAppManager.FindItem(_reqId);
706 SysTryReturnResult(NID_APP, pInfo == null, E_IN_PROGRESS, "Request ID %d is already in progress.", _reqId);
708 int req = _REQ_ID_INVALID;
709 _LibraryImpl* pLib = null;
711 pLib = new (std::nothrow) _LibraryImpl;
712 SysTryReturnResult(NID_APP, pLib != null, E_OUT_OF_MEMORY, "Failed to allocate libraryimpl.");
714 unsigned long option = _LIBRARY_LOAD_OPTION_LAZY;
715 option |= _LIBRARY_LOAD_OPTION_NODELETE;
717 result r = pLib->Construct(_path, option);
719 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
723 _InProcessInfo* pItem = new (std::nothrow) _InProcessInfo(_provider, _opId, _property, false, *pLib, pListener);
726 req = _AppControlManager::GetInstance()->__inAppManager.InsertItem(pItem);
729 if (_ThreadImpl::GetCurrentThreadImpl()->GetThreadType() == THREAD_TYPE_EVENT_DRIVEN)
731 _AppControlResponseEvent* pAppControlResponseEvent = new (std::nothrow) _AppControlResponseEvent();
733 if (pAppControlResponseEvent != null)
735 r = pAppControlResponseEvent->Construct();
736 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::Construct() is failed", GetErrorMessage(r));
738 r = pAppControlResponseEvent->AddListener(*this, true);
739 SysTryLog(NID_APP, r == E_SUCCESS, "[%s]_AppControlResponseEvent::AddListener() is failed", GetErrorMessage(r));
741 IMapT<int, _AppControlResponseEvent*>* pResponseEventContainer = _AppControlManager::GetInstance()->GetAppControlResponseEventContainer();
742 if (pResponseEventContainer != null)
744 int responseEventRequestId = RESPONSE_EVENT_REQID_MAGIC + req;
745 pResponseEventContainer->Add(responseEventRequestId, pAppControlResponseEvent);
746 __appControlResponseEventList.Add(responseEventRequestId);
747 SysLog(NID_APP, "pResponseEvent gets added. reqId(%d)", responseEventRequestId);
752 r = InvokeStartAppControl(*pLib, req, _provider, _opId, pUriData, pMimeType, pDataList);
754 if (pListener == null)
759 // after acquring request number, pLib should be managed from the list, not CATCH
762 SetLastResult(E_SYSTEM);
763 _AppControlManager::GetInstance()->__inAppManager.RemoveItem(req);
764 SysLog(NID_APP, "[E_SYSTEM] A system error has occurred with %s.", GetErrorMessage(r));
770 SysLog(NID_APP, "Exit");
779 case E_LIBRARY_NOT_FOUND:
791 _AppControlImpl::InvokeStartAppControl(_LibraryImpl& lib, int req, const String& appId, const String& oId, const IList* pList)
793 SysLog(NID_APP, "Legacy stuff for converting argument");
795 HashMap map(SingleObjectDeleter);
796 HashMap* pMap = null;
801 _AppArg::FillMapFromList(&map, pList);
806 return InvokeStartAppControl(lib, req, appId, oId, null, null, pMap);
811 _AppControlImpl::InvokeStartAppControl(_LibraryImpl& lib, int req, const String& appId, const String& oId, const String* pUri, const String* pMime, const IMap* pMap)
813 result (*pFunc)(int req, const String&, const String&, const String*, const String*, const IMap*) = null;
816 reinterpret_cast<result (*)(int, const String&, const String&, const String*, const String*, const IMap*)>(lib.GetProcAddress(L"StartAppControl"));
817 SysTryReturnResult(NID_APP, pFunc != null, E_OBJ_NOT_FOUND, "Entry \"StartAppControl\" not found for %ls", appId.GetPointer());
819 const String* pActualUri = (pUri && !(pUri->IsEmpty())) ? pUri : null;
820 const String* pActualMime = (pMime && !(pMime->IsEmpty())) ? pMime : null;
821 return (*pFunc)(req, appId, oId, pActualUri, pActualMime, pMap);
825 IsValidAppControl(const String& appcontrolID)
827 return ((appcontrolID == L"osp.appcontrol.provider.audio")
828 || (appcontrolID == L"osp.appcontrol.provider.bluetooth")
829 || (appcontrolID == L"osp.appcontrol.provider.calendar")
830 || (appcontrolID == L"osp.appcontrol.provider.camera")
831 || (appcontrolID == L"osp.appcontrol.provider.contact")
832 || (appcontrolID == L"osp.appcontrol.provider.certificatemanager")
833 || (appcontrolID == L"osp.appcontrol.provider.email")
834 || (appcontrolID == L"osp.appcontrol.provider.image")
835 || (appcontrolID == L"osp.appcontrol.provider.media")
836 || (appcontrolID == L"osp.appcontrol.provider.message")
837 || (appcontrolID == L"osp.appcontrol.provider.video")
838 || (appcontrolID == L"osp.appcontrol.provider.imageeditor")
839 || (appcontrolID == L"osp.appcontrol.provider.allshare")
840 || (appcontrolID == L"tizen.filemanager")
841 || (appcontrolID == L"tizen.camera")
842 || (appcontrolID == L"tizen.gallery")
843 || (appcontrolID == L"tizen.imageviewer")
844 || (appcontrolID == L"tizen.videoplayer")
845 || (appcontrolID == L"tizen.memo")
846 || (appcontrolID == L"tizen.contacts")
847 || (appcontrolID == L"tizen.calendar")
848 || (appcontrolID == L"tizen.events")
849 || (appcontrolID == L"tizen.email")
850 || (appcontrolID == L"tizen.settings")
851 || (appcontrolID == L"tizen.messages")
852 || (appcontrolID == L"tizen.musicplayer")
853 || (appcontrolID == L"tizen.bluetooth")
854 || (appcontrolID == L"samsung.snote")
855 || (appcontrolID == L"0pnxz8hbsr.MyFiles")
856 || (appcontrolID == L"hdufar9ycj.Camera")
857 || (appcontrolID == L"ijudt7w61q.Gallery")
858 || (appcontrolID == L"jysyv9o1dc.ImageViewer")
859 || (appcontrolID == L"npwf0scb88.VideoPlayer")
860 || (appcontrolID == L"zunqjlsnce.Memo")
861 || (appcontrolID == L"f9uev8hsyo.Contacts")
862 || (appcontrolID == L"ph1vq2phrp.Calendar")
863 || (appcontrolID == L"vxqbrefica.Email")
864 || (appcontrolID == L"kto5jikgul.Settings")
865 || (appcontrolID == L"8r4r5ddzzn.Messages")
866 || (appcontrolID == L"dhrul6qzj3.MusicPlayer")
867 || (appcontrolID == L"smemo-efl"));
871 _AppControlImpl::Stop(void)
873 const String appcontrolID(GetAppControlProviderId());
874 SysTryReturnResult(NID_APP, IsValidAppControl(appcontrolID), E_INVALID_OPERATION, "Invalid appcontrolID(%ls)", appcontrolID.GetPointer());
876 if (_property & _APPCONTROL_PROPERTY_SLP)
878 SysTryReturnResult(NID_APP, _reqId != _REQ_ID_INVALID, E_INVALID_OPERATION, "Invalid request ID .");
880 _InProcessInfo* pInfo = _AppControlManager::GetInstance()->__inAppManager.FindItem(_reqId);
881 SysTryReturnResult(NID_APP, pInfo != null, E_INVALID_OPERATION, "Request ID %d is not found.", _reqId);
883 result (*pStop)(int req) = null;
884 pStop = reinterpret_cast<result (*)(int)>(pInfo->pLib->GetProcAddress(L"TerminateAppControl"));
885 SysTryReturnResult(NID_APP, pStop != null, E_SYSTEM, "No TerminateAppControl() function.");
889 _AppControlManager::GetInstance()->__inAppManager.RemoveItem(_reqId);
891 _reqId = _REQ_ID_INVALID;
893 else if (_property & _APPCONTROL_PROPERTY_OSP)
895 _Aul::TerminateApplicationByPid(_processId);
902 _AppControlImpl::GetAppName(void)
904 if ((_property & _APPCONTROL_PROPERTY_OSP) && _appName.IsEmpty())
906 const AppId& appId = _path;
908 std::unique_ptr<PackageAppInfo> pInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(appId));
912 const String& name = pInfo->GetAppName();
913 if (name == L"_AppControl")
915 // workaround for special case: requery with actual appId
916 const PackageId& packageId = _PackageManagerImpl::GetPackageIdByAppId(appId);
917 const String& defaultName = _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(packageId);
919 const String& convertedAppId = packageId + L'.' + defaultName;
921 std::unique_ptr<PackageAppInfo> pNewInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(convertedAppId));
925 _appName = pNewInfo->GetAppName();
929 SysLog(NID_APP, "No default applicaiton information, possible database error.");
934 _appName = pInfo->GetAppName();
936 SysLog(NID_APP, "Initializing AppName(%ls) for %ls.", _appName.GetPointer(), appId.GetPointer());
944 _AppControlImpl::GetAppId(void) const
946 return (_property & _APPCONTROL_PROPERTY_OSP) ? _path : _provider;
950 _AppControlImpl::GetAppControlProviderId(void) const
956 _AppControlImpl::GetOperationId(void) const
962 _AppControlImpl::GetCategoryListN(void) const
964 const AppId& appId = GetAppId();
965 SysTryReturn(NID_APP, !appId.IsEmpty(), null, E_SYSTEM, "[E_SYSTEM] Empty appId.");
967 SysLog(NID_APP, "Acquiring category for appId %ls.", appId.GetPointer());
969 std::unique_ptr<PackageAppInfo> pAppInfo(_PackageManagerImpl::GetInstance()->GetPackageAppInfoN(appId));
970 SysTryReturn(NID_APP, pAppInfo.get() != null, null, E_SYSTEM, "[E_SYSTEM] Getting PackageAppInfo failed.");
972 return pAppInfo->GetAppCategoryListN();
976 _AppControlImpl::StopAppControlResponseListener(IAppControlResponseListener* pListener)
978 _AppControlManager::GetInstance()->__listenerList.Add(pListener);
982 _AppControlImpl::OnAppControlResponseEventReceivedN(const Tizen::Base::Runtime::IEventArg* arg)
984 const _AppControlResponseEventArg* pEventArg = dynamic_cast<const _AppControlResponseEventArg*>(arg);
986 if (pEventArg != null)
988 IAppControlResponseListener* pResponseListener = pEventArg->GetListener();
990 if(pResponseListener != null)
992 if(pEventArg->GetType() == _APPCONTROL_RESPONSETYPE_COMPLETE)
994 pResponseListener->OnAppControlCompleteResponseReceived(pEventArg->GetAppId(), pEventArg->GetOperationId(), pEventArg->GetAppControlResult(), pEventArg->GetExtraData());
995 SysLog(NID_APP, "OnAppControlCompleteResponseReceived called");
997 _AppControlResponseEvent* pResponseEvent = null;
998 _AppControlManager::GetInstance()->GetAppControlResponseEventContainer()->GetValue(pEventArg->GetRequestId(), pResponseEvent);
999 _AppControlManager::GetInstance()->GetAppControlResponseEventContainer()->Remove(pEventArg->GetRequestId());
1000 delete pResponseEvent;
1001 SysLog(NID_APP, "pResponseEvent gets deleted, reqId(%d)", pEventArg->GetRequestId());
1005 SysLog(NID_APP, "Unexpected AppControlResponseType(%d)", pEventArg->GetType());
1010 SysLog(NID_APP, "Invalid ResponseListener");
1015 SysLog(NID_APP, "Invalid AppControl arguments : arg(0x%x)", &arg);