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