2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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_ConditionManagerService.cpp
20 * @brief This is the implementation for the _ConditionManagerService class.
24 #include <FIoDirectory.h>
25 #include <FIoRegistry.h>
28 #include <FBaseSysLog.h>
29 #include <FIo_RegistryImpl.h>
31 #include "FApp_Types.h"
32 #include "FAppPkg_PackageManagerImpl.h"
33 #include "FApp_ConditionHandler.h"
34 #include "FApp_ConditionManagerService.h"
38 namespace Tizen { namespace App {
40 using namespace Package;
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Collection;
43 using namespace Tizen::Io;
47 const String REGISTRY_FILE_PLUGIN = L"res/app-launch-condition-handlers.ini";
48 const String REG_KEY_KEY = L"Key";
49 const String REG_KEY_FILENAME = L"Filename";
51 const String REGISTRY_FILE_OPERATIONS = L"data/app-launch-conditions.ini";
52 const String REG_KEY_APPID = L"PackageId";
53 const String REG_KEY_EXENAME = L"ExecutableName";
54 const String REG_KEY_CONDTION = L"Condition";
55 const String REG_KEY_LAUNCH_TYPE = L"LaunchType";
56 const String REG_KEY_ARG_COUNT = L"ArgCount";
57 const String REG_KEY_ARG = L"Arg";
59 const int MAX_LEN_ARG = 1024;
60 const int MAX_LEN_CONDITION = 400;
64 _ConditionManagerService::_ConditionManagerService()
66 SysLog(NID_APP, "Enter");
67 SysLog(NID_APP, "Exit");
70 _ConditionManagerService::~_ConditionManagerService()
72 SysLog(NID_APP, "Enter");
75 _ConditionHandler* pHandler = null;
76 for (int i =0; i < __handlers.GetCount(); i ++)
79 r = __handlers.GetAt(i, pHandler);
82 __handlers.RemoveAll();
84 SysLog(NID_APP, "Exit");
88 _ConditionManagerService::Construct(void)
90 SysLog(NID_APP,"Enter.");
94 r = __handlers.Construct();
95 SysTryReturn(NID_APP, !IsFailed(r), r, r, "failed to __handlers.Construct.(%s)", GetErrorMessage(r) );
97 r = __handlerLookupTable.Construct( 16, 0.75f, __strHashMapProvider, __strComparer);
98 SysTryReturn(NID_APP, !IsFailed(r), r, r, "failed to __handlerLookupTable.Construct.(%s)", GetErrorMessage(r) );
100 r = InitializePlugins();
101 SysTryReturn(NID_APP, !IsFailed(r), r, r, "failed to InitializePlugins.(%s)", GetErrorMessage(r) );
103 r = InitializeConditionalOperations();
104 SysTryLog(NID_APP, !IsFailed(r), "failed to InitializeLaunchConditions.(%s)", GetErrorMessage(r) );
106 SysLog(NID_APP,"Exit.");
111 _ConditionManagerService::InitializePlugins(void)
113 SysLog(NID_APP,"Enter.");
115 const String& homePath = App::GetInstance()->GetAppRootPath();
117 result r = reg.Construct(homePath + REGISTRY_FILE_PLUGIN, REG_OPEN_READ_ONLY , null);
120 SysLog(NID_APP, "failed to open registry '%ls' (%s)", (homePath + REGISTRY_FILE_PLUGIN).GetPointer(), GetErrorMessage(r) );
124 IList *pSections = null;
125 r = reg.GetSectionListN(&pSections);
126 SysTryReturn(NID_APP, !IsFailed(r), r, r, "failed to GetSectionListN. (%s)", GetErrorMessage(r) );
128 IEnumerator* pEnum = pSections->GetEnumeratorN();
129 String* pSecName = null;
133 while (pEnum->MoveNext() == E_SUCCESS)
135 pSecName = static_cast<String*>(pEnum->GetCurrent());
138 pMap = reg.GetAllEntriesN(*pSecName);
139 SysTryCatch(NID_APP, pMap != null, , E_SYSTEM, "");// try next
141 r = InitializePluginEntry(*pMap);
142 if ( r == E_OBJ_NOT_FOUND)
148 SysTryCatch(NID_APP, !IsFailed(r), , r, "");
151 pMap->RemoveAll(true);
155 pSections->RemoveAll(true);
157 SysLog(NID_APP,"Exit.");
161 SysLog(NID_APP,"Catch.");
162 pSections->RemoveAll(true);
168 _ConditionManagerService::InitializePluginEntry(IMap& map)
170 result r = E_SUCCESS;
172 const String* pTypes = static_cast<const String*>(map.GetValue(REG_KEY_KEY));
173 const String* pFilename = static_cast<const String*>(map.GetValue(REG_KEY_FILENAME));
174 _ConditionHandler * pHandler = null;
176 SysTryReturn(NID_APP, pTypes != null, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "registry value is invalid. pTypes is null");
177 SysTryReturn(NID_APP, pFilename != null, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "registry value is invalid. pFilename is null");
179 Utility::StringTokenizer strTok(*pTypes, L',');
182 pHandler = new (std::nothrow) _ConditionHandler(*pFilename, *pTypes);
183 SysTryReturn(NID_APP, pHandler != null, E_FAILURE, E_FAILURE, "failed to new _ConditionHandler(%ls, %ls).", pFilename->GetPointer(), pTypes->GetPointer() );
185 r = pHandler->Construct();
186 SysTryCatch(NID_APP, !IsFailed(r), , r, "failed to pHandler->Construct. (%s)", GetErrorMessage(r) );
188 __handlers.Add(pHandler);
191 if ( strTok.GetTokenCount() == 0)
193 __handlerLookupTable.Add(*pTypes, pHandler);
197 while ( strTok.GetNextToken(type) == E_SUCCESS)
200 __handlerLookupTable.Add(type, pHandler);
204 SysLog(NID_APP, "%ls is loaded.", pFilename->GetPointer() );
209 SysLog(NID_APP, "CATCH:");
216 _ConditionManagerService::InitializeConditionalOperations(void)
218 SysLog(NID_APP,"Enter.");
220 String homePath = App::GetInstance()->GetAppRootPath();
222 result r = reg.Construct(homePath + REGISTRY_FILE_OPERATIONS, REG_OPEN_READ_ONLY, null);
223 // SysTryReturn(NID_APP, !IsFailed(r), r, r, "");
226 SysLog(NID_APP, "failed to open registry '%ls'", (homePath + REGISTRY_FILE_OPERATIONS).GetPointer());
230 IList *pSections = null;
231 reg.GetSectionListN(&pSections );
233 IEnumerator* pEnum = pSections->GetEnumeratorN();
234 String* pSecName = null;
238 while (pEnum->MoveNext() == E_SUCCESS)
240 pSecName = static_cast<String*>(pEnum->GetCurrent());
243 pMap = reg.GetAllEntriesN(*pSecName);
244 SysTryCatch(NID_APP, pMap != null, r = E_INVALID_FORMAT, E_INVALID_FORMAT, "failed to GetAllEntryNamesN(%ls)", pSecName->GetPointer() );
246 r = InitializeConditionalOperationEntry(*pSecName, *pMap);
247 SysTryLog(NID_APP, !IsFailed(r), "failed to InitializeConditionalOperationEntry(%ls), but ignored.", pSecName->GetPointer() );
249 pMap->RemoveAll(true);
260 pSections->RemoveAll(true);
263 SysLog(NID_APP,"Exit.");
268 _ConditionManagerService::InitializeConditionalOperationEntry(const String& sectionName, const IMap& map)
271 String executableName;
273 ArrayList* pArgs = null;
275 result r = _ConditionRegistryHelper::GetAllParamsN(map, packageId, executableName, condition, pArgs);
276 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] packageId(%ls), condition(%ls) is failed to register.", GetErrorMessage(r), packageId.GetPointer(), condition.GetPointer() );
278 r = RegisterAppLaunch( packageId, executableName, condition, pArgs, AppManager::LAUNCH_OPTION_DEFAULT, §ionName);
279 SysTryLog(NID_APP, !IsFailed(r), "[%s] packageId(%ls), condition(%ls) is failed to register.", GetErrorMessage(r), packageId.GetPointer(), condition.GetPointer() );
283 pArgs->RemoveAll(true);
289 // // remove invalid conditions.
290 // _ConditionRegistryHelper::RemoveFromRegistry(sectionName);
295 _ConditionManagerService::GetHandlerByCondition(const String& condition)
297 Tizen::Base::Utility::StringTokenizer strTok(condition, L"=");
298 SysTryReturn(NID_APP, strTok.GetTokenCount() > 0, null, E_INVALID_ARG, "Condition string is invalid.(%ls)", condition.GetPointer() );
301 result r = strTok.GetNextToken(key);
302 SysTryReturn(NID_APP, !IsFailed(r), null, E_INVALID_ARG, "[%s](%ls)", GetErrorMessage(r), condition.GetPointer() );
304 _ConditionHandler* pHandler = null;
305 r = __handlerLookupTable.GetValue(key, pHandler);
306 SysTryReturn(NID_APP, !IsFailed(r), null, E_INVALID_ARG, "[%s](%ls)", GetErrorMessage(r), key.GetPointer() );
311 ///////////////////////////////////////////
312 // stub implementations
313 ///////////////////////////////////////////
316 _ConditionManagerService::DumpArguments(const IList* pArguments)
318 if (pArguments != null)
320 const String* pArg = null;
321 for(int i = 0; i < pArguments->GetCount(); i ++)
323 pArg = dynamic_cast<const String*>(pArguments->GetAt(i));
326 SysLog(NID_APP, "argument%d : %ls", i, pArg->GetPointer());
333 _ConditionManagerService::RegisterAppLaunch(const Tizen::Base::String& packageId, const String& executableName, const Tizen::Base::String& condition, const Tizen::Base::Collection::IList* pArguments, AppManager::LaunchOption option, const String* pRegSectionName)
335 SysTryReturnResult(NID_APP, packageId.IsEmpty()==false, E_INVALID_ARG, "The packageId is empty.");
337 const String& exeName = (executableName.IsEmpty()) ? Tizen::App::Package::_PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(packageId) : executableName;
339 result r = E_SUCCESS;
340 SysTryReturnResult(NID_APP, exeName.IsEmpty()==false, E_INVALID_ARG, "The name is empty.");
341 SysTryReturnResult(NID_APP, condition.IsEmpty()==false, E_INVALID_ARG, "The launch condition is empty or too long (Maximum %d bytes).", MAX_LEN_CONDITION);
342 SysTryReturnResult(NID_APP, condition.GetLength() < MAX_LEN_CONDITION, E_INVALID_ARG, "The launch condition is empty or too long (Maximum %d bytes).", MAX_LEN_CONDITION);
343 //SysTryReturnResult(NID_APP, _PackageManagerImpl::GetInstance()->IsPackageInstalled(packageId) == true, E_APP_NOT_INSTALLED, "The application(%ls) is not installed.", appId.GetPointer()); // Moved to client side due to negative test.
344 SysTryReturn(NID_APP, pArguments == null || (r = ValidateArguments(pArguments)) == E_SUCCESS, r, r, "[%s]", GetErrorMessage(r));
346 SysTryReturnResult(NID_APP, (packageId.GetLength() + executableName.GetLength()) < WIDGET_APP_MAX_APPID_LENGTH, E_INVALID_ARG, "The appId is too long (Maximum %d bytes).", WIDGET_APP_MAX_APPID_LENGTH);
348 SysLog(NID_APP,"packageId(%ls), executableName(%ls), condition(%ls)", packageId.GetPointer(), executableName.GetPointer(), condition.GetPointer() );
349 if (pArguments != null)
351 DumpArguments(pArguments);
354 _ConditionHandler* pHandler = this->GetHandlerByCondition(condition);
355 SysTryReturnResult(NID_APP, pHandler != null, E_INVALID_ARG, "failed to GetHandlerByCondition(%ls)", condition.GetPointer() );
357 _AppLaunchCondition* pAppLaunchCondition = new (std::nothrow) _AppLaunchCondition();
358 SysTryReturnResult(NID_APP, pAppLaunchCondition != null, E_OUT_OF_MEMORY, "failed to create pAppLaunchCondition");
360 r = pAppLaunchCondition->Construct(packageId, exeName, condition, pArguments, option, pRegSectionName );
361 SysTryCatch(NID_APP, !IsFailed(r), , r, "failed to pAppLaunchCondition->Constructor");
363 r = pHandler->AddCondition(*pAppLaunchCondition);
364 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s]", GetErrorMessage(r));
366 SysLog(NID_APP, "SUCCESSED.");
370 delete pAppLaunchCondition;
375 _ConditionManagerService::ValidateArguments(const IList* pArguments) const
377 int totalArgumentsLen = 0;
378 for (int i = 0; i< pArguments->GetCount(); i ++)
380 const String* pArg = dynamic_cast<const String*>(pArguments->GetAt(i));
381 SysTryReturnResult(NID_APP, pArg != null, E_SYSTEM , "A system error has occurred.");
383 totalArgumentsLen += pArg->GetLength();
385 SysTryReturnResult(NID_APP, totalArgumentsLen < MAX_LEN_ARG, E_MAX_EXCEEDED, "The size of pArguments(%d) has exceeded the maximum limit(%d).", totalArgumentsLen, MAX_LEN_ARG);
391 _ConditionManagerService::UnregisterAppLaunch(const Tizen::Base::String& packageId, const String& executableName, const Tizen::Base::String* pCondition)
393 SysTryReturnResult(NID_APP, _PackageManagerImpl::GetInstance()->IsPackageInstalled(packageId) == true, E_APP_NOT_INSTALLED, "The packageId(%ls) is not installed.", packageId.GetPointer());
394 String exeName = ( executableName.IsEmpty())? Tizen::App::Package::_PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(packageId) : executableName;
396 SysLog(NID_APP,"packageId(%ls), executableName(%ls), condition(%ls)", packageId.GetPointer(), exeName.GetPointer(), (pCondition) ? pCondition->GetPointer() : L"" );
398 if ( pCondition == null)
400 return UnregisterAppLaunch(packageId, &exeName);
404 _ConditionHandler* pHandler = GetHandlerByCondition(*pCondition);
405 SysTryReturnResult(NID_APP, pHandler != null, E_OBJ_NOT_FOUND, "");
407 return pHandler->RemoveCondition(packageId, &exeName, pCondition);
410 SysLog(NID_APP, "FAILED.");
411 return E_FAILURE;// NEVER_GET_HERE
415 _ConditionManagerService::UnregisterAppLaunch(const Tizen::Base::String& packageId, const String* pExecutableName)
417 result r = E_SUCCESS;
418 _ConditionHandler* pHandler = null;
419 for (int i =0; i < __handlers.GetCount(); i ++)
422 r = __handlers.GetAt(i, pHandler);
423 SysTryReturn(NID_APP, pHandler != null, r, r, "[%s]", GetErrorMessage(r) );
424 pHandler->RemoveCondition(packageId, pExecutableName, null);
430 _ConditionManagerService::IsAppLaunchRegistered(const Tizen::Base::String& packageId, const String& executableName, const Tizen::Base::String* pCondition)
432 //SysTryReturnResult(NID_APP, _Aul::IsInstalled(appId) == true, E_APP_NOT_INSTALLED, "The application(%ls) is not installed.", appId.GetPointer());
433 SysTryReturnResult(NID_APP, _PackageManagerImpl::GetInstance()->IsPackageInstalled(packageId) == true, E_APP_NOT_INSTALLED, "The application(%ls) is not installed.", packageId.GetPointer());
436 String exeName = ( executableName.IsEmpty())? Tizen::App::Package::_PackageManagerImpl::GetInstance()->GetDefaultAppExecutableName(packageId) : executableName;
438 if (pCondition == null)
440 result r = E_SUCCESS;
441 _ConditionHandler* pHandler = null;
442 for (int i =0; i < __handlers.GetCount(); i ++)
445 r = __handlers.GetAt(i, pHandler);
446 SysTryReturn(NID_APP, pHandler != null, r, r, "[%s]", GetErrorMessage(r) );
447 if ( pHandler->HasCondition(packageId, exeName, null) == true)
455 _ConditionHandler* pHandler = GetHandlerByCondition(*pCondition);
456 SysTryReturn(NID_APP, pHandler != null, false, E_INVALID_ARG, "[E_INVALID_ARG]");
458 return pHandler->HasCondition(packageId, exeName, pCondition);
465 ///////////////////////////////////////////
467 ///////////////////////////////////////////
468 //TODO: save arguments
470 _ConditionRegistryHelper::AddToRegistry(const String& sectionName, const Tizen::Base::String& packageId, const String& executableName, const String& condition, const IList *pArg)
474 result r = reg.Construct(App::GetInstance()->GetAppRootPath() + REGISTRY_FILE_OPERATIONS, REG_OPEN_READ_WRITE | REG_OPEN_CREATE, null);
475 SysTryReturn(NID_APP, !IsFailed(r), r, r, "%s", GetErrorMessage(r) );
477 // String name = String(packageId) + String(condition);
478 r = reg.AddSection(sectionName);
479 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] sectionName : %ls", GetErrorMessage(r), sectionName.GetPointer() );
481 r = reg.AddValue(sectionName, REG_KEY_APPID, packageId);
482 r = reg.AddValue(sectionName, REG_KEY_EXENAME, executableName);
483 r = reg.AddValue(sectionName, REG_KEY_CONDTION, condition);
484 r = reg.AddValue(sectionName, REG_KEY_LAUNCH_TYPE, L"");
488 String value = Integer::ToString(pArg->GetCount());
489 r = reg.AddValue(sectionName, REG_KEY_ARG_COUNT, value );
491 const String* pCurArg = null;
493 for( int i = 0; i< pArg->GetCount(); i ++)
495 pCurArg = dynamic_cast<const String*>(pArg->GetAt(i));
498 key = REG_KEY_ARG + Integer::ToString(i);
499 r = reg.AddValue(sectionName, key, *pCurArg);
505 SysTryCatch(NID_APP, !IsFailed(r), , r, "%s", GetErrorMessage(r) );
507 SysLog(NID_APP, "ConditionInfo is added to registry. [%ls] packageId=%ls, condition=%ls, lunchType=none", sectionName.GetPointer(), packageId.GetPointer(), condition.GetPointer() );
516 _ConditionRegistryHelper::RemoveFromRegistry(const String §ion)
519 result r = reg.Construct(App::GetInstance()->GetAppRootPath() + REGISTRY_FILE_OPERATIONS, REG_OPEN_READ_WRITE, null);
520 SysTryReturn(NID_APP, !IsFailed(r), r, r, "%s", GetErrorMessage(r) );
522 r = reg.RemoveSection(section);
523 SysTryCatch(NID_APP, !IsFailed(r), , r, "%s", GetErrorMessage(r) );
526 SysTryCatch(NID_APP, !IsFailed(r), , r, "%s", GetErrorMessage(r) );
528 SysLog(NID_APP, "Removed. [%ls]", section.GetPointer() );
536 _ConditionRegistryHelper::GetAllParamsN(const IMap& map, String& packageId, String& executableName, String& condition, ArrayList*& pArgs)
538 const String* pPackageId = static_cast<const String*>(map.GetValue(REG_KEY_APPID));
539 const String* pExeName = static_cast<const String*>(map.GetValue(REG_KEY_EXENAME));
540 const String* pCondition = static_cast<const String*>(map.GetValue(REG_KEY_CONDTION));
541 // const String* pLaunchMode = static_cast<const String*>(map.GetValue(REG_KEY_LAUNCH_TYPE));
542 SysTryReturn(NID_APP, pPackageId != null, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "registry value is invalid. pPackageId is null");
543 SysTryReturn(NID_APP, pCondition != null, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "registry value is invalid. pCondition is null");
545 const String* pArgCount = static_cast<const String*>(map.GetValue(REG_KEY_ARG_COUNT));
546 if (pArgCount != null)
549 Integer::Parse(*pArgCount, argCount);
553 const String* pValue = null;
554 pArgs = new ArrayList();
556 for (int i = 0; i< argCount; i++)
558 key = REG_KEY_ARG + Integer::ToString(i);
559 pValue = dynamic_cast<const String*>(map.GetValue(key));
560 SysTryCatch(NID_APP, pValue != null, , GetLastResult(), "failed to get '%ls'.", key.GetPointer() );
561 pArgs->Add(*new String(*pValue));
566 packageId = *pPackageId;
567 condition = *pCondition;
570 executableName = *pExeName;
577 pArgs->RemoveAll(true);
587 //_ConditionRegistryHelper::ContainsSectionName(const String& sectionName)
589 // _RegistryImpl reg;
591 // result r = reg.Construct(REGISTRY_FILE_OPERATIONS, REG_OPEN_READ_ONLY, false, 0);
592 // SysTryReturn(NID_APP, !IsFailed(r), r, r, "%s", GetErrorMessage(r) );
593 // return ( reg.GetSectionIndex(sectionName) >= 0);
597 _ConditionManagerService::Dump(void) const
599 // result r = E_SUCCESS;
600 // _ConditionHandler* pHandler = null;
601 // for (int i =0; i < __handlers.GetCount(); i ++)
604 // r = __handlers.GetAt(i, pHandler);
605 // SysTryReturnVoidResult(NID_APP, pHandler != null, r, "[%s]", GetErrorMessage(r) );
611 }} //namespace Tizen { namespace App {