b13b58df1cbb77276576c181b30fbf4c3a1fa6e9
[platform/framework/native/appfw.git] / src / app / FApp_AppManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FApp_AppManagerImpl.cpp
20  * @brief       This is the implementation for the _AppManagerImpl class.
21  */
22
23 #include <memory>
24 #include <stdint.h>
25 #include <cstdio>
26 #include <unique_ptr.h>
27
28 #include <aul/aul.h>
29 #include <bundle.h>
30 #include <Ecore.h>
31 #include <Ecore_X.h>
32 #include <X11/Xlib.h>
33
34 #include <FBaseInteger.h>
35 #include <FBaseObject.h>
36 #include <FBaseString.h>
37 #include <FBaseColArrayList.h>
38 #include <FBaseErrors.h>
39 #include <FAppAppControl.h>
40 #include <FAppAppManager.h>
41 #include <FAppSqlDataControl.h>
42 #include <FAppMapDataControl.h>
43 #include <FAppPkgPackageInfo.h>
44 #include <FAppIActiveAppEventListener.h>
45 #include <FBaseSysLog.h>
46 #include <FAppIAppControlListener.h>
47
48 #include <FBase_StringConverter.h>
49 #include <FBaseRt_LibraryImpl.h>
50 #include <FIo_DataControlResultSetImpl.h>
51
52 #include "FApp_AppControlRegistry.h"
53 #include "FApp_AppImpl.h"
54 #include "FApp_AppInfo.h"
55 #include "FApp_AppManagerEventArg.h"
56 #include "FApp_AppManagerImpl.h"
57 #include "FApp_AppManagerProxy.h"
58 #include "FApp_AppMessageImpl.h"
59 #include "FApp_AppControlImpl.h"
60 #include "FApp_ConditionManagerProxy.h"
61 #include "FApp_IAppManagerEventListener.h"
62 #include "FApp_MapDataControlImpl.h"
63 #include "FApp_SqlDataControlImpl.h"
64 #include "FAppPkg_PackageManagerImpl.h"
65 #include "FAppPkg_PackageInfoImpl.h"
66 #include "FApp_AppControlManager.h"
67 #include "FApp_Aul.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 //extern const char* _DATACONTROL_RESULTSET_DIR;
77
78 namespace
79 {
80
81 //const long MAX_APPCONTROL_ARGUMENT = 4096;
82 const long MAX_APPCONTROL_ARGUMENT = 1024;
83 const long MAX_CONDITION_LENGTH = 400;
84
85 // ActiveWindow related function and variable from shared library.
86 // libecore_x.so.1
87 static Ecore_X_Atom(* p_ecore_x_atom_get)(const char* name) = null;
88 static int(* p_ecore_x_window_prop_window_get)(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window* val, unsigned int len) = null;
89 static Eina_Bool(* p_ecore_x_netwm_pid_get)(Ecore_X_Window win, int* pid) = null;
90 static int(* p_ecore_x_netwm_name_get)(Ecore_X_Window win, char** name) = null;
91 static Ecore_X_Window* (* p_ecore_x_window_root_list)(int* num_ret) = null;
92 static int* p_ECORE_X_EVENT_WINDOW_PROPERTY = null;
93 // libecore.so.1
94 static Ecore_Event_Handler* (* p_ecore_event_handler_add)(int type, Ecore_Event_Handler_Cb func, const void* data) = null;
95 static void* (* p_ecore_event_handler_del)(Ecore_Event_Handler* event_handler) = null;
96 // libX11.so
97 static int (* p_XSelectInput)(Display* display, Window w, long event_mask) = null;
98 static Display* (* p_XOpenDisplay)(_Xconst char* display_name) = null;
99
100 Ecore_Event_Handler* pWindowPropertyChanged = null;
101
102
103 int
104 GetTotalSize(const Tizen::Base::Collection::ICollection& col)
105 {
106         int size = 0;
107         std::unique_ptr<IEnumerator> pEnum(col.GetEnumeratorN());
108
109         if (pEnum)
110         {
111                 while (pEnum->MoveNext() == E_SUCCESS)
112                 {
113                         String* pStr = static_cast<String*>(pEnum->GetCurrent());
114                         if (pStr == null)
115                         {
116                                 continue;
117                         }
118                         size += pStr->GetLength();
119                 }
120         }
121
122         return size;
123 }
124
125 Eina_Bool
126 OnPropertyChanged(void* pData, int type, void* pEvent)
127 {
128         using namespace Tizen::App;
129
130         if (p_ecore_x_atom_get == null)
131         {
132                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
133                 p_ecore_x_atom_get = reinterpret_cast<Ecore_X_Atom(*)(const char* name)>(lib.GetProcAddress(L"ecore_x_atom_get"));
134                 SysTryReturnResult(NID_APP, p_ecore_x_atom_get != null, EINA_FALSE,
135                                                    "A system error has been occurred. Failed to get ecore_x_atom_get.");
136         }
137         if (p_ecore_x_window_prop_window_get == null)
138         {
139                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
140                 p_ecore_x_window_prop_window_get = reinterpret_cast<int(*)(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window* val, unsigned int len)>(lib.GetProcAddress(L"ecore_x_window_prop_window_get"));
141                 SysTryReturnResult(NID_APP, p_ecore_x_window_prop_window_get != null, EINA_FALSE,
142                                                    "A system error has been occurred. Failed to get ecore_x_window_prop_window_get.");
143         }
144         if (p_ecore_x_netwm_pid_get == null)
145         {
146                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
147                 p_ecore_x_netwm_pid_get = reinterpret_cast<Eina_Bool(*)(Ecore_X_Window win, int* pid)>(lib.GetProcAddress(L"ecore_x_netwm_pid_get"));
148                 SysTryReturnResult(NID_APP, p_ecore_x_netwm_pid_get != null, EINA_FALSE,
149                                                    "A system error has been occurred. Failed to get ecore_x_netwm_pid_get.");
150         }
151         if (p_ecore_x_netwm_name_get == null)
152         {
153                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
154                 p_ecore_x_netwm_name_get = reinterpret_cast<int(*)(Ecore_X_Window win, char** name)>(lib.GetProcAddress(L"ecore_x_netwm_name_get"));
155                 SysTryReturnResult(NID_APP, p_ecore_x_netwm_name_get != null, EINA_FALSE,
156                                                    "A system error has been occurred. Failed to get ecore_x_netwm_name_get.");
157         }
158
159         if (!pData)
160         {
161                 SysLog(NID_UI, "The data is not valid.");
162                 return EINA_FALSE;
163         }
164         if (!pEvent)
165         {
166                 SysLog(NID_UI, "The event is not valid.");
167                 return EINA_FALSE;
168         }
169
170         Ecore_X_Event_Window_Property* pE = (Ecore_X_Event_Window_Property*) pEvent;
171         Ecore_X_Atom atom = pE->atom;
172         Ecore_X_Atom activeAtom = p_ecore_x_atom_get("_NET_ACTIVE_WINDOW");
173
174         if (atom != activeAtom)
175         {
176                 return ECORE_CALLBACK_PASS_ON;
177         }
178
179         Ecore_X_Window win = pE->win;
180         Ecore_X_Window activeWin = 0;
181         p_ecore_x_window_prop_window_get(win, activeAtom, &activeWin, 1);
182
183         int pid = 0;
184         p_ecore_x_netwm_pid_get(activeWin, &pid);
185
186         char* pAppName = null;
187         p_ecore_x_netwm_name_get(activeWin, &pAppName);
188
189         Tizen::App::_AppManagerImpl* pAppManagerImpl = static_cast<Tizen::App::_AppManagerImpl*>(pData);
190         pAppManagerImpl->FireActiveAppEvent(activeWin, pid, pAppName);
191
192         if (pAppName)
193         {
194                 free(pAppName);
195         }
196
197         return ECORE_CALLBACK_PASS_ON;
198 }
199
200 } // anonymous name-space
201
202
203 namespace Tizen { namespace App
204 {
205
206 const wchar_t LEGACY_LAUNCH_REASON_NORMAL[] = L"LAUNCH_NORMAL";
207 const wchar_t LEGACY_LAUNCH_REASON_CONDITIONAL[] = L"LAUNCH_CONDITIONAL";
208 const wchar_t OSP_UI_SONAME[] = L"libosp-uifw.so.1";
209 const wchar_t OSP_ECORE_X_SONAME[] = L"libecore_x.so.1";
210 const wchar_t OSP_ECORE_SONAME[] = L"libecore.so.1";
211 const wchar_t OSP_X11_SONAME[] = L"libX11.so.6";
212 const int _MAX_PACKAGE_ID_LENGTH = 10;
213
214 _LibraryImpl* _AppManagerImpl::__pEcoreLibrary = null;
215 _LibraryImpl* _AppManagerImpl::__pEcoreXLibrary = null;
216
217 _AppManagerImpl::_AppManagerImpl(void)
218         : __pConditionManager(null)
219         , __eventListenerCount(0)
220         , __pUiLibrary(null)
221         , __pX11Library(null)
222 {
223         SysLog(NID_APP, "");
224 }
225
226 _AppManagerImpl::~_AppManagerImpl(void)
227 {
228         SysLog(NID_APP, "");
229
230         if (__activeAppEventListenerList.GetCount() > 0)
231         {
232                 if (p_ecore_event_handler_del == null)
233                 {
234                         _LibraryImpl& lib = GetEcoreLibraryImpl();
235                         p_ecore_event_handler_del = reinterpret_cast<void*(*)(Ecore_Event_Handler* event_handler)>(lib.GetProcAddress(L"ecore_event_handler_del"));
236                 }
237                 if (p_ecore_event_handler_del)
238                 {
239                         if (pWindowPropertyChanged)
240                         {
241                                 p_ecore_event_handler_del(pWindowPropertyChanged);
242                                 pWindowPropertyChanged = null;
243                         }
244                 }
245         }
246
247         delete __pConditionManager;
248         delete __pUiLibrary;
249         delete __pX11Library;
250         delete __pEcoreXLibrary;
251         __pEcoreXLibrary = null;
252         delete __pEcoreLibrary;
253         __pEcoreLibrary = null;
254 }
255
256
257 result
258 _AppManagerImpl::Construct(void)
259 {
260         __appManagerEvent.Construct();
261
262         _IAppManager* pMgr = _AppManagerProxy::GetService();
263         //todo : uncomment following _SysTryReturn or put assert.
264         //SysTryReturn(NID_APP, pMgr != null, GetLastResult(), GetLastResult(), "[%s]GetService failed. Please check 'ps -A | grep OspAppService'!", GetLastResult());
265         SysTryReturn(NID_APP, pMgr != null, E_SUCCESS, E_SUCCESS, "[E_SYSTEM] fatal error. Please check 'ps -A | grep osp-app-service'!", GetLastResult());
266         pMgr->InitEventListener(this);
267
268         return E_SUCCESS;
269 }
270
271 _AppManagerImpl*
272 _AppManagerImpl::GetInstance(void)
273 {
274         return AppManager::GetInstance()->__pAppManagerImpl;
275 }
276
277 _ConditionManagerProxy*
278 _AppManagerImpl::GetConditionManagerProxy(void)
279 {
280         if (__pConditionManager == null)
281         {
282                 __pConditionManager = new (std::nothrow) _ConditionManagerProxy;
283                 SysAssert(__pConditionManager != null);
284
285                 result r = __pConditionManager->Construct();
286                 SysAssertf(r == E_SUCCESS, "__pConditionManager->Construct() faliied [%s].", GetErrorMessage(r));
287         }
288
289         return __pConditionManager;
290 }
291
292 AppControl*
293 _AppManagerImpl::FindAppControlN(const AppId& aId, const String& oId)
294 {
295         _AppControlRegistry* pRegs = _AppControlRegistry::GetInstance();
296
297         AppControl* pAc = null;
298
299         pAc = pRegs->GetNativeAppControlN(aId, oId);
300         if (pAc != null)
301         {
302                 SetLastResult(E_SUCCESS);
303                 return pAc;
304         }
305
306         pAc = pRegs->GetAliasAppControlN(aId, oId);
307         if (pAc != null)
308         {
309                 SetLastResult(E_SUCCESS);
310                 return pAc;
311         }
312
313         pAc = pRegs->GetAppControlN(aId, oId);
314
315         SysTryReturn(NID_APP, pAc != null, null, E_OBJ_NOT_FOUND, "[%s] No matching AppControl instance found (%ls, %ls).",
316                                  GetErrorMessage(E_OBJ_NOT_FOUND), aId.GetPointer(), oId.GetPointer());
317         SetLastResult(E_SUCCESS);
318         return pAc;
319 }
320
321 IList*
322 _AppManagerImpl::FindAppControlsN(const String* pOperationId, const String* pCategory, const String* pDataType,
323                                                                   const String* pUriScheme)
324 {
325         SysTryReturn(NID_APP, !(pOperationId == null && pCategory == null && pUriScheme == null && pDataType == null), null,
326                                  E_INVALID_ARG, "[%s] At least one parameter should not be null.", GetErrorMessage(E_INVALID_ARG));
327
328         String mimeType;
329         const String* pMimeType = pDataType;
330
331         if (pDataType)
332         {
333                 if ((*pDataType)[0] == L'.')
334                 {
335                         SysLog(NID_APP, "Extension to MIME conversion for %ls", pDataType->GetPointer());
336
337                         String ext;
338                         pDataType->SubString(1, ext);
339
340                         result r = _AppControlManager::GetMimeFromExt(ext, mimeType);
341
342                         SysTryReturn(NID_APP, !IsFailed(r), null, r, "[%s] MIME type conversion failure for %ls.", GetErrorMessage(r), ext.GetPointer());
343
344                         pMimeType = &mimeType;
345
346                         SysLog(NID_APP, "Conversion : %ls -> %ls.", pDataType->GetPointer(), pMimeType->GetPointer());
347                 }
348         }
349
350         if (pUriScheme)
351         {
352                 SysTryReturn(NID_APP, !(pUriScheme->IsEmpty()), null, E_INVALID_FORMAT, "[%s] The specified URI scheme is invalid.",
353                                          GetErrorMessage(E_INVALID_FORMAT));
354         }
355
356         ArrayList* pRetArg = null;
357         pRetArg = new (std::nothrow) ArrayList();
358         SysTryReturn(NID_APP, pRetArg != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
359                                  GetErrorMessage(E_OUT_OF_MEMORY));
360
361         pRetArg->Construct();
362
363         _AppControlRegistry* pRegs = _AppControlRegistry::GetInstance();
364
365         pRetArg = pRegs->FindAppControlListN(pOperationId, pUriScheme, pMimeType, pCategory);
366
367         if ((pRetArg == null) || (pRetArg->GetCount() == 0))
368         {
369                 delete pRetArg;
370                 pRetArg = null;
371                 SetLastResult(E_OBJ_NOT_FOUND);
372                 return null;
373         }
374
375         SetLastResult(E_SUCCESS);
376         SysLog(NID_APP, "Found %d matching AppControls.", pRetArg->GetCount());
377
378         return pRetArg;
379 }
380
381
382 result
383 _AppManagerImpl::StartAppControl(const String& uri, const String* pOperationId, const String* pDataType,
384                                                                  IAppControlListener* pListener)
385 {
386         return StartAppControl(pOperationId, null, pDataType, &uri, null, pListener);
387 }
388
389
390 result
391 _AppManagerImpl::StartAppControl(const String* pOperationId, const String* pCategory, const String* pDataType,
392                                                                  const String* pUri, const IList* pDataList, IAppControlListener* pListener)
393 {
394         SysTryReturnResult(NID_APP, !(pOperationId == null && pUri == null && pCategory == null && pDataType == null), E_INVALID_ARG,
395                                                 "At least one of the specified argument must not be null.");
396         if (pDataList != null)
397         {
398                 int argSize = 0;
399                 argSize = GetTotalSize(*pDataList);
400
401                 SysLog(NID_APP, "Argument count = %d, size = %d", pDataList->GetCount(), argSize);
402
403                 SysTryReturnResult(NID_APP, argSize <= MAX_APPCONTROL_ARGUMENT, E_MAX_EXCEEDED,
404                                                   "The size of pDataList exceeded the limit(%d).",
405                                                   MAX_APPCONTROL_ARGUMENT);
406         }
407
408         String operation = (pOperationId) ? *pOperationId : TIZEN_OPERATION_MAIN;
409
410         std::unique_ptr<bundle, BundleDeleter> pBundle(bundle_create());
411         SysTryReturnResult(NID_APP, pBundle.get(), E_OUT_OF_MEMORY, "Bundle creation failure.");
412
413         _AppMessageImpl::SetOperation(pBundle.get(), operation);
414
415         if (pUri)
416         {
417                 _AppMessageImpl::SetUri(pBundle.get(), *pUri);
418         }
419
420         if (pDataType)
421         {
422                 String mimeType = *pDataType;
423
424                 if ((*pDataType)[0] == L'.')
425                 {
426                         SysLog(NID_APP, "Extension to MIME conversion for %ls", pDataType->GetPointer());
427
428 #if 0
429                         String ext;
430                         pDataType->SubString(1, ext);
431
432                         result r = _AppControlManager::GetMimeFromExt(ext, mimeType);
433
434                         SysTryReturn(NID_APP, !IsFailed(r), null, r, "[%s] MIME type conversion failure for %ls.", GetErrorMessage(r), ext.GetPointer());
435
436                         pMimeType = &mimeType;
437
438                         SysLog(NID_APP, "Conversion : %ls -> %ls.", pDataType->GetPointer(), pMimeType->GetPointer());
439 #endif
440                 }
441
442                 _AppMessageImpl::SetMime(pBundle.get(), mimeType);
443         }
444
445         if (pCategory)
446         {
447                 _AppMessageImpl::SetCategory(pBundle.get(), *pCategory);
448         }
449
450         return _AppControlImpl::StartImplicit(pBundle.get(), pDataList, pListener);
451 }
452
453
454 SqlDataControl*
455 _AppManagerImpl::GetSqlDataControlN(const String& providerId)
456 {
457         SqlDataControl* pDc = null;
458         String type(L"Sql");
459         String* pAppId = null;
460         String* pAccess = null;
461         String appId;
462
463         // XXX: Need _NativeDataControlRegistry for SLP native app ?
464         // Try to searach SLP data control.
465 //      _NativeDataControlRegistry* pReg = _NativeDataControlRegistry::GetInstance(); // singleton
466 //      pDc = pReg->GetNativeSqlDataControlN(providerId);
467 //      if (pDc != null)
468 //      {
469 //              return pDc;
470 //      }
471
472         std::unique_ptr <IList, AllElementsDeleter> pList(_PackageManagerImpl::GetInstance()->GetDataControlInfoN(providerId, type));
473         SysTryReturn(NID_APP, pList != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The data control provider does not exist.");
474
475         pAppId = dynamic_cast< String* >(pList->GetAt(0));
476         SysTryReturn(NID_APP, pAppId != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
477         pAccess = dynamic_cast< String* >(pList->GetAt(1));
478         SysTryReturn(NID_APP, pAccess != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
479         pAccess->ToLower();
480
481         if (pAppId->StartsWith(L"org.tizen.", 0))
482         {
483                 std::unique_ptr<StringTokenizer> pStrTok(new (std::nothrow) StringTokenizer(*pAppId, L'.'));
484                 SysTryReturn(NID_APP, pStrTok != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
485                 for (int i = 0; i < 3; ++i)
486                 {
487                         pStrTok->GetNextToken(appId);
488                 }
489
490                 appId[_MAX_PACKAGE_ID_LENGTH] = L'.';
491         }
492         else
493         {
494                 appId.Append(*pAppId);
495         }
496
497         pDc = _SqlDataControlImpl::CreateSqlDataControl(appId, providerId, *pAccess);
498         SysTryReturn(NID_APP, pDc != null, null, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
499
500         return pDc;
501 }
502
503 MapDataControl*
504 _AppManagerImpl::GetMapDataControlN(const String& providerId)
505 {
506         MapDataControl* pDc = null;
507         String type(L"Map");
508         String* pAppId = null;
509         String* pAccess = null;
510         String appId;
511
512         // XXX: Need _NativeDataControlRegistry for SLP native app ?
513         // Try to searach SLP data control.
514 //      _NativeDataControlRegistry* pReg = _NativeDataControlRegistry::GetInstance(); // singleton
515 //      pDc = pReg->GetNativeMapDataControlN(providerId);
516 //      if (pDc != null)
517 //      {
518 //              return pDc;
519 //      }
520
521         std::unique_ptr <IList, AllElementsDeleter> pList(_PackageManagerImpl::GetInstance()->GetDataControlInfoN(providerId, type));
522         SysTryReturn(NID_APP, pList != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The data control provider does not exist.");
523
524         pAppId = dynamic_cast< String* >(pList->GetAt(0));
525         SysTryReturn(NID_APP, pAppId != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
526         pAccess = dynamic_cast< String* >(pList->GetAt(1));
527         SysTryReturn(NID_APP, pAccess != null, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
528         pAccess->ToLower();
529
530         if (pAppId->StartsWith(L"org.tizen.", 0))
531         {
532                 std::unique_ptr<StringTokenizer> pStrTok( new (std::nothrow) StringTokenizer(*pAppId, L'.'));
533                 SysTryReturn(NID_APP, pStrTok != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
534                 for (int i = 0; i < 3; ++i)
535                 {
536                         pStrTok->GetNextToken(appId);
537                 }
538
539                 appId[_MAX_PACKAGE_ID_LENGTH] = L'.';
540         }
541         else
542         {
543                 appId.Append(*pAppId);
544         }
545
546         pDc = _MapDataControlImpl::CreateMapDataControl(appId, providerId, *pAccess);
547         SysTryReturn(NID_APP, pDc != null, null, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
548
549         return pDc;
550 }
551
552 result
553 _AppManagerImpl::GetAppRootPath(const AppId& appId, String& appRootPath)
554 {
555         String pkgId = PackageManager::GetPackageIdByAppId(appId);
556         SysTryReturnResult(NID_APP, pkgId.IsEmpty() == false, E_APP_NOT_INSTALLED,
557                         "The application is not installed. (appId: %ls)", appId.GetPointer());
558
559         _PackageManagerImpl* pPkgMgr = _PackageManagerImpl::GetInstance();
560         SysTryReturnResult(NID_APP, pPkgMgr != null, E_SYSTEM,
561                         "Failed to get _PackageManagerImpl instance.");
562
563         std::unique_ptr< PackageInfo >pPkgInfo(pPkgMgr->GetPackageInfoN(pkgId));
564         SysTryReturnResult(NID_APP, pPkgInfo != null, E_APP_NOT_INSTALLED,
565                         "The application is not installed. (appId: %ls)", appId.GetPointer());
566
567         _PackageInfoImpl* pPkgInfoImpl = _PackageInfoImpl::GetInstance(pPkgInfo.get());
568         SysTryReturnResult(NID_APP, pPkgInfoImpl != null, E_SYSTEM,
569                         "Failed to get _PackageInfoImpl instance.");
570
571         appRootPath = pPkgInfoImpl->GetAppRootPath();
572         appRootPath.Append(L"/");
573
574         return E_SUCCESS;
575 }
576
577 result
578 _AppManagerImpl::LaunchApplication(const String& appId, const IList* pArguments, AppManager::LaunchOption option)
579 {
580         SysTryReturnResult(NID_APP, !appId.IsEmpty(), E_INVALID_ARG, "The appid is empty.");
581         SysTryReturnResult(NID_APP, _Aul::IsInstalled(appId) == true, E_OBJ_NOT_FOUND,
582                                            "The target application(%ls) is not installed.", appId.GetPointer());
583 //      SysTryReturnResult(NID_APP,
584 //                                        appId.GetLength() <= WIDGET_APP_MAX_APPID_LENGTH, E_MAX_EXCEEDED,
585 //                                        "The length of appid exceeded the limit(%d).",
586 //                                        WIDGET_APP_MAX_APPID_LENGTH);
587
588         AppControl* pAc = _AppControlRegistry::GetInstance()->GetAppControlN(appId, TIZEN_OPERATION_MAIN);
589         SysTryReturnResult(NID_APP, pAc != null, E_OBJ_NOT_FOUND, "The target application (%ls) is not found.", appId.GetPointer());
590
591         if (pArguments)
592         {
593                 int argSize = 0;
594                 argSize = GetTotalSize(*pArguments);
595
596                 SysLog(NID_APP, "Argument count = %d, size = %d", pArguments->GetCount(), argSize);
597
598                 SysTryReturnResult(NID_APP, argSize <= MAX_APPCONTROL_ARGUMENT, E_MAX_EXCEEDED,
599                                                   "The size of pDataList exceeded the limit(%d).",
600                                                   MAX_APPCONTROL_ARGUMENT);
601         }
602
603         result r = pAc->Start(pArguments, null);
604
605         SysLog(NID_APP, "[%s] Launching %ls finished.", GetErrorMessage(r), appId.GetPointer());
606         return r;
607 }
608
609
610 result
611 _AppManagerImpl::LaunchApplication(const String& appId, AppManager::LaunchOption option)
612 {
613         SysTryReturnResult(NID_APP, !appId.IsEmpty(), E_APP_NOT_INSTALLED, "The appid is empty.");
614
615         std::unique_ptr<char[]> pName(_StringConverter::CopyToCharArrayN(appId));
616
617         int ret = aul_open_app(pName.get());
618
619         if (ret > 0)
620         {
621                 SysLog(NID_APP, "Launching %ls successful.", appId.GetPointer());
622                 return E_SUCCESS;
623         }
624
625         // failure
626         SysTryReturnResult(NID_APP, _Aul::IsInstalled(appId) == true, E_APP_NOT_INSTALLED,
627                                            "The target application(%ls) is not installed.", appId.GetPointer());
628
629         result r = E_SYSTEM;
630         switch (ret)
631         {
632         case AUL_R_EINVAL:
633                 r = E_APP_NOT_INSTALLED;
634                 break;
635         case AUL_R_OK:
636                 // r = E_SUCCESS;
637                 // never reach here
638                 break;
639         default:
640                 break;
641         }
642
643         SysLog(NID_APP, "[%s] Launching %ls failed.", GetErrorMessage(r), appId.GetPointer());
644         return r;
645 }
646
647
648 result
649 _AppManagerImpl::TerminateApplication(const AppId& appId, const String* pExecutableName)
650 {
651         result r = E_SUCCESS;
652
653         _IAppManager* pMgr = _AppManagerProxy::GetService();
654         if (pMgr)
655         {
656                 const String& name = (pExecutableName) ? *pExecutableName : _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(appId);
657                 r = pMgr->TerminateApplication(appId, name);
658         }
659
660         return r;
661 }
662
663
664 static int
665 TerminateIterFnCb(const aul_app_info* pAppInfo, void* pData)
666 {
667         const char* pStr = static_cast<const char*>(pData);
668
669         if (pStr && strncmp(pStr, pAppInfo->pkg_name, 10) == 0)
670         {
671                 aul_terminate_pid(pAppInfo->pid);
672                 SysLog(NID_APP, "%s(%d) is terminated.", pAppInfo->pkg_name, pAppInfo->pid);
673         }
674         return 0;
675 }
676
677 result
678 _AppManagerImpl::TerminateApplications(const PackageId& packageId)
679 {
680         result r = E_SUCCESS;
681
682         std::unique_ptr<char[]> pPackage(_StringConverter::CopyToCharArrayN(packageId));
683         aul_app_get_running_app_info(TerminateIterFnCb, static_cast<void*>(pPackage.get()));
684
685         SysLog(NID_APP, "%ls terminated.", packageId.GetPointer());
686         return E_SUCCESS;
687 }
688
689 bool
690 _AppManagerImpl::IsRunning(const AppId& appId, const String* pExecutableName) const
691 {
692         bool b = false;
693
694         _IAppManager* pMgr = _AppManagerProxy::GetService();
695         if (pMgr)
696         {
697                 const String& name = (pExecutableName) ? *pExecutableName : _PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(appId);
698                 b = pMgr->IsRunning(appId, name);
699         }
700
701         return b;
702 }
703
704 static int
705 AulAppInfoIterFnCb(const aul_app_info* pAppInfo, void* pData)
706 {
707         ArrayList* pList = static_cast<ArrayList*>(pData);
708         if (pList && pAppInfo && pAppInfo->appid)
709         {
710                 pList->Add(*new (std::nothrow) String(pAppInfo->appid));
711         }
712
713         return 0;
714 }
715
716 IList*
717 _AppManagerImpl::GetRunningAppListN(void) const
718 {
719         ArrayList* pRunningAppList = new (std::nothrow) ArrayList();
720         SysTryReturn(NID_APP, pRunningAppList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
721                                  GetErrorMessage(E_OUT_OF_MEMORY));
722         pRunningAppList->Construct();
723
724         int ret = aul_app_get_running_app_info(AulAppInfoIterFnCb, reinterpret_cast<void*>(pRunningAppList));
725         SysTryLog(NID_APP, ret == AUL_R_OK, "Getting running list failed.");
726
727         // according to the doxygen, GetRunningAppListN() does not return null pointer for no object
728         return pRunningAppList;
729 }
730
731
732 result
733 _AppManagerImpl::RegisterAppLaunch(const AppId& appId, const String& executableName, const String& condition, const IList* pArguments,
734                                                                    AppManager::LaunchOption option)
735 {
736         _ConditionManagerProxy* pProxy = GetConditionManagerProxy();
737         SysTryReturnResult(NID_APP, null != pProxy, E_INVALID_STATE, "ConditionManager instance must not be null.");
738
739         return pProxy->RegisterAppLaunch(appId, executableName, condition, pArguments, option);
740 }
741
742 result
743 _AppManagerImpl::UnregisterAppLaunch(const AppId& appId, const String& executableName, const String* pCondition)
744 {
745         _ConditionManagerProxy* pProxy = GetConditionManagerProxy();
746         SysTryReturnResult(NID_APP, null != pProxy, E_INVALID_STATE, "ConditionManager instance must not be null.");
747
748         if (pCondition)
749         {
750                 SysTryReturnResult(NID_APP,
751                                                   !pCondition->IsEmpty() && pCondition->GetLength() < MAX_CONDITION_LENGTH, E_OBJ_NOT_FOUND,
752                                                   "No such a condition.");
753         }
754
755         return pProxy->UnregisterAppLaunch(appId, executableName, pCondition);
756 }
757
758 bool
759 _AppManagerImpl::IsAppLaunchRegistered(const AppId& appId, const String &executableName, const String* pCondition)
760 {
761         _ConditionManagerProxy* pProxy = GetConditionManagerProxy();
762         SysTryReturn(NID_APP, null != pProxy, false, E_INVALID_STATE, "[%s] ConditionManager instance must not be null.",
763                                  GetErrorMessage(E_INVALID_STATE));
764
765         ClearLastResult();
766         return pProxy->IsAppLaunchRegistered(appId, executableName, pCondition);
767 }
768
769 result
770 _AppManagerImpl::SetEventListener(_AppEvent appEvent, Tizen::Base::Runtime::IEventListener* pListener)
771 {
772         return _AppImpl::GetInstance()->SetListener(appEvent, pListener);
773 }
774
775 result
776 _AppManagerImpl::OnServiceEventReceived(int clientId, const _AppManagerEventArg& arg)
777 {
778         SysLog(NID_APP, "appId:%ls, appType:0x%x", arg.GetAppId().GetPointer(), arg.GetAppType());
779
780         _AppManagerEventArg* pArg = new (std::nothrow)_AppManagerEventArg(arg);
781         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
782                                            GetErrorMessage(E_OUT_OF_MEMORY));
783         __appManagerEvent.FireAsync(*pArg);
784         return E_SUCCESS;
785 }
786
787 result
788 _AppManagerImpl::OnTerminateApplicationRequested(int clientId)
789 {
790         SysLog(NID_APP, "");
791
792         return E_SUCCESS;
793 }
794
795 result
796 _AppManagerImpl::AddEventListener(_IAppManagerEventListener& listener)
797 {
798         _IAppManager* pMgr = _AppManagerProxy::GetService();
799         SysTryReturnResult(NID_APP, pMgr != null, E_INVALID_STATE, "");
800
801         result r = __appManagerEvent.AddListener(listener);
802         SysTryReturn(NID_APP, IsFailed(r) == false, r, r, "[%s]", GetErrorMessage(r));
803
804         __eventListenerCount++;
805         SysLog(NID_APP, "registered event listener(s) # %d", __eventListenerCount);
806
807         if( __eventListenerCount > 1)
808         {
809                 return E_SUCCESS;
810         }
811
812         return pMgr->AddEventListener(-1);
813 }
814
815 result
816 _AppManagerImpl::RemoveEventListener(_IAppManagerEventListener& listener)
817 {
818         _IAppManager* pMgr = _AppManagerProxy::GetService();
819         SysTryReturnResult(NID_APP, pMgr != null, E_INVALID_STATE, "");
820
821         result r = __appManagerEvent.RemoveListener(listener);
822         SysTryReturn(NID_APP, IsFailed(r) == false, r, r, "[%s]", GetErrorMessage(r));
823
824         __eventListenerCount--;
825         SysLog(NID_APP, "registered event listener(s) # %d", __eventListenerCount);
826
827         if (__eventListenerCount == 0)
828         {
829                 return pMgr->RemoveEventListener(-1);
830         }
831
832         return E_SUCCESS;
833 }
834
835 // input ("qik37po9ck.BasicApp") => output {"qik37po9ck", "BasicApp"}
836 result
837 _AppManagerImpl::ExtractValues(AppId inAppId, AppId& outAppId, String& outExecutableName)
838 {
839         const int APP_ID_LEN = 10;
840
841         if (inAppId.GetLength() > APP_ID_LEN)
842         {
843                 result r = inAppId.SubString(APP_ID_LEN + 1, inAppId.GetLength() - (APP_ID_LEN + 1), outExecutableName);
844                 SysTryReturnResult(NID_APP, !IsFailed(r), E_INVALID_ARG, "invalid AppId(%ls)", inAppId.GetPointer());
845
846                 r = inAppId.SubString(0, APP_ID_LEN, outAppId);
847                 SysTryReturnResult(NID_APP, !IsFailed(r), E_INVALID_ARG, "invalid AppId(%ls)", inAppId.GetPointer());
848
849                 SysLog(NID_APP, "appId(%ls), executableName(%ls)", outAppId.GetPointer(), outExecutableName.GetPointer());
850                 return E_SUCCESS;
851         }
852         return E_SYSTEM;
853 }
854
855 _LibraryImpl&
856 _AppManagerImpl::GetUiLibraryImpl(void)
857 {
858         if (__pUiLibrary == null)
859         {
860                 __pUiLibrary = new (std::nothrow) _LibraryImpl;
861                 SysAssertf(__pUiLibrary != null, "_LibraryImpl allocation failure.");
862
863                 result r = __pUiLibrary->Construct(OSP_UI_SONAME);
864                 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
865         }
866
867         return *__pUiLibrary;
868 }
869
870 _LibraryImpl&
871 _AppManagerImpl::GetEcoreXLibraryImpl(void)
872 {
873         if (__pEcoreXLibrary == null)
874         {
875                 __pEcoreXLibrary = new (std::nothrow) _LibraryImpl;
876                 SysAssertf(__pEcoreXLibrary != null, "_LibraryImpl allocation failure.");
877
878                 result r = __pEcoreXLibrary->Construct(OSP_ECORE_X_SONAME);
879                 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
880         }
881         return *__pEcoreXLibrary;
882 }
883
884 _LibraryImpl&
885 _AppManagerImpl::GetEcoreLibraryImpl(void)
886 {
887         if (__pEcoreLibrary == null)
888         {
889                 __pEcoreLibrary = new (std::nothrow) _LibraryImpl;
890                 SysAssertf(__pEcoreLibrary != null, "_LibraryImpl allocation failure.");
891
892                 result r = __pEcoreLibrary->Construct(OSP_ECORE_SONAME);
893                 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
894         }
895         return *__pEcoreLibrary;
896 }
897
898 _LibraryImpl&
899 _AppManagerImpl::GetX11LibraryImpl(void)
900 {
901         if (__pX11Library == null)
902         {
903                 __pX11Library = new (std::nothrow) _LibraryImpl;
904                 SysAssertf(__pX11Library != null, "_LibraryImpl allocation failure.");
905
906                 result r = __pX11Library->Construct(OSP_X11_SONAME);
907                 SysAssertf(r == E_SUCCESS, "Dynamic loading error : %s.", GetErrorMessage(r));
908         }
909         return *__pX11Library;
910 }
911
912 void
913 _AppManagerImpl::FireActiveAppEvent(unsigned int xid, int pid, char* pAppName)
914 {
915         static int oldPid = 0;
916         if (oldPid != pid)
917         {
918                 oldPid = pid;
919                 std::unique_ptr<IEnumeratorT<Tizen::App::IActiveAppEventListener* > > pEnum(__activeAppEventListenerList.GetEnumeratorN());
920                 if (pEnum.get())
921                 {
922                         while (pEnum->MoveNext() == E_SUCCESS)
923                         {
924                                 Tizen::App::IActiveAppEventListener* pListener = null;
925                                 pEnum->GetCurrent(pListener);
926                                 if (pListener)
927                                 {
928                                         char pkgname[255] = {0, };
929                                         aul_app_get_pkgname_bypid(pid, pkgname, 255);
930                                         // TODO: Translate it to package name --> AppId
931                                         pListener->OnActiveAppChanged(AppId(pkgname));
932                                 }
933                         }
934                 }
935         }
936 }
937
938 unsigned int
939 _AppManagerImpl::GetActiveWindow(void)
940 {
941         if (p_ecore_x_window_root_list == null)
942         {
943                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
944                 p_ecore_x_window_root_list = reinterpret_cast<Ecore_X_Window*(*)(int* num_ret)>(lib.GetProcAddress(L"ecore_x_window_root_list"));
945                 SysTryReturnResult(NID_APP, p_ecore_x_window_root_list != null, 0,
946                                                    "A system error has been occurred. Failed to get p_ecore_x_window_root_list.");
947         }
948         if (p_ecore_x_atom_get == null)
949         {
950                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
951                 p_ecore_x_atom_get = reinterpret_cast<Ecore_X_Atom(*)(const char* name)>(lib.GetProcAddress(L"ecore_x_atom_get"));
952                 SysTryReturnResult(NID_APP, p_ecore_x_atom_get != null, 0,
953                                                    "A system error has been occurred. Failed to get ecore_x_atom_get.");
954         }
955         if (p_ecore_x_window_prop_window_get == null)
956         {
957                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
958                 p_ecore_x_window_prop_window_get = reinterpret_cast<int(*)(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Window* val, unsigned int len)>(lib.GetProcAddress(L"ecore_x_window_prop_window_get"));
959                 SysTryReturnResult(NID_APP, p_ecore_x_window_prop_window_get != null, EINA_FALSE,
960                                                    "A system error has been occurred. Failed to get ecore_x_window_prop_window_get.");
961         }
962
963         Ecore_X_Window* pRoots = null;
964         int num = 0;
965
966         pRoots = p_ecore_x_window_root_list(&num);
967         Ecore_X_Atom activeAtom = p_ecore_x_atom_get("_NET_ACTIVE_WINDOW");
968
969         Ecore_X_Window activeWin = 0;
970         p_ecore_x_window_prop_window_get(pRoots[0], activeAtom, &activeWin, 1);
971
972         return activeWin;
973 }
974
975 int
976 _AppManagerImpl::GetProcessId(unsigned int window)
977 {
978         if (p_ecore_x_netwm_pid_get == null)
979         {
980                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
981                 p_ecore_x_netwm_pid_get = reinterpret_cast<Eina_Bool(*)(Ecore_X_Window win, int* pid)>(lib.GetProcAddress(L"ecore_x_netwm_pid_get"));
982                 SysTryReturnResult(NID_APP, p_ecore_x_netwm_pid_get != null, EINA_FALSE,
983                                                    "A system error has been occurred. Failed to get ecore_x_netwm_pid_get.");
984         }
985
986         int pid = 0;
987         p_ecore_x_netwm_pid_get(window, &pid);
988
989         return pid;
990 }
991
992 result
993 _AppManagerImpl::AddActiveAppEventListener(IActiveAppEventListener& listener)
994 {
995         if (p_ecore_x_window_root_list == null)
996         {
997                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
998                 p_ecore_x_window_root_list = reinterpret_cast<Ecore_X_Window*(*)(int* num_ret)>(lib.GetProcAddress(L"ecore_x_window_root_list"));
999                 SysTryReturnResult(NID_APP, p_ecore_x_window_root_list != null, EINA_FALSE,
1000                                                    "A system error has been occurred. Failed to get p_ecore_x_window_root_list.");
1001         }
1002         if (p_ECORE_X_EVENT_WINDOW_PROPERTY == null)
1003         {
1004                 _LibraryImpl& lib = _AppManagerImpl::GetEcoreXLibraryImpl();
1005                 p_ECORE_X_EVENT_WINDOW_PROPERTY = reinterpret_cast<int*>(lib.GetProcAddress(L"ECORE_X_EVENT_WINDOW_PROPERTY"));
1006                 SysTryReturnResult(NID_APP, p_ECORE_X_EVENT_WINDOW_PROPERTY != null, EINA_FALSE,
1007                                                    "A system error has been occurred. Failed to get p_ECORE_X_EVENT_WINDOW_PROPERTY.");
1008         }
1009         if (p_XOpenDisplay == null)
1010         {
1011                 _LibraryImpl& lib = GetX11LibraryImpl();
1012                 p_XOpenDisplay = reinterpret_cast<Display*(*)(_Xconst char* display_name)>(lib.GetProcAddress(L"XOpenDisplay"));
1013                 SysTryReturnResult(NID_APP, p_XOpenDisplay != null, EINA_FALSE,
1014                                                    "A system error has been occurred. Failed to get p_XOpenDisplay.");
1015         }
1016         if (p_XSelectInput == null)
1017         {
1018                 _LibraryImpl& lib = GetX11LibraryImpl();
1019                 p_XSelectInput = reinterpret_cast<int(*)(Display* display, Window w, long event_mask)>(lib.GetProcAddress(L"XSelectInput"));
1020                 SysTryReturnResult(NID_APP, p_XSelectInput != null, EINA_FALSE,
1021                                                    "A system error has been occurred. Failed to get p_XSelectInput.");
1022         }
1023         if (p_ecore_event_handler_add == null)
1024         {
1025                 _LibraryImpl& lib = GetEcoreLibraryImpl();
1026                 p_ecore_event_handler_add = reinterpret_cast<Ecore_Event_Handler*(*)(int type, Ecore_Event_Handler_Cb func, const void* data)>(lib.GetProcAddress(L"ecore_event_handler_add"));
1027                 SysTryReturnResult(NID_APP, p_ecore_event_handler_add != null, EINA_FALSE,
1028                                                    "A system error has been occurred. Failed to get p_ecore_event_handler_add.");
1029         }
1030
1031         bool alreadyExist = __activeAppEventListenerList.Contains(&listener);
1032         SysTryReturnResult(NID_APP, !alreadyExist, E_OBJ_ALREADY_EXIST, "The event listener already exist.");
1033         result r = __activeAppEventListenerList.Add(&listener);
1034         SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1035
1036         Ecore_X_Window* pRoots = null;
1037         int num = 0;
1038         pRoots = p_ecore_x_window_root_list(&num);
1039
1040         for (int i = 0; i < num; i++)
1041         {
1042                 Display* pDisplay = p_XOpenDisplay(NULL);
1043                 p_XSelectInput(pDisplay, pRoots[i], PropertyChangeMask);
1044         }
1045
1046         if (!pWindowPropertyChanged)
1047         {
1048                 pWindowPropertyChanged = p_ecore_event_handler_add(*p_ECORE_X_EVENT_WINDOW_PROPERTY, OnPropertyChanged, (void*) this);
1049                 SysTryReturnResult(NID_APP, pWindowPropertyChanged, E_SYSTEM, "A system error has been occurred.");
1050         }
1051
1052         return r;
1053 }
1054
1055 result
1056 _AppManagerImpl::RemoveActiveAppEventListener(IActiveAppEventListener& listener)
1057 {
1058         if (p_ecore_event_handler_del == null)
1059         {
1060                 _LibraryImpl& lib = GetEcoreLibraryImpl();
1061                 p_ecore_event_handler_del = reinterpret_cast<void*(*)(Ecore_Event_Handler* event_handler)>(lib.GetProcAddress(L"ecore_event_handler_del"));
1062                 SysTryReturnResult(NID_APP, p_ecore_event_handler_del != null, E_SYSTEM,
1063                                                    "A system error has been occurred. Failed to get p_ecore_event_handler_del.");
1064         }
1065
1066         result r = __activeAppEventListenerList.Remove(&listener);
1067         SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1068
1069         if (__activeAppEventListenerList.GetCount() == 0)
1070         {
1071                 p_ecore_event_handler_del(pWindowPropertyChanged);
1072                 pWindowPropertyChanged = null;
1073         }
1074
1075         return r;
1076 }
1077
1078 result
1079 _AppManagerImpl::GetActiveApp(AppId& appId)
1080 {
1081         unsigned int windowId = GetActiveWindow();
1082         int processId = GetProcessId(windowId);
1083         char pkgname[255] = {0, };
1084         aul_app_get_pkgname_bypid(processId, pkgname, 255);
1085         // TODO: Translate it to package name --> AppId
1086         appId = pkgname;
1087         return E_SUCCESS;
1088 }
1089
1090 }} // Tizen::App