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