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