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