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_AppControlRegistry.cpp
20 * @brief This is the implementation for the _AppControlRegistry.cpp class.
24 #include <unique_ptr.h>
28 #include <FBaseErrors.h>
29 #include <FBaseSysLog.h>
30 #include <FBaseColAllElementsDeleter.h>
31 #include <FBaseColHashMap.h>
32 #include <FAppAppControl.h>
33 #include <FIoRegistry.h>
36 #include <FBase_StringConverter.h>
37 #include <FIo_RegistryImpl.h>
39 #include "FAppPkg_PackageManagerImpl.h"
40 #include "FApp_AppControlImpl.h"
42 #include "FApp_AppControlRegistry.h"
43 #include "FApp_AppMessageImpl.h"
44 #include "FApp_TemplateUtil.h"
45 #ifdef _SINGLETON_CLEANUP
46 #include "FApp_LongevityManager.h"
49 using namespace Tizen::App::Package;
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Collection;
52 using namespace Tizen::Io;
57 const wchar_t ACTL_PRIVATE_FILE[] = L"/usr/etc/app-control-system.ini";
58 const wchar_t ACTL_DEFAULT_FILE[] = L"/usr/etc/app-control-info.ini";
59 const wchar_t ACTL_LEGACY_FILE[] = L"/usr/etc/app-control-alias.ini";
60 const wchar_t ACTL_ALIAS_FILE[] = L"/usr/etc/app-control-appid.ini";
61 const wchar_t ACTL_PRIVATE_ALIAS_FILE[] = L"/usr/etc/app-control-private-appid.ini";
63 const wchar_t TIZEN_ALIAS_APPID_PREFIX[] = L"tizen.";
65 const String ACTL_REGISTRY_OP_NUM = L"OPID_Count";
66 const String ACTL_REGISTRY_PUBLIC = L"Public";
67 const String ACTL_REGISTRY_LAUNCH_TYPE = L"LaunchType";
68 const String ACTL_REGISTRY_PATH = L"Path";
69 const String ACTL_REGISTRY_CATEGORY = L"Category";
70 const String ACTL_REGISTRY_TITLE = L"Title";
71 const String ACTL_REGISTRY_ALIAS_PROVIDER = L"PROVIDER_ALIAS";
73 const int PKG_CATEGORY_LEN = 256;
74 const int PKG_APPID_LEN = 256;
75 const int REG_VALUE_BUFFER_LEN = 256;
80 namespace Tizen { namespace App
83 _AppControlRegistry* _AppControlRegistry::__pSelf = null;
85 _AppControlRegistry::_AppControlRegistry(void)
87 __nativeList.Construct();
89 __aliasList.Construct();
91 __aliasOperation.Construct();
93 __aliasAppId.Construct();
96 _AppControlRegistry::~_AppControlRegistry(void)
98 _DeleteCollection<AppControl>(__nativeList);
100 _DeleteCollectionMapValue<String, _AppControlAliasEntry>(__aliasList);
104 _AppControlRegistry::GetInstance(void)
108 SysLog(NID_APP, "Create new instance");
109 __pSelf = new (std::nothrow) _AppControlRegistry();
110 SysTryReturn(NID_APP, __pSelf != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
111 SysAssertf(__pSelf != null, "AppControl registry instance creation failure");
113 __pSelf->LoadRegistry();
115 __pSelf->LoadLegacyList();
117 __pSelf->LoadAliasList();
119 #ifdef _SINGLETON_CLEANUP
120 _LongevityManager::GetInstance().RegisterOwnership(*__pSelf);
128 _AppControlRegistry::LoadRegistry(void)
132 String regPath = ACTL_PRIVATE_FILE;
134 // if ACTL_SYSTEM does not exist, then use default name
135 if (!File::IsFileExist(regPath))
137 regPath = ACTL_DEFAULT_FILE;
140 result r = reg.Construct(regPath, REG_OPEN_READ_ONLY, null);
141 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
143 const int sec_count = reg.GetAllSectionCount();
144 SysTryReturnResult(NID_APP, !(sec_count <= 0), E_OBJ_NOT_FOUND, "Registry contains no data.");
146 SysLog(NID_APP, "Loading %d sections from %ls", sec_count, regPath.GetPointer());
155 // actual parameter manipulation
156 for (int i = 0; i < sec_count; i++)
158 ///////////////////////////////////////////////////////////////////////
160 String sec_name(reg.GetSectionName(i));
163 if (sec_name.IsEmpty())
171 ///////////////////////////////////////////////////////////////////////
173 index = reg.GetEntryIndex(i, ACTL_REGISTRY_PUBLIC);
179 reg.GetEntryValue(i, index, REG_VALUE_TYPE_INT, &num, &size);
187 ///////////////////////////////////////////////////////////////////////
189 index = reg.GetEntryIndex(i, ACTL_REGISTRY_LAUNCH_TYPE);
194 reg.GetEntryValue(i, index, REG_VALUE_TYPE_INT, &launch_type, &size);
197 ///////////////////////////////////////////////////////////////////////
199 index = reg.GetEntryIndex(i, ACTL_REGISTRY_PATH);
202 size = REG_VALUE_BUFFER_LEN;
203 reg.GetEntryValue(i, index, REG_VALUE_TYPE_STRING, &actl_path, &size);
205 if (launch_type == _APPCONTROL_TYPE_OSP)
207 if (!_Aul::IsInstalled(actl_path))
209 SysLog(NID_APP, "Osp app %ls not installed.", actl_path.GetPointer());
212 // [FIXME] retrieve from package info here
216 ///////////////////////////////////////////////////////////////////////
218 // [FIXME] SLP localized name here
219 index = reg.GetEntryIndex(i, ACTL_REGISTRY_TITLE);
222 size = REG_VALUE_BUFFER_LEN;
223 reg.GetEntryValue(i, index, REG_VALUE_TYPE_STRING, &actl_name, &size);
226 //SysLog(NID_APP, "%dth iteration : %ls", i, sec_name.GetPointer());
228 ///////////////////////////////////////////////////////////////////////
229 // Number of operation Id
230 index = reg.GetEntryIndex(i, ACTL_REGISTRY_OP_NUM);
234 reg.GetEntryValue(i, index, REG_VALUE_TYPE_INT, &num, &size);
239 //SysLog(NID_APP, "number of operation %d for index %d", num, index);
241 for (int j = 0; j < num; j++)
243 size = REG_VALUE_BUFFER_LEN;
245 ///////////////////////////////////////////////////////////////
247 tagName.Format(10, L"OPID_%d", j);
249 index = reg.GetEntryIndex(i, tagName);
252 reg.GetEntryValue(i, index, REG_VALUE_TYPE_STRING, &actl_opId, &size);
255 //SysLog(NID_APP, "Operation(%d) %ls", index, actl_opId.GetPointer());
257 ///////////////////////////////////////////////////////////////
258 // AppControl allocation
261 if (public_open == 1)
263 prop |= _APPCONTROL_PROPERTY_PUBLIC;
268 case _APPCONTROL_TYPE_NATIVE:
269 prop |= _APPCONTROL_PROPERTY_SLP;
271 case _APPCONTROL_TYPE_OSP:
272 prop |= _APPCONTROL_PROPERTY_OSP;
275 SysLog(NID_APP, "Invalid launch type %d", launch_type);
279 //SysLog(NID_APP, "(%ls, %ls)", sec_name.GetPointer(), actl_opId.GetPointer());
280 AppControl* pAc = _AppControlImpl::CreateN(actl_path, sec_name, actl_opId, actl_name, prop);
284 __nativeList.Add(pAc);
288 SysLog(NID_APP, "Failed to create AppControl instance (%ls, %ls, %d, %d)",
289 sec_name.GetPointer(), actl_opId.GetPointer(), public_open, launch_type);
296 SysLog(NID_APP, "Finished loading %d entries", __nativeList.GetCount());
302 _AppControlRegistry::LoadLegacyList(void)
306 const String& regPath(ACTL_LEGACY_FILE);
308 result r = reg.Construct(regPath, REG_OPEN_READ_ONLY, null);
309 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
311 const int sec_count = reg.GetAllSectionCount();
312 SysTryReturnResult(NID_APP, !(sec_count <= 0), E_OBJ_NOT_FOUND, "Registry contains no data.");
314 SysLog(NID_APP, "Loading %d sections from %ls", sec_count, regPath.GetPointer());
316 String aliasProvider;
320 // actual parameter manipulation
321 for (int i = 0; i < sec_count; i++)
323 ///////////////////////////////////////////////////////////////////////
325 const String& secName(reg.GetSectionName(i));
327 ///////////////////////////////////////////////////////////////////////
328 // aliased appcontrol name
329 const int index = reg.GetEntryIndex(i, ACTL_REGISTRY_ALIAS_PROVIDER);
332 int size = REG_VALUE_BUFFER_LEN;
333 reg.GetEntryValue(i, index, REG_VALUE_TYPE_STRING, &aliasProvider, &size);
336 ///////////////////////////////////////////////////////////////////////
338 IList* pList = reg.GetAllEntryNamesN(secName);
344 std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
346 while (pEnum->MoveNext() == E_SUCCESS)
348 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
350 if (pStr == null || pStr->IsEmpty() || pStr->Equals(ACTL_REGISTRY_ALIAS_PROVIDER, false))
355 r = reg.GetValue(secName, *pStr, value);
358 SysLog(NID_APP, "[%s] Propagating.", GetErrorMessage(r));
363 __aliasOperation.ContainsKey(*pStr, b);
366 __aliasOperation.SetValue(*pStr, value);
370 __aliasOperation.Add(*pStr, value);
373 // add entry to aliasList
374 _AppControlAliasEntry* pEntry = new (std::nothrow) _AppControlAliasEntry(secName, *pStr, aliasProvider, value);
375 SysTryReturnResult(NID_APP, pEntry != null, E_OUT_OF_MEMORY, "Insufficient memory.");
379 SysLog(NID_APP, "(%ls, %ls)", secName.GetPointer(), aliasProvider.GetPointer());
380 __aliasList.Add(secName, pEntry);
384 pList->RemoveAll(true);
388 SysLog(NID_APP, "Finished loading %d entries with %d operation aliases.", __aliasList.GetCount(), __aliasOperation.GetCount());
394 _AppControlRegistry::LoadAliasList(void)
398 String regPath = ACTL_PRIVATE_ALIAS_FILE;
400 // if ACTL_SYSTEM does not exist, then use default name
401 if (!File::IsFileExist(regPath))
403 regPath = ACTL_ALIAS_FILE;
406 result r = reg.Construct(regPath, REG_OPEN_READ_ONLY, null);
407 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
409 HashMap* pMap = null;
410 r = reg.GetEntryListN(L"Alias", &pMap);
413 SysLog(NID_APP, "[%s] Propagating.", GetErrorMessage(r));
420 std::unique_ptr<IMapEnumerator> pEnum(pMap->GetMapEnumeratorN());
421 SysTryCatch(NID_APP, pEnum.get(), r = E_OUT_OF_MEMORY , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory error.");
423 while(pEnum->MoveNext() == E_SUCCESS)
425 pKey = static_cast<String*>(pEnum->GetKey());
426 pVal = static_cast<String*>(pEnum->GetValue());
428 __aliasAppId.Add(*pKey, *pVal);
429 //SysLog(NID_APP, "(%ls, %ls)", pKey->GetPointer(), pVal->GetPointer());
432 SysLog(NID_APP, "Loading %d alias sections", __aliasAppId.GetCount());
442 _AppControlRegistry::GetNativeAppControlN(const String& aId, const String& oId) const
444 std::unique_ptr< IEnumeratorT<AppControl*> > pEnum(__nativeList.GetEnumeratorN());
446 while (pEnum->MoveNext() == E_SUCCESS)
448 AppControl* pAc = null;
449 pEnum->GetCurrent(pAc);
451 if (pAc->GetAppControlProviderId() == aId && pAc->GetOperationId() == oId)
453 SysLog(NID_APP, "Found matching AppControl (%ls, %ls)", aId.GetPointer(), oId.GetPointer());
454 return _AppControlImpl::CreateN(*pAc);
458 SysLog(NID_APP, "No matching AppControl (%ls, %ls)", aId.GetPointer(), oId.GetPointer());
464 // data structure for _AppControlRegistry::GetAppControlListN() only
466 struct AppSvcIterData
469 AppSvcIterData(ArrayList* pArr, const String& op) : pArray(pArr), operation(op) {}
472 const String& operation;
476 // callback function for _AppControlRegistry::GetAppControlListN()
479 AppSvcIterFnCb(const char* pAppId, void* pData)
481 SysAssert(pData != null);
483 AppSvcIterData* pAppSvcIterData = static_cast<AppSvcIterData*>(pData);
484 ArrayList* pList = pAppSvcIterData->pArray;
485 SysAssert(pList != null);
486 const String& operation = pAppSvcIterData->operation;
490 SysLog(NID_APP, "Empty appId received.");
494 String appId = pAppId;
495 AppControl* pAc = _AppControlImpl::CreateN(appId, operation, false);
498 SysLog(NID_APP, "AppControl allocation failure for %ls.", appId.GetPointer());
507 Tizen::Base::Collection::ArrayList*
508 _AppControlRegistry::FindAppControlListN(const String* pOid, const String* pUri, const String* pMimeType, const String* pCategory) const
510 String operation = (pOid) ? *pOid : TIZEN_OPERATION_MAIN;
512 std::unique_ptr<bundle, BundleDeleter> pBundle(bundle_create());
513 SysTryReturn(NID_APP, pBundle.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Bundle creation failure.");
515 _AppMessageImpl::SetOperation(pBundle.get(), operation);
519 _AppMessageImpl::SetUri(pBundle.get(), *pUri);
524 _AppMessageImpl::SetMime(pBundle.get(), *pMimeType);
529 _AppMessageImpl::SetCategory(pBundle.get(), *pCategory);
532 ArrayList* pList = new (std::nothrow) ArrayList;
533 SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] ArrayList creation failure.");
536 AppSvcIterData data(pList, operation);
538 appsvc_get_list(pBundle.get(), AppSvcIterFnCb, reinterpret_cast<void*>(&data));
540 if (pList->GetCount() == 0)
542 SysLog(NID_APP, "Found no AppControl entry for operation %ls.", operation.GetPointer());
551 _AppControlRegistry::_AppControlAliasEntry*
552 _AppControlRegistry::GetAppControlAliasEntry(const String& aId, const String& oId) const
554 std::unique_ptr< IEnumeratorT<_AppControlAliasEntry*> > pEnum(__aliasList.GetValuesN(aId));
555 if (pEnum.get() == null)
557 SysLog(NID_APP, "[E_OBJ_NOT_FOUND] No alias entry for %ls.", aId.GetPointer());
561 while (pEnum->MoveNext() == E_SUCCESS)
563 _AppControlAliasEntry* pEntry = null;
564 pEnum->GetCurrent(pEntry);
565 if (pEntry->provider == aId && pEntry->operation == oId)
567 SysLog(NID_APP, "Found matching AppControl (%ls, %ls)->(%ls, %ls)", aId.GetPointer(), oId.GetPointer(), pEntry->provider2.GetPointer(), pEntry->operation2.GetPointer());
576 _AppControlRegistry::_AppControlAliasEntry*
577 _AppControlRegistry::GetReverseAppControlAliasEntry(const String& aId, const String& oId) const
579 std::unique_ptr< IMapEnumeratorT<String, _AppControlAliasEntry*> > pEnum(__aliasList.GetMapEnumeratorN());
581 while (pEnum->MoveNext() == E_SUCCESS)
583 _AppControlAliasEntry* pEntry = null;
584 pEnum->GetValue(pEntry);
585 if (pEntry->provider2 == aId && pEntry->operation2 == oId)
587 SysLog(NID_APP, "Found matching AppControl (%ls, %ls)<-(%ls, %ls)", aId.GetPointer(), oId.GetPointer(), pEntry->provider.GetPointer(), pEntry->operation.GetPointer());
597 _AppControlRegistry::GetAliasAppControlN(const String& aId, const String& oId) const
599 _AppControlAliasEntry* pEntry = GetAppControlAliasEntry(aId, oId);
603 AppControl* pAc = GetNativeAppControlN(pEntry->provider2, pEntry->operation2);
606 _AppControlImpl* pImpl = _AppControlImpl::GetInstance(*pAc);
607 pImpl->SetProperty(_APPCONTROL_PROPERTY_ALIAS);
611 pAc = GetAppControlN(pEntry->provider2, pEntry->operation2);
614 _AppControlImpl* pImpl = _AppControlImpl::GetInstance(*pAc);
615 pImpl->SetProperty(_APPCONTROL_PROPERTY_ALIAS);
619 SysLog(NID_APP, "No matching AppControl found.");
626 SysLog(NID_APP, "No matching AppControl found.");
631 _AppControlRegistry::GetAppControlN(const String& appId, const String& operationId) const
633 bool changeAppId = false;
635 String actualAppId = appId;
636 if (appId.StartsWith(TIZEN_ALIAS_APPID_PREFIX, 0))
639 result r = __aliasAppId.GetValue(appId, tmp);
643 SysLog(NID_APP, "Found alias appId (%ls -> %ls).", appId.GetPointer(), tmp.GetPointer());
649 bool b = _Aul::IsInstalled(actualAppId);
650 SysTryReturn(NID_APP, b == true, null, E_APP_NOT_INSTALLED, "[E_APP_NOT_INSTALLED] %ls not installed.", actualAppId.GetPointer());
652 return _AppControlImpl::CreateN(actualAppId, operationId, changeAppId);
656 _AppControlRegistry::GetReverseAliasAppId(const AppId& appId) const
658 std::unique_ptr< IMapEnumeratorT<String, String> > pEnum(__aliasAppId.GetMapEnumeratorN());
662 while (pEnum->MoveNext() == E_SUCCESS)
665 pEnum->GetValue(value);
672 SysLog(NID_APP, "No entry found for %ls", appId.GetPointer());
677 _AppControlRegistry::GetAliasedOperation(const String& operation) const
680 __aliasOperation.ContainsKey(operation, b);
685 __aliasOperation.GetValue(operation, tmp);