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