19317811276207dd8af3b096df068f1bf06a4ba6
[platform/framework/native/appfw.git] / src / app / FApp_AppManagerImpl.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_AppManagerImpl.cpp
19  * @brief       This is the implementation for the _AppManagerImpl class.
20  */
21
22 #include <memory>
23 #include <stdint.h>
24 #include <cstdio>
25 #include <unique_ptr.h>
26
27 #include <aul/aul.h>
28 #include <bundle.h>
29
30 #include <FBaseObject.h>
31 #include <FBaseString.h>
32 #include <FBaseColArrayList.h>
33 #include <FBaseErrors.h>
34 #include <FAppAppControl.h>
35 #include <FAppAppManager.h>
36 #include <FAppSqlDataControl.h>
37 #include <FAppMapDataControl.h>
38 #include <FAppPkgPackageInfo.h>
39 #include <FAppIActiveAppEventListener.h>
40 #include <FBaseSysLog.h>
41 #include <FAppIAppControlListener.h>
42
43 #include <FBase_StringConverter.h>
44 #include <FBaseRt_LibraryImpl.h>
45 #include <FSys_SystemInfoImpl.h>
46
47 #include "FApp_AppControlRegistry.h"
48 #include "FApp_AppImpl.h"
49 #include "FApp_AppInfo.h"
50 #include "FApp_AppManagerImpl.h"
51 #include "FApp_AppManagerProxy.h"
52 #include "FApp_AppMessageImpl.h"
53 #include "FApp_AppControlImpl.h"
54 #include "FApp_ConditionManagerProxy.h"
55 #include "FApp_IAppEventListener.h"
56 #include "FApp_MapDataControlImpl.h"
57 #include "FApp_SqlDataControlImpl.h"
58 #include "FAppPkg_PackageManagerImpl.h"
59 #include "FAppPkg_PackageInfoImpl.h"
60 #include "FApp_AppControlManager.h"
61 #include "FApp_TemplateUtil.h"
62 #include "FApp_Aul.h"
63 #include "FApp_AppLifecycleEvent.h"
64 #include "FApp_AppLifecycleEventArg.h"
65 #include "FApp_IAppLifecycleEventListener.h"
66 #include "FApp_ActiveWindowManager.h"
67
68 using namespace Tizen::App::Package;
69 using namespace Tizen::Base;
70 using namespace Tizen::Base::Collection;
71 using namespace Tizen::Base::Runtime;
72 using namespace Tizen::Base::Utility;
73 using namespace Tizen::Io;
74
75 namespace
76 {
77
78 //const long MAX_APPCONTROL_ARGUMENT = 4096;
79 const long MAX_APPCONTROL_ARGUMENT = 1024;
80 const long MAX_CONDITION_LENGTH = 400;
81
82 int
83 GetTotalSize(const Tizen::Base::Collection::ICollection& col)
84 {
85         int size = 0;
86         std::unique_ptr<IEnumerator> pEnum(col.GetEnumeratorN());
87
88         if (pEnum)
89         {
90                 while (pEnum->MoveNext() == E_SUCCESS)
91                 {
92                         String* pStr = static_cast<String*>(pEnum->GetCurrent());
93                         if (pStr == null)
94                         {
95                                 continue;
96                         }
97                         size += pStr->GetLength();
98                 }
99         }
100
101         return size;
102 }
103
104 } // anonymous name-space
105
106
107 namespace Tizen { namespace App
108 {
109
110 const wchar_t LEGACY_LAUNCH_REASON_NORMAL[] = L"LAUNCH_NORMAL";
111 const wchar_t LEGACY_LAUNCH_REASON_CONDITIONAL[] = L"LAUNCH_CONDITIONAL";
112 const wchar_t OSP_UI_SONAME[] = L"libosp-uifw.so.1";
113 const int _MAX_PACKAGE_ID_LENGTH = 10;
114
115
116 _AppManagerImpl::_AppManagerImpl(void)
117         : __pConditionManager(null)
118         , __pActiveWindowManager(new (std::nothrow) _ActiveWindowManager)
119         , __pUiLibrary(null)
120 {
121         SysLog(NID_APP, "");
122 }
123
124 _AppManagerImpl::~_AppManagerImpl(void)
125 {
126         SysLog(NID_APP, "");
127
128         delete __pConditionManager;
129         delete __pUiLibrary;
130 }
131
132
133 result
134 _AppManagerImpl::Construct(void)
135 {
136         __appLifecycleEvent.Construct();
137         __appListForAppLifecycle.Construct();
138         result r = __mutex.Create();
139         SysTryLog(NID_APP, r == E_SUCCESS, "Creating mutex failed.");
140
141         _IAppManager* pMgr = _AppManagerProxy::GetService();
142         //todo : uncomment following _SysTryReturn or put assert.
143         //SysTryReturn(NID_APP, pMgr != null, GetLastResult(), GetLastResult(), "[%s]GetService failed. Please check 'ps -A | grep OspAppService'!", GetLastResult());
144         SysTryReturn(NID_APP, pMgr != null, E_SUCCESS, E_SUCCESS, "[E_SYSTEM] fatal error. Please check 'ps -A | grep osp-app-service'!", GetLastResult());
145         pMgr->InitEventListener(this);
146
147         return E_SUCCESS;
148 }
149
150 _AppManagerImpl*
151 _AppManagerImpl::GetInstance(void)
152 {
153         return AppManager::GetInstance()->__pAppManagerImpl;
154 }
155
156 _ConditionManagerProxy*
157 _AppManagerImpl::GetConditionManagerProxy(void)
158 {
159         if (__pConditionManager == null)
160         {
161                 const int MAX_TRY_COUNT = 5;
162                 const int TRY_SLEEP_TIME = 250;
163
164                 __pConditionManager = new (std::nothrow) _ConditionManagerProxy;
165                 SysAssert(__pConditionManager != null);
166
167                 int count = 0;
168                 while (true)
169                 {
170                         result r = __pConditionManager->Construct();
171                         if (r == E_SUCCESS)
172                         {
173                                 SysLog(NID_APP, "Succeeded in connecting condition manager.");
174                                 break;
175                         }
176
177                         if (count >= MAX_TRY_COUNT)
178                         {
179                                 SysLog(NID_APP, "Failed to connecting condition manager.");
180                                 break;
181                         }
182
183                         count++;
184                         Thread::Sleep(TRY_SLEEP_TIME);
185                 }
186         }
187
188         return __pConditionManager;
189 }
190
191 AppControl*
192 _AppManagerImpl::FindAppControlN(const AppId& aId, const String& oId)
193 {
194         _AppControlRegistry* pRegs = _AppControlRegistry::GetInstance();
195
196         AppControl* pAc = null;
197
198         pAc = pRegs->GetTizenAppControlN(aId, oId);
199         SysTryReturn(NID_APP, pAc != null, null, E_OBJ_NOT_FOUND, "[%s] No matching AppControl instance found (%ls, %ls).",
200                                  GetErrorMessage(E_OBJ_NOT_FOUND), aId.GetPointer(), oId.GetPointer());
201         SetLastResult(E_SUCCESS);
202         return pAc;
203 }
204
205 IList*
206 _AppManagerImpl::FindAppControlsN(const String* pOperationId, const String* pCategory, const String* pDataType,
207                                                                   const String* pUriScheme)
208 {
209         SysTryReturn(NID_APP, !(pOperationId == null && pCategory == null && pUriScheme == null && pDataType == null), null,
210                                  E_INVALID_ARG, "[%s] At least one parameter should not be null.", GetErrorMessage(E_INVALID_ARG));
211
212         String mimeType;
213         const String* pMimeType = pDataType;
214
215         if (pDataType)
216         {
217                 mimeType = _AppControlManager::GetMimeTypeFromDataType(*pDataType);
218         }
219
220         if (pUriScheme)
221         {
222                 SysTryReturn(NID_APP, !(pUriScheme->IsEmpty()), null, E_INVALID_FORMAT, "[%s] The specified URI scheme is invalid.",
223                                          GetErrorMessage(E_INVALID_FORMAT));
224         }
225
226         _AppControlRegistry* pRegs = _AppControlRegistry::GetInstance();
227         ArrayList* pRetArg = pRegs->FindAppControlListN(pOperationId, pUriScheme, pMimeType, pCategory);
228
229         if ((pRetArg == null) || (pRetArg->GetCount() == 0))
230         {
231                 delete pRetArg;
232                 pRetArg = null;
233                 SetLastResult(E_OBJ_NOT_FOUND);
234                 return null;
235         }
236
237         SetLastResult(E_SUCCESS);
238         SysLog(NID_APP, "Found %d matching AppControls.", pRetArg->GetCount());
239
240         return pRetArg;
241 }
242
243
244 result
245 _AppManagerImpl::StartAppControl(const String& uri, const String* pOperationId, const String* pDataType,
246                                                                  IAppControlListener* pListener)
247 {
248         return StartAppControl(pOperationId, null, pDataType, &uri, null, pListener);
249 }
250
251
252 result
253 _AppManagerImpl::StartAppControl(const String* pOperationId, const String* pCategory, const String* pDataType,
254                                                                  const String* pUri, const IList* pDataList, IAppControlListener* pListener)
255 {
256         SysTryReturnResult(NID_APP, !(pOperationId == null && pUri == null && pCategory == null && pDataType == null), E_INVALID_ARG,
257                                                 "At least one of the specified argument must not be null.");
258         if (pDataList != null)
259         {
260                 int argSize = 0;
261                 argSize = GetTotalSize(*pDataList);
262
263                 SysLog(NID_APP, "Argument count = %d, size = %d", pDataList->GetCount(), argSize);
264
265                 SysTryReturnResult(NID_APP, argSize <= MAX_APPCONTROL_ARGUMENT, E_MAX_EXCEEDED,
266                                                   "The size of pDataList exceeded the limit(%d).",
267                                                   MAX_APPCONTROL_ARGUMENT);
268         }
269
270         String operation = (pOperationId) ? *pOperationId : TIZEN_OPERATION_MAIN;
271
272         std::unique_ptr<bundle, BundleDeleter> pBundle(bundle_create());
273         SysTryReturnResult(NID_APP, pBundle.get(), E_OUT_OF_MEMORY, "Bundle creation failure.");
274
275         _AppMessageImpl::SetOperation(pBundle.get(), operation);
276
277         if (pUri)
278         {
279                 _AppMessageImpl::SetUri(pBundle.get(), *pUri);
280         }
281
282         if (pDataType)
283         {
284                 const String& mimeType = _AppControlManager::GetMimeTypeFromDataType(*pDataType);
285
286                 _AppMessageImpl::SetMime(pBundle.get(), mimeType);
287         }
288
289         if (pCategory)
290         {
291                 _AppMessageImpl::SetCategory(pBundle.get(), *pCategory);
292         }
293
294         return _AppControlImpl::StartImplicit(pBundle.get(), pDataList, pListener);
295 }
296
297
298 SqlDataControl*
299 _AppManagerImpl::GetSqlDataControlN(const String& providerId)
300 {
301         SqlDataControl* pDc = null;
302         String type(L"Sql");
303         String* pAppId = null;
304         String* pAccess = null;
305         String appId;
306
307         // XXX: Need _NativeDataControlRegistry for SLP native app ?
308         // Try to searach SLP data control.
309 //      _NativeDataControlRegistry* pReg = _NativeDataControlRegistry::GetInstance(); // singleton
310 //      pDc = pReg->GetNativeSqlDataControlN(providerId);
311 //      if (pDc != null)
312 //      {
313 //              return pDc;
314 //      }
315
316         std::unique_ptr <IList, AllElementsDeleter> pList(_PackageManagerImpl::GetInstance()->GetDataControlInfoN(providerId, type));
317         SysTryReturn(NID_APP, pList != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The data control provider does not exist.");
318
319         pAppId = dynamic_cast< String* >(pList->GetAt(0));
320         SysTryReturn(NID_APP, pAppId != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
321         pAccess = dynamic_cast< String* >(pList->GetAt(1));
322         SysTryReturn(NID_APP, pAccess != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
323         pAccess->ToLower();
324
325         if (pAppId->StartsWith(L"org.tizen.", 0))
326         {
327                 std::unique_ptr<StringTokenizer> pStrTok(new (std::nothrow) StringTokenizer(*pAppId, L'.'));
328                 SysTryReturn(NID_APP, pStrTok != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
329                 for (int i = 0; i < 3; ++i)
330                 {
331                         pStrTok->GetNextToken(appId);
332                 }
333
334                 appId[_MAX_PACKAGE_ID_LENGTH] = L'.';
335         }
336         else
337         {
338                 appId.Append(*pAppId);
339         }
340
341         pDc = _SqlDataControlImpl::CreateSqlDataControl(appId, providerId, *pAccess);
342         SysTryReturn(NID_APP, pDc != null, null, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
343
344         return pDc;
345 }
346
347 MapDataControl*
348 _AppManagerImpl::GetMapDataControlN(const String& providerId)
349 {
350         MapDataControl* pDc = null;
351         String type(L"Map");
352         String* pAppId = null;
353         String* pAccess = null;
354         String appId;
355
356         // XXX: Need _NativeDataControlRegistry for SLP native app ?
357         // Try to searach SLP data control.
358 //      _NativeDataControlRegistry* pReg = _NativeDataControlRegistry::GetInstance(); // singleton
359 //      pDc = pReg->GetNativeMapDataControlN(providerId);
360 //      if (pDc != null)
361 //      {
362 //              return pDc;
363 //      }
364
365         std::unique_ptr <IList, AllElementsDeleter> pList(_PackageManagerImpl::GetInstance()->GetDataControlInfoN(providerId, type));
366         SysTryReturn(NID_APP, pList != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The data control provider does not exist.");
367
368         pAppId = dynamic_cast< String* >(pList->GetAt(0));
369         SysTryReturn(NID_APP, pAppId != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
370         pAccess = dynamic_cast< String* >(pList->GetAt(1));
371         SysTryReturn(NID_APP, pAccess != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
372         pAccess->ToLower();
373
374         if (pAppId->StartsWith(L"org.tizen.", 0))
375         {
376                 std::unique_ptr<StringTokenizer> pStrTok( new (std::nothrow) StringTokenizer(*pAppId, L'.'));
377                 SysTryReturn(NID_APP, pStrTok != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
378                 for (int i = 0; i < 3; ++i)
379                 {
380                         pStrTok->GetNextToken(appId);
381                 }
382
383                 appId[_MAX_PACKAGE_ID_LENGTH] = L'.';
384         }
385         else
386         {
387                 appId.Append(*pAppId);
388         }
389
390         pDc = _MapDataControlImpl::CreateMapDataControl(appId, providerId, *pAccess);
391         SysTryReturn(NID_APP, pDc != null, null, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
392
393         return pDc;
394 }
395
396 result
397 _AppManagerImpl::GetAppRootPath(const AppId& appId, String& appRootPath)
398 {
399         String pkgId = PackageManager::GetPackageIdByAppId(appId);
400         SysTryReturnResult(NID_APP, pkgId.IsEmpty() == false, E_APP_NOT_INSTALLED,
401                         "The application is not installed. (app: %ls)", appId.GetPointer());
402
403         _PackageManagerImpl* pPkgMgr = _PackageManagerImpl::GetInstance();
404         SysTryReturnResult(NID_APP, pPkgMgr != null, E_SYSTEM,
405                         "Failed to get _PackageManagerImpl instance.");
406
407         std::unique_ptr< PackageInfo >pPkgInfo(pPkgMgr->GetPackageInfoN(pkgId));
408         SysTryReturnResult(NID_APP, pPkgInfo != null, E_APP_NOT_INSTALLED,
409                         "The application is not installed. (app: %ls)", appId.GetPointer());
410
411         _PackageInfoImpl* pPkgInfoImpl = _PackageInfoImpl::GetInstance(pPkgInfo.get());
412         SysTryReturnResult(NID_APP, pPkgInfoImpl != null, E_SYSTEM,
413                         "Failed to get _PackageInfoImpl instance.");
414
415         appRootPath = pPkgInfoImpl->GetAppRootPath();
416         appRootPath.Append(L"/");
417
418         return E_SUCCESS;
419 }
420
421 result
422 _AppManagerImpl::LaunchApplication(const String& appId, const IList* pArguments, AppManager::LaunchOption option)
423 {
424         SysTryReturnResult(NID_APP, !appId.IsEmpty(), E_INVALID_ARG, "The appid is empty.");
425         SysTryReturnResult(NID_APP, _Aul::IsInstalled(appId) == true, E_OBJ_NOT_FOUND,
426                                            "The target application(%ls) is not installed.", appId.GetPointer());
427 //      SysTryReturnResult(NID_APP,
428 //                                        appId.GetLength() <= WIDGET_APP_MAX_APPID_LENGTH, E_MAX_EXCEEDED,
429 //                                        "The length of appid exceeded the limit(%d).",
430 //                                        WIDGET_APP_MAX_APPID_LENGTH);
431
432         std::unique_ptr<AppControl> pAc(FindAppControlN(appId, TIZEN_OPERATION_MAIN));
433         SysTryReturnResult(NID_APP, pAc.get() != null, E_OBJ_NOT_FOUND, "The target application (%ls) is not found.", appId.GetPointer());
434
435         if (pArguments)
436         {
437                 int argSize = 0;
438                 argSize = GetTotalSize(*pArguments);
439
440                 SysLog(NID_APP, "Argument count = %d, size = %d", pArguments->GetCount(), argSize);
441
442                 SysTryReturnResult(NID_APP, argSize <= MAX_APPCONTROL_ARGUMENT, E_MAX_EXCEEDED,
443                                                   "The size of pDataList exceeded the limit(%d).",
444                                                   MAX_APPCONTROL_ARGUMENT);
445         }
446
447         result r = pAc->Start(pArguments, null);
448
449         SysLog(NID_APP, "[%s] Launching %ls finished.", GetErrorMessage(r), appId.GetPointer());
450         return r;
451 }
452
453
454 result
455 _AppManagerImpl::LaunchApplication(const String& appId, AppManager::LaunchOption option)
456 {
457         SysTryReturnResult(NID_APP, !appId.IsEmpty(), E_APP_NOT_INSTALLED, "The appid is empty.");
458
459         std::unique_ptr<char[]> pName(_StringConverter::CopyToCharArrayN(appId));
460
461         int ret = aul_open_app(pName.get());
462
463         if (ret > 0)
464         {
465                 SysLog(NID_APP, "Launching %ls successful.", appId.GetPointer());
466                 return E_SUCCESS;
467         }
468
469         // failure
470         SysTryReturnResult(NID_APP, _Aul::IsInstalled(appId) == true, E_APP_NOT_INSTALLED,
471                                            "The target application(%ls) is not installed.", appId.GetPointer());
472
473         result r = E_SYSTEM;
474         switch (ret)
475         {
476         case AUL_R_EINVAL:
477                 r = E_APP_NOT_INSTALLED;
478                 break;
479         case AUL_R_OK:
480                 // r = E_SUCCESS;
481                 // never reach here
482                 break;
483         default:
484                 break;
485         }
486
487         SysLog(NID_APP, "[%s] Launching %ls failed.", GetErrorMessage(r), appId.GetPointer());
488         return r;
489 }
490
491
492 result
493 _AppManagerImpl::TerminateApplication(const AppId& appId)
494 {
495         _IAppManager* pMgr = _AppManagerProxy::GetService();
496         SysTryReturnResult(NID_APP, pMgr, E_SYSTEM, "Failed to _AppManagerProxy::GetService().");
497
498         return pMgr->TerminateApplication(appId);
499 }
500
501
502 static int
503 TerminateIterFnCb(const aul_app_info* pAppInfo, void* pData)
504 {
505         const char* pStr = static_cast<const char*>(pData);
506
507         if (pStr && strncmp(pStr, pAppInfo->pkg_name, _MAX_PACKAGE_ID_LENGTH) == 0)
508         {
509                 aul_terminate_pid(pAppInfo->pid);
510                 SysLog(NID_APP, "%s(%d) is terminated.", pAppInfo->pkg_name, pAppInfo->pid);
511         }
512         return 0;
513 }
514
515 result
516 _AppManagerImpl::TerminateApplications(const PackageId& packageId)
517 {
518         std::unique_ptr<char[]> pPackage(_StringConverter::CopyToCharArrayN(packageId));
519         aul_app_get_running_app_info(TerminateIterFnCb, static_cast<void*>(pPackage.get()));
520
521         SysLog(NID_APP, "%ls terminated.", packageId.GetPointer());
522         return E_SUCCESS;
523 }
524
525 bool
526 _AppManagerImpl::IsRunning(const AppId& appId) const
527 {
528         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
529
530         return aul_app_is_running(pAppId.get());
531 }
532
533 static int
534 AulAppInfoIterFnCb(const aul_app_info* pAppInfo, void* pData)
535 {
536         ArrayList* pList = static_cast<ArrayList*>(pData);
537         if (pList && pAppInfo && pAppInfo->appid)
538         {
539                 pList->Add(*new (std::nothrow) String(pAppInfo->appid));
540         }
541
542         return 0;
543 }
544
545 IList*
546 _AppManagerImpl::GetRunningAppListN(void) const
547 {
548         ArrayList* pRunningAppList = new (std::nothrow) ArrayList();
549         SysTryReturn(NID_APP, pRunningAppList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
550                                  GetErrorMessage(E_OUT_OF_MEMORY));
551         pRunningAppList->Construct();
552
553         int ret = aul_app_get_running_app_info(AulAppInfoIterFnCb, reinterpret_cast<void*>(pRunningAppList));
554         SysTryLog(NID_APP, ret == AUL_R_OK, "Getting running list failed.");
555
556         // according to the doxygen, GetRunningAppListN() does not return null pointer for no object
557         return pRunningAppList;
558 }
559
560
561 result
562 _AppManagerImpl::RegisterAppLaunch(const AppId& appId, const String& condition, const IList* pArguments,
563                                                                    AppManager::LaunchOption option)
564 {
565         _ConditionManagerProxy* pProxy = GetConditionManagerProxy();
566         SysTryReturnResult(NID_APP, null != pProxy, E_INVALID_STATE, "ConditionManager instance must not be null.");
567
568         Tizen::Base::Utility::StringTokenizer strTok(condition, L"=");
569         SysTryReturnResult(NID_APP, strTok.GetTokenCount() > 0, E_INVALID_ARG, "Condition string is invalid.(%ls)", condition.GetPointer());
570
571         String key;
572         result r = strTok.GetNextToken(key);
573         SysTryReturnResult(NID_APP, !IsFailed(r), E_INVALID_ARG, "Condition string is invalid.(%ls)", condition.GetPointer());
574
575         bool ret = true;
576         if (key == L"Serial")
577         {
578                 r = Tizen::System::_SystemInfoImpl::GetSysInfo(L"http://tizen.org/feature/usb.accessory", ret);
579         }
580         else if (key == L"NFC")
581         {
582                 r = Tizen::System::_SystemInfoImpl::GetSysInfo(L"http://tizen.org/feature/network.nfc", ret);
583         }
584         SysTryReturnResult(NID_APP, ret != false, E_UNSUPPORTED_OPERATION, "Condition(%ls)", condition.GetPointer());
585
586         return pProxy->RegisterAppLaunch(appId, condition, pArguments, option);
587 }
588
589 result
590 _AppManagerImpl::UnregisterAppLaunch(const AppId& appId, const String* pCondition)
591 {
592         _ConditionManagerProxy* pProxy = GetConditionManagerProxy();
593         SysTryReturnResult(NID_APP, null != pProxy, E_INVALID_STATE, "ConditionManager instance must not be null.");
594
595         if (pCondition)
596         {
597                 SysTryReturnResult(NID_APP,
598                                                   !pCondition->IsEmpty() && pCondition->GetLength() < MAX_CONDITION_LENGTH, E_OBJ_NOT_FOUND,
599                                                   "No such a condition.");
600         }
601
602         return pProxy->UnregisterAppLaunch(appId, pCondition);
603 }
604
605 bool
606 _AppManagerImpl::IsAppLaunchRegistered(const AppId& appId, const String* pCondition)
607 {
608         _ConditionManagerProxy* pProxy = GetConditionManagerProxy();
609         SysTryReturn(NID_APP, null != pProxy, false, E_INVALID_STATE, "[%s] ConditionManager instance must not be null.",
610                                  GetErrorMessage(E_INVALID_STATE));
611
612         ClearLastResult();
613         return pProxy->IsAppLaunchRegistered(appId, pCondition);
614 }
615
616 result
617 _AppManagerImpl::SetEventListener(_AppEvent appEvent, Tizen::Base::Runtime::IEventListener* pListener)
618 {
619         return _AppImpl::GetInstance()->SetListener(appEvent, pListener);
620 }
621
622
623 result
624 _AppManagerImpl::OnTerminateApplicationRequested(int clientId)
625 {
626         SysLog(NID_APP, "");
627
628         return E_SUCCESS;
629 }
630
631
632 ///////////////////////////////////////////////////////////////////////////////
633 // LifecycleManager begins.
634 ///////////////////////////////////////////////////////////////////////////////
635
636 void
637 _AppLifecycleManager::Init(void)
638 {
639         aul_listen_app_launch_signal(LaunchCallback, this);
640         aul_listen_app_dead_signal(TerminateCallback, this);
641 }
642
643 void
644 _AppLifecycleManager::Fini(void)
645 {
646         aul_listen_app_launch_signal(NULL, NULL);
647         aul_listen_app_dead_signal(NULL, NULL);
648 }
649
650 result
651 _AppLifecycleManager::AddListener(_IAppEventListener& listener)
652 {
653         if (__pEventList == null)
654         {
655                 std::unique_ptr< LinkedListT<_IAppEventListener*> > pAppEventList(new LinkedListT<_IAppEventListener*>);
656                 SysTryReturnResult(NID_APP, pAppEventList, E_SYSTEM, "Memory allocation failed.");
657
658                 Init();
659
660                 __pEventList = pAppEventList.release();
661                 SysLog(NID_APP, "Registered app event listener.");
662         }
663
664         return __pEventList->Add(&listener);
665 }
666
667 result
668 _AppLifecycleManager::RemoveListener(_IAppEventListener& listener)
669 {
670         SysTryReturnResult(NID_APP,__pEventList != null, E_OBJ_NOT_FOUND, "_IEventListener list is empty.");
671
672         result r = __pEventList->Remove(&listener);
673
674         if (__pEventList->GetCount() == 0)
675         {
676                 Fini();
677
678                 delete __pEventList;
679                 __pEventList = null;
680         }
681
682         return r;
683 }
684
685 int
686 _AppLifecycleManager::LaunchCallback(int pid, void* pData)
687 {
688         _AppLifecycleManager* pImpl = static_cast<_AppLifecycleManager*>(pData);
689         if (pImpl == null || pImpl->__pEventList == null)
690         {
691                 SysLogException(NID_APP, E_SYSTEM, "Wrong _AppLifecycleImpl state.");
692                 return -1;
693         }
694
695         char appId[255];
696         int ret = aul_app_get_appid_bypid(pid, appId, sizeof(appId));
697         if (ret != AUL_R_OK)
698         {
699                 SysLogException(NID_APP, E_SYSTEM, "Cannot acquire app for %d.", pid);
700                 return -1;
701         }
702
703         std::unique_ptr< IEnumeratorT<_IAppEventListener*> > pEnum(pImpl->__pEventList->GetEnumeratorN());
704         if (pEnum.get())
705         {
706                 const String tmp = appId;
707                 pImpl->__map.Add(pid, tmp);
708
709                 while (pEnum->MoveNext() == E_SUCCESS)
710                 {
711                         _IAppEventListener* pListener = null;
712                         pEnum->GetCurrent(pListener);
713
714                         pListener->OnApplicationLaunched(tmp, pid);
715                 }
716         }
717
718         SysLog(NID_APP, "Finished invoking application event listener for %s, %d.", appId, pid);
719
720         return 0;
721 }
722
723 int
724 _AppLifecycleManager::TerminateCallback(int pid, void* pData)
725 {
726         _AppLifecycleManager* pImpl = static_cast<_AppLifecycleManager*>(pData);
727         if (pImpl == null || pImpl->__pEventList == null)
728         {
729                 SysLogException(NID_APP, E_SYSTEM, "Wrong _AppLifecycleImpl state.");
730                 return -1;
731         }
732
733         // terminate callback cannot acquire appId from pid
734         String tmp;
735         result r = pImpl->__map.GetValue(pid, tmp);
736         if (r != E_SUCCESS)
737         {
738                 SysLog(NID_APP, "[%s] Cannot acquire app from pid %d.", GetErrorMessage(r), pid);
739                 return -1;
740         }
741
742         pImpl->__map.Remove(pid);
743
744         std::unique_ptr< IEnumeratorT<_IAppEventListener*> > pEnum(pImpl->__pEventList->GetEnumeratorN());
745         if (pEnum.get())
746         {
747                 while (pEnum->MoveNext() == E_SUCCESS)
748                 {
749                         _IAppEventListener* pListener = null;
750                         pEnum->GetCurrent(pListener);
751
752                         pListener->OnApplicationTerminated(tmp, pid);
753                 }
754         }
755
756         SysLog(NID_APP, "Finished invoking application event listener for %ls, %d.", tmp.GetPointer(), pid);
757
758         return 0;
759 }
760
761 ///////////////////////////////////////////////////////////////////////////////
762 // LifecycleManager ends.
763 ///////////////////////////////////////////////////////////////////////////////
764
765
766 result
767 _AppManagerImpl::AddAppEventListener(_IAppEventListener& listener)
768 {
769         return __lifeManager.AddListener(listener);
770 }
771
772 result
773 _AppManagerImpl::RemoveAppEventListener(_IAppEventListener& listener)
774 {
775         return __lifeManager.RemoveListener(listener);
776 }
777
778
779 _LibraryImpl&
780 _AppManagerImpl::GetUiLibraryImpl(void)
781 {
782         if (__pUiLibrary == null)
783         {
784                 __pUiLibrary = new (std::nothrow) _LibraryImpl;
785                 SysAssertf(__pUiLibrary != null, "_LibraryImpl allocation failure.");
786
787                 result r = __pUiLibrary->Construct(OSP_UI_SONAME);
788                 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
789         }
790
791         return *__pUiLibrary;
792 }
793
794
795 result
796 _AppManagerImpl::AddActiveAppEventListener(IActiveAppEventListener& listener)
797 {
798         return __pActiveWindowManager->AddActiveAppEventListener(listener);
799 }
800
801
802 result
803 _AppManagerImpl::RemoveActiveAppEventListener(IActiveAppEventListener& listener)
804 {
805         return __pActiveWindowManager->RemoveActiveAppEventListener(listener);
806 }
807
808
809 result
810 _AppManagerImpl::GetActiveApp(AppId& appId)
811 {
812         return __pActiveWindowManager->GetActiveApp(appId);
813 }
814
815
816 bool 
817 _AppManagerImpl::IsUserPreferredAppForAppControlResolution(const AppId& appId) const
818 {
819         _IAppManager* pMgr = _AppManagerProxy::GetService();
820         SysTryReturn(NID_APP, pMgr, false, E_SYSTEM, "Failed to _AppManagerProxy::GetService().");
821
822         return pMgr->IsUserPreferredAppForAppControlResolution(appId);
823 }
824
825 result 
826 _AppManagerImpl::ClearUserPreferenceForAppControlResolution(const AppId& appId)
827 {
828         _IAppManager* pMgr = _AppManagerProxy::GetService();
829         SysTryReturnResult(NID_APP, pMgr, E_SYSTEM, "Failed to _AppManagerProxy::GetService().");
830
831         return pMgr->ClearUserPreferenceForAppControlResolution(appId);
832 }
833
834 result
835 _AppManagerImpl::AddAppLifecycleEventListener(_IAppLifecycleEventListener& listener)
836 {
837         return __appLifecycleEvent.AddListener(listener, false);
838 }
839
840 result
841 _AppManagerImpl::RemoveAppLifecycleEventListener(_IAppLifecycleEventListener& listener)
842 {
843         return __appLifecycleEvent.RemoveListener(listener);
844 }
845
846 result
847 _AppManagerImpl::RegisterAppForAppLifecycleEvent(const AppId& appId)
848 {
849         SysLog(NID_APP, "Enter");
850
851         result res = __mutex.Acquire();
852         SysTryLog(NID_APP, res == E_SUCCESS, "Acquiring mutex failed.");
853
854         bool isContained = false;
855         result r = __appListForAppLifecycle.ContainsKey(appId, isContained);
856
857         int currentRefCnt = 0;
858         if(isContained)
859         {
860                 r = __appListForAppLifecycle.GetValue(appId, currentRefCnt);
861                 r = __appListForAppLifecycle.SetValue(appId, ++currentRefCnt);
862         }
863         else
864         {
865                 r = __appListForAppLifecycle.Add(appId, currentRefCnt);
866                 
867                 _IAppManager* pMgr = _AppManagerProxy::GetService();
868                 SysTryReturnResult(NID_APP, pMgr, E_SYSTEM, "_AppManagerProxy::GetService() is failed.");
869
870                 r = pMgr->RegisterAppForAppLifecycleEvent(appId, -1);
871                 SysLog(NID_APP, "The appId(%ls) is registered.", appId.GetPointer());
872         }
873         res = __mutex.Release();
874         SysTryLog(NID_APP, res == E_SUCCESS, "Releasing mutex failed.");
875         
876         SysLog(NID_APP, "Exit");
877
878         return r;
879 }
880
881 result
882 _AppManagerImpl::UnregisterAppForAppLifecycleEvent(const AppId& appId)
883 {
884         SysLog(NID_APP, "Enter");
885
886         result res = __mutex.Acquire();
887         SysTryLog(NID_APP, res == E_SUCCESS, "Acquiring mutex failed.");
888         
889         bool isContained = false;
890         result r = __appListForAppLifecycle.ContainsKey(appId, isContained);
891
892         if(isContained)
893         {
894                 int currentRefCnt = 0;
895                 r = __appListForAppLifecycle.GetValue(appId, currentRefCnt);
896
897                 currentRefCnt--;
898
899                 if (currentRefCnt < 0)
900                 {
901                         r = __appListForAppLifecycle.Remove(appId);
902
903                         _IAppManager* pMgr = _AppManagerProxy::GetService();
904                         SysTryReturnResult(NID_APP, pMgr, E_SYSTEM, "_AppManagerProxy::GetService() is failed.");
905
906                         r = pMgr->UnregisterAppForAppLifecycleEvent(appId, -1);
907                         
908                         SysLog(NID_APP, "The appId(%ls) is unregistered.", appId.GetPointer());
909                 }
910                 else
911                 {
912                         r = __appListForAppLifecycle.SetValue(appId, currentRefCnt);
913                 }
914         }
915         else
916         {
917                 SysLog(NID_APP, "The appId(%ls) is not registered.", appId.GetPointer());
918         }
919         
920         res = __mutex.Release();
921         SysTryLog(NID_APP, res == E_SUCCESS, "Releasing mutex failed.");
922         
923         SysLog(NID_APP, "Exit");
924
925         return r;
926
927 }
928
929 result
930 _AppManagerImpl::OnAppLifecycleEventReceived(int clientId,const AppId& appId, _AppLifecycleEventType appLifecycleEventType)
931 {
932         SysLog(NID_APP, "Enter appId(%ls), appLifecycleEventType(%d)", appId.GetPointer(), appLifecycleEventType);
933         
934         _AppLifecycleEventArg* pArg = new (std::nothrow)_AppLifecycleEventArg(appId, appLifecycleEventType);
935         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
936         
937         __appLifecycleEvent.FireAsync(*pArg);
938         return E_SUCCESS;
939 }
940
941 }} // Tizen::App