2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FApp_AppControlRegistry.cpp
19 * @brief This is the implementation for the _AppControlRegistry.cpp class.
23 #include <unique_ptr.h>
27 #include <FBaseErrors.h>
28 #include <FBaseSysLog.h>
29 #include <FBaseColAllElementsDeleter.h>
30 #include <FBaseColHashMap.h>
31 #include <FAppAppControl.h>
32 #include <FIoRegistry.h>
35 #include <FBase_StringConverter.h>
36 #include <FIo_RegistryImpl.h>
38 #include "FAppPkg_PackageManagerImpl.h"
39 #include "FApp_AppControlImpl.h"
41 #include "FApp_AppControlRegistry.h"
42 #include "FApp_AppMessageImpl.h"
43 #include "FApp_TemplateUtil.h"
44 #ifdef _SINGLETON_CLEANUP
45 #include "FApp_LongevityManager.h"
48 using namespace Tizen::App::Package;
49 using namespace Tizen::Base;
50 using namespace Tizen::Base::Collection;
51 using namespace Tizen::Io;
56 const wchar_t ACTL_DEFAULT_FILE[] = L"/usr/etc/app-control-info.ini";
57 const wchar_t ACTL_LEGACY_FILE[] = L"/usr/etc/app-control-alias.ini";
58 const wchar_t ACTL_ALIAS_FILE[] = L"/usr/etc/app-control-appid.ini";
60 const wchar_t TIZEN_ALIAS_APPID_PREFIX[] = L"tizen.";
62 const String ACTL_REGISTRY_PUBLIC = L"Public";
63 const String ACTL_REGISTRY_PATH = L"Path";
64 const String ACTL_REGISTRY_ALIAS_PROVIDER = L"PROVIDER_ALIAS";
66 const int PKG_APPID_LEN = 256;
67 const int REG_VALUE_BUFFER_LEN = 256;
72 namespace Tizen { namespace App
75 _AppControlRegistry* _AppControlRegistry::__pSelf = null;
77 _AppControlRegistry::_AppControlRegistry(void)
79 __tizenList.Construct();
81 __aliasList.Construct();
83 __aliasAppId.Construct();
85 __runtimeAlias.Construct();
88 _AppControlRegistry::~_AppControlRegistry(void)
90 _DeleteCollectionMapValue<String, _AppControlAliasEntry>(__aliasList);
92 _DeleteCollection<_AppControlAliasEntry>(__runtimeAlias);
96 _AppControlRegistry::GetInstance(void)
100 SysLog(NID_APP, "Create new instance");
101 __pSelf = new (std::nothrow) _AppControlRegistry();
102 SysTryReturn(NID_APP, __pSelf != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
103 SysAssertf(__pSelf != null, "AppControl registry instance creation failure");
105 __pSelf->LoadTizenAppControlRegistry();
107 __pSelf->LoadLegacyList();
109 __pSelf->LoadAliasList();
111 #ifdef _SINGLETON_CLEANUP
112 _LongevityManager::GetInstance().RegisterOwnership(*__pSelf);
121 _AppControlRegistry::LoadTizenAppControlRegistry(void)
125 const String regPath = ACTL_DEFAULT_FILE;
127 result r = reg.Construct(regPath, REG_OPEN_READ_ONLY, null);
128 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
130 const int secCount = reg.GetAllSectionCount();
131 SysTryReturnResult(NID_APP, !(secCount <= 0), E_OBJ_NOT_FOUND, "Registry contains no data.");
133 SysLog(NID_APP, "Loading %d sections from %ls", secCount, regPath.GetPointer());
140 for (int i = 0; i < secCount; i++)
142 ///////////////////////////////////////////////////////////////////////
144 String sec_name(reg.GetSectionName(i));
147 if (sec_name.IsEmpty())
155 ///////////////////////////////////////////////////////////////////////
157 index = reg.GetEntryIndex(i, ACTL_REGISTRY_PUBLIC);
163 reg.GetEntryValue(i, index, REG_VALUE_TYPE_INT, &num, &size);
172 ///////////////////////////////////////////////////////////////////////
174 index = reg.GetEntryIndex(i, ACTL_REGISTRY_PATH);
177 size = REG_VALUE_BUFFER_LEN;
178 reg.GetEntryValue(i, index, REG_VALUE_TYPE_STRING, &path, &size);
181 __tizenList.Add(sec_name, path);
184 SysLog(NID_APP, "Finished loading %d tizen AppControl entries", __tizenList.GetCount());
190 _AppControlRegistry::LoadLegacyList(void)
194 const String& regPath(ACTL_LEGACY_FILE);
196 result r = reg.Construct(regPath, REG_OPEN_READ_ONLY, null);
197 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
199 const int sec_count = reg.GetAllSectionCount();
200 SysTryReturnResult(NID_APP, !(sec_count <= 0), E_OBJ_NOT_FOUND, "Registry contains no data.");
202 SysLog(NID_APP, "Loading %d sections from %ls", sec_count, regPath.GetPointer());
204 String aliasProvider;
208 // actual parameter manipulation
209 for (int i = 0; i < sec_count; i++)
211 ///////////////////////////////////////////////////////////////////////
213 const String& secName(reg.GetSectionName(i));
215 ///////////////////////////////////////////////////////////////////////
216 // aliased appcontrol name
217 const int index = reg.GetEntryIndex(i, ACTL_REGISTRY_ALIAS_PROVIDER);
220 int size = REG_VALUE_BUFFER_LEN;
221 reg.GetEntryValue(i, index, REG_VALUE_TYPE_STRING, &aliasProvider, &size);
224 ///////////////////////////////////////////////////////////////////////
226 IList* pList = reg.GetAllEntryNamesN(secName);
232 std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
234 while (pEnum->MoveNext() == E_SUCCESS)
236 String* pStr = dynamic_cast<String*>(pEnum->GetCurrent());
238 if (pStr == null || pStr->IsEmpty() || pStr->Equals(ACTL_REGISTRY_ALIAS_PROVIDER, false))
243 r = reg.GetValue(secName, *pStr, value);
246 SysLog(NID_APP, "[%s] Propagating.", GetErrorMessage(r));
250 // add entry to aliasList
251 _AppControlAliasEntry* pEntry = new (std::nothrow) _AppControlAliasEntry(secName, *pStr, aliasProvider, value);
252 SysTryReturnResult(NID_APP, pEntry != null, E_OUT_OF_MEMORY, "Insufficient memory.");
256 SysLog(NID_APP, "(%ls, %ls)", secName.GetPointer(), aliasProvider.GetPointer());
257 __aliasList.Add(secName, pEntry);
261 pList->RemoveAll(true);
265 SysLog(NID_APP, "Finished loading %d entries.", __aliasList.GetCount());
271 _AppControlRegistry::LoadAliasList(void)
275 const String regPath = ACTL_ALIAS_FILE;
277 result r = reg.Construct(regPath, REG_OPEN_READ_ONLY, null);
278 SysTryReturn(NID_APP, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
280 HashMap* pMap = null;
281 r = reg.GetEntryListN(L"Alias", &pMap);
284 SysLog(NID_APP, "[%s] Propagating.", GetErrorMessage(r));
285 pMap->RemoveAll(true);
292 std::unique_ptr<IMapEnumerator> pEnum(pMap->GetMapEnumeratorN());
293 SysTryCatch(NID_APP, pEnum.get(), r = E_OUT_OF_MEMORY , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory error.");
295 while(pEnum->MoveNext() == E_SUCCESS)
297 pKey = static_cast<String*>(pEnum->GetKey());
298 pVal = static_cast<String*>(pEnum->GetValue());
300 __aliasAppId.Add(*pKey, *pVal);
301 //SysLog(NID_APP, "(%ls, %ls)", pKey->GetPointer(), pVal->GetPointer());
304 SysLog(NID_APP, "Loading %d alias sections", __aliasAppId.GetCount());
307 pMap->RemoveAll(true);
315 _AppControlRegistry::GetTizenAppControlN(const String& aId, const String& oId)
318 const String* pAppId = &aId;
319 const String* pOperation = &oId;
322 const _AppControlAliasEntry* const pEntry = GetAppControlAliasEntry(*pAppId, *pOperation);
323 // number does not matter
324 if (count >= 5 || pEntry == null)
329 pAppId = &pEntry->provider2;
330 pOperation = &pEntry->operation2;
336 SysAssert(pAppId != null);
337 SysAssert(pOperation != null);
339 SysLog(NID_APP, "Found matching AppControl (%ls, %ls)", pAppId->GetPointer(), pOperation->GetPointer());
341 const String& soName = GetTizenAppControlProvider(*pAppId, *pOperation);
343 if (soName.IsEmpty())
345 AppControl* pAc = GetAppControlN(*pAppId, *pOperation);
348 _AppControlImpl* pImpl = _AppControlImpl::GetInstance(*pAc);
349 pImpl->SetProperty(_APPCONTROL_PROPERTY_ALIAS);
351 const _AppControlAliasEntry* pLookupEntry = GetReverseRuntimeAliasEntry(*pAppId, *pOperation);
352 if (pLookupEntry == null)
354 // no entry found : add new one
355 _AppControlAliasEntry* pEntry = new (std::nothrow) _AppControlAliasEntry(aId, oId, *pAppId, *pOperation);
359 __runtimeAlias.Add(pEntry);
360 SysLog(NID_APP, "Setting alias app (%ls -> %ls).", aId.GetPointer(), pAppId->GetPointer());
366 SysLog(NID_APP, "No AppControl instance for (%ls, %ls)", pAppId->GetPointer(), pOperation->GetPointer());
371 return _AppControlImpl::CreateN(soName, *pAppId, *pOperation, L"", _APPCONTROL_PROPERTY_PUBLIC | _APPCONTROL_PROPERTY_SLP);
376 _AppControlRegistry::GetTizenAppControlProvider(const String& appId, const String& oId) const
379 result r = __tizenList.GetValue(appId, val);
382 SysLog(NID_APP, "Found TIZEN AppControl stub %ls for %ls.", val.GetPointer(), appId.GetPointer());
386 SysLog(NID_APP, "No platform AppControl and use custom AppControl instead.");
392 // data structure for _AppControlRegistry::FindAppControlListN() only
394 struct AppSvcIterData
397 AppSvcIterData(ArrayList* pArr, const String& op) : pArray(pArr), operation(op) {}
400 const String& operation;
404 // callback function for _AppControlRegistry::FindAppControlListN()
407 AppSvcIterFnCb(const char* pAppId, void* pData)
409 SysAssert(pData != null);
411 AppSvcIterData* pAppSvcIterData = static_cast<AppSvcIterData*>(pData);
412 ArrayList* pList = pAppSvcIterData->pArray;
413 SysAssert(pList != null);
414 const String& operation = pAppSvcIterData->operation;
418 SysLog(NID_APP, "Empty appId received.");
422 String appId = pAppId;
423 AppControl* pAc = _AppControlImpl::CreateN(appId, operation, false);
426 SysLog(NID_APP, "AppControl allocation failure for %ls.", appId.GetPointer());
435 Tizen::Base::Collection::ArrayList*
436 _AppControlRegistry::FindAppControlListN(const String* pOid, const String* pUri, const String* pMimeType, const String* pCategory) const
438 String operation = (pOid) ? *pOid : TIZEN_OPERATION_MAIN;
440 std::unique_ptr<bundle, BundleDeleter> pBundle(bundle_create());
441 SysTryReturn(NID_APP, pBundle.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Bundle creation failure.");
443 _AppMessageImpl::SetOperation(pBundle.get(), operation);
447 _AppMessageImpl::SetUri(pBundle.get(), *pUri);
452 _AppMessageImpl::SetMime(pBundle.get(), *pMimeType);
457 _AppMessageImpl::SetCategory(pBundle.get(), *pCategory);
460 ArrayList* pList = new (std::nothrow) ArrayList;
461 SysTryReturn(NID_APP, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] ArrayList creation failure.");
464 AppSvcIterData data(pList, operation);
466 appsvc_get_list(pBundle.get(), AppSvcIterFnCb, reinterpret_cast<void*>(&data));
468 if (pList->GetCount() == 0)
470 SysLog(NID_APP, "Found no AppControl entry for operation %ls.", operation.GetPointer());
479 const _AppControlRegistry::_AppControlAliasEntry*
480 _AppControlRegistry::GetAppControlAliasEntry(const String& aId, const String& oId) const
482 std::unique_ptr< IEnumeratorT<_AppControlAliasEntry*> > pEnum(__aliasList.GetValuesN(aId));
483 if (pEnum.get() == null)
485 SysLog(NID_APP, "[E_OBJ_NOT_FOUND] No alias entry for %ls.", aId.GetPointer());
489 while (pEnum->MoveNext() == E_SUCCESS)
491 _AppControlAliasEntry* pEntry = null;
492 pEnum->GetCurrent(pEntry);
493 if (pEntry->provider == aId && pEntry->operation == oId)
495 SysLog(NID_APP, "Found matching AppControl (%ls, %ls)->(%ls, %ls)", aId.GetPointer(), oId.GetPointer(), pEntry->provider2.GetPointer(), pEntry->operation2.GetPointer());
505 const _AppControlRegistry::_AppControlAliasEntry*
506 _AppControlRegistry::GetReverseAppControlAliasEntry(const String& aId, const String& oId) const
508 std::unique_ptr< IMapEnumeratorT<String, _AppControlAliasEntry*> > pEnum(__aliasList.GetMapEnumeratorN());
510 while (pEnum->MoveNext() == E_SUCCESS)
512 _AppControlAliasEntry* pEntry = null;
513 pEnum->GetValue(pEntry);
514 if (pEntry->provider2 == aId && pEntry->operation2 == oId)
516 SysLog(NID_APP, "Found matching AppControl (%ls, %ls)<-(%ls, %ls)", aId.GetPointer(), oId.GetPointer(), pEntry->provider.GetPointer(), pEntry->operation.GetPointer());
526 const _AppControlRegistry::_AppControlAliasEntry*
527 _AppControlRegistry::GetReverseRuntimeAliasEntry(const String& aId, const String& oId) const
529 std::unique_ptr< IEnumeratorT<_AppControlAliasEntry*> > pEnum(__runtimeAlias.GetEnumeratorN());
531 while (pEnum->MoveNext() == E_SUCCESS)
533 _AppControlAliasEntry* pEntry = null;
534 pEnum->GetCurrent(pEntry);
535 if (pEntry->provider2 == aId && pEntry->operation2 == oId)
537 SysLog(NID_APP, "Found matching AppControl (%ls, %ls)->(%ls, %ls)", aId.GetPointer(), oId.GetPointer(), pEntry->provider2.GetPointer(), pEntry->operation2.GetPointer());
548 _AppControlRegistry::GetAppControlN(const String& appId, const String& operationId) const
550 bool changeAppId = false;
552 String actualAppId = appId;
553 if (appId.StartsWith(TIZEN_ALIAS_APPID_PREFIX, 0))
555 const String& tmp = GetAliasAppId(appId);
560 SysLog(NID_APP, "Found alias app (%ls -> %ls).", appId.GetPointer(), tmp.GetPointer());
566 bool b = _Aul::IsInstalled(actualAppId);
567 SysTryReturn(NID_APP, b == true, null, E_APP_NOT_INSTALLED, "[E_APP_NOT_INSTALLED] %ls not installed.", actualAppId.GetPointer());
569 return _AppControlImpl::CreateN(actualAppId, operationId, changeAppId);
574 _AppControlRegistry::GetAliasAppId(const AppId& appId) const
577 result r = __aliasAppId.GetValue(appId, tmp);
588 _AppControlRegistry::GetReverseAliasAppId(const AppId& appId) const
590 std::unique_ptr< IMapEnumeratorT<String, String> > pEnum(__aliasAppId.GetMapEnumeratorN());
594 while (pEnum->MoveNext() == E_SUCCESS)
597 pEnum->GetValue(value);
604 SysLog(NID_APP, "No entry found for %ls", appId.GetPointer());