2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FApp_ContextManager.cpp
20 * @brief This is the implementation for the _ContextManager.cpp class.
28 #include <FBaseColArrayList.h>
29 #include <FBaseSysLog.h>
32 #include <FBase_StringConverter.h>
34 #include <FApp_AppManagerImpl.h>
35 #include <FAppPkg_PackageManagerImpl.h>
37 #include "FApp_ContextManager.h"
38 #include "FIo_MmcStorageManagerService.h"
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::Io;
44 namespace Tizen { namespace App {
46 const unsigned long CONTEXT_MANAGER_MAGIC = 0x585443; // 'C' 'T' 'X'
48 ///////////////////////////////////////////////////
50 ///////////////////////////////////////////////////
51 _AppContext::_AppContext(const String& appId, const String& executableName, _AppType appType, int pid, int ipcClientId, bool isSystemService)
53 , executableName(executableName)
56 , ipcClientId(ipcClientId)
57 , uiState(APP_UI_STATE_BACKGROUND)
59 , isSystemService(isSystemService)
64 _AppContext::ToString(void) const
66 Tizen::Base::String ret;
67 ret.Format(1024, L"%ls.%ls(pid:%d)", appId.GetPointer(), executableName.GetPointer(), pId);
72 ///////////////////////////////////////////////////
74 ///////////////////////////////////////////////////
75 _ContextManager::_ContextManager()
76 : __magic(CONTEXT_MANAGER_MAGIC)
77 , __pEventListener(null)
82 _ContextManager::~_ContextManager()
87 _ContextManager::Construct(void)
90 __errorProneAppIds.Construct();
91 _Aul::SetOnAppTerminatedCb(OnAppTerminate, this);
97 _ContextManager::SetEventListener(_IContextManagerEventListener& listener)
99 __pEventListener = &listener;
103 _ContextManager::Register(const PackageId& pkgId, const String& executableName, _AppType appType, int pid, int ipcClientId, bool isSystemService )
105 if( __appContexts[pid] != null)
107 SysAssertf( isSystemService == true, "The application (appid:%ls, pid:%d) is registered twice.", pkgId.GetPointer(), pid);
111 _AppContext* pAppContext = new (std::nothrow) _AppContext(pkgId, executableName, appType, pid, ipcClientId, isSystemService);
113 __appContexts[pid] = pAppContext;
115 String appRoot(L"/opt/usr/apps/");
116 appRoot.Append(pkgId);
117 String compatFile(appRoot);
118 compatFile.Append(L"/info/compat.info");
120 bool ospCompat = File::IsFileExist(compatFile);
121 if (GetLastResult() == E_SUCCESS && ospCompat == true)
123 _MmcStorageManagerService* pMmcMgr = _MmcStorageManagerService::GetInstance();
124 String* pAppRoot = new (std::nothrow) String(appRoot);
127 result r = appRoot.LastIndexOf(L'/', appRoot.GetLength() - 1, index);
128 SysTryLog(NID_IO, !IsFailed(r), "[E_SYSTEM] The method cannot proceed due to a severe system error.");
131 r = appRoot.SubString(++index, pkgId);
132 SysTryLog(NID_IO, !IsFailed(r), "[E_SYSTEM] The method cannot proceed due to a severe system error.");
134 //pMmcMgr->__appList[pid] = pAppRoot;
135 char* pKey = _StringConverter::CopyToCharArrayN(pkgId);
136 std::string key(pKey);
138 pMmcMgr->__appList.insert(_MmcStorageManagerService::_AppListPair(key, pAppRoot));
139 SysLog(NID_APP, "OSP compatible application (%ls) is registered.", pkgId.GetPointer());
142 // ==== set oom policy for ServiceApp
143 result r = E_SUCCESS;
144 switch (GetOomAppType(pkgId, pid))
146 case OOM_APP_TYPE_SYSTEM:
148 case OOM_APP_TYPE_LAUNCHING:
150 case OOM_APP_TYPE_FOREGROUND_HIGH:
152 case OOM_APP_TYPE_SERVICE_HIGH:
154 case OOM_APP_TYPE_FOREGROUND:
156 case OOM_APP_TYPE_SERVICE_MID:
157 r = _Aul::SetOomAdj(pid, -7);
159 case OOM_APP_TYPE_BACKGROUND_HIGH:
161 case OOM_APP_TYPE_SERVICE_LOW:
162 r = _Aul::SetOomAdj(pid, -3);
164 case OOM_APP_TYPE_BACKGROUND:
167 SysLog(NID_APP, "Set OOM : result is %s", GetErrorMessage(r));
169 SysLog(NID_APP, "The %s (appid:%ls, pid:%d) Registered.", isSystemService ? "application":"system service", pkgId.GetPointer(), pid);
174 // see also OnAppTerminate
176 _ContextManager::Unregister(int pid)
178 _AppContext* pAppContext = __appContexts[pid];
179 SysTryReturn(NID_APP, pAppContext != null, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "Unknown pid(%d).", pid);
181 pAppContext->isRegistered = false;
182 SysLog(NID_APP, "(appid:%ls, pid:%d) Unregistered.", pAppContext->appId.GetPointer(), pid);
185 _MmcStorageManagerService* pMmcMgr = _MmcStorageManagerService::GetInstance();
186 String* pAppRoot = pMmcMgr->__appList[pid];
187 if (pAppRoot != null)
189 pMmcMgr->__appList.erase(pid);
190 SysLog(NID_APP, "OSP 2.0 application is unregistered.");
197 // event handler for _Aul::SetOnAppTerminatedCb
199 _ContextManager::OnAppTerminate(int pid, void *pData)
201 SysTryReturn(NID_APP, pData != null, -1, E_INVALID_STATE, "");
203 _ContextManager* pContextMgr = static_cast<_ContextManager*>(pData);
204 SysTryReturn(NID_APP, pContextMgr->__magic == CONTEXT_MANAGER_MAGIC, -1, E_INVALID_STATE, "Wrong magic number %x(%x)", pContextMgr->__magic, CONTEXT_MANAGER_MAGIC);
206 _AppContext* pAppContext = pContextMgr->__appContexts[pid];
208 if ( pAppContext == null)
210 // SysLog(NID_APP, "Not registered pid(%d), It means this process isn't osp app.", pid);
214 if (pAppContext->isRegistered)
216 SysLog(NID_APP, "This app is terminated abnormally.");
217 pContextMgr->AbonormalAppTerminationHanlder( pAppContext->pId, pAppContext->appId, pAppContext->executableName );
220 if (pContextMgr->__pEventListener != null )
222 pContextMgr->__pEventListener->OnApplicationTerminated(*pAppContext);
225 int res = pContextMgr->__appContexts.erase(pid);
226 SysTryCatch(NID_APP, res == 1, , E_INVALID_STATE, "[E_INVALID_STATE] __appContexts.erase(%d) returns (%d). It seems to be invalid.", pid, res);
228 SysLog(NID_APP, "app info is removed (%ls, %d)", pAppContext->executableName.GetPointer(), pid);
238 _ContextManager::AbonormalAppTerminationHanlder(int pid, const AppId& appId, const String& execName)
240 this->Unregister(pid);
242 const String& needToAutoRestartOnFailure = _Util::QueryFeatureFromPackageManager(appId, execName, L"AutoRestart");
243 if (needToAutoRestartOnFailure == "True")
245 if(!IsErrorProneApp(appId))// prevent error prone app being restarted over and over again..
247 SysLog(NID_APP, "The app is configured as AutoRestart, so It will be restarted.");
249 __errorProneAppIds.Add(appId);
251 String realId = appId + L'.' + execName;
252 _AppManagerImpl::GetInstance()->LaunchApplication(realId, null, AppManager::LAUNCH_OPTION_DEFAULT);
257 SysLog(NID_APP, "The app is configured as AutoRestart, but It won't be restarted. because it was already restarted, and terminated unexpectedly again. ");
263 _ContextManager::IsErrorProneApp(const AppId& appId) const
265 const int count = __errorProneAppIds.GetCount();
266 String errorProneAppId;
268 for (int i = 0; i < count; i ++)
270 __errorProneAppIds.GetAt(i, errorProneAppId);
271 if(errorProneAppId == appId)
281 _ContextManager::Find(const AppId& appId, const Tizen::Base::String& executableName) const
283 AppContexts::const_iterator it;
285 for (it = __appContexts.begin(); it != __appContexts.end(); it++)
287 const _AppContext* const pAppContext = (*it).second;
289 if (pAppContext != null && pAppContext->appId == appId && pAppContext->executableName == executableName)
299 _ContextManager::Find(int pid)
301 return __appContexts[pid];
305 _ContextManager::GetAppListN(Tizen::Base::Collection::ArrayList* pArray) const
307 AppContexts::const_iterator it;
310 for (it = __appContexts.begin(); it != __appContexts.end(); it++)
312 const _AppContext* const pAppContext = (*it).second;
314 if (pAppContext != null)
318 pArray->Add(pAppContext->appId);
321 logText.Append(pAppContext->appId);
322 logText.Append(L", ");
325 SysLog(NID_APP, "Total %d apps : %ls", __appContexts.size(), logText.GetPointer() );
331 _ContextManager::GetOomAppType(const AppId& appId, const int pid) const
333 _OomAppType appType = OOM_APP_TYPE_FOREGROUND;
335 // FIX_ME : will be implemented for type checking
341 _ContextManager::Dump(void) const
343 AppContexts::const_iterator it;
345 SysLog(NID_APP, "registered app count : %d", __appContexts.size());
347 for (it = __appContexts.begin(); it != __appContexts.end(); it++)
349 const _AppContext* const pAppContext = (*it).second;
350 if (pAppContext != null)
352 SysLog(NID_APP, "%ls", pAppContext->ToString().GetPointer());
360 * _ContextManager::Util
364 _ContextManager::_Util::GetExecNameFromPackageName(const String& packageName)
367 const String prefix(L"org.tizen.1234567890");
368 const int prefixLen = prefix.GetLength();
369 packageName.SubString(prefixLen, execName);
375 _ContextManager::_Util::QueryFeatureFromPackageManager(const String& appId, const String& execName, const String& feature)
377 ArrayList* pFeatureList = Tizen::App::Package::_PackageManagerImpl::GetInstance()->GetPackageAppFeatureListN(appId, execName);
378 SysTryReturn(NID_APP, pFeatureList != null, L"", E_SYSTEM, "Cannot acquire feature list.");
382 for (int i = 0; i < pFeatureList->GetCount(); i++)
384 const Tizen::App::Package::_AppFeatureInfoImpl* pInfo = static_cast<const Tizen::App::Package::_AppFeatureInfoImpl*>(pFeatureList->GetAt(i));
385 SysLog(NID_APP, "%ls, %ls", pInfo->GetName().GetPointer(), pInfo->GetValue().GetPointer());
386 if (pInfo != null && pInfo->GetName() == feature)
388 ret = pInfo->GetValue();
393 pFeatureList->RemoveAll(true);