Add defensive codes for broken AppRegistry file
[platform/framework/native/appfw.git] / src / app / FApp_DataControlManager.cpp
1 //
2 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 /**
18  * @file        FApp_DataControlManager.cpp
19  * @brief       This is the implementation for the _DataControlManager class.
20  */
21
22 #include <new>
23 #include <unique_ptr.h>
24 #include <cstdlib>
25 #include <pthread.h>
26 #include <typeinfo>
27 #include <glib.h>
28 #include <security-server.h>
29
30 #include <FBaseInteger.h>
31 #include <FBaseSysLog.h>
32 #include <FBaseColIEnumerator.h>
33 #include <FBaseRtMutexGuard.h>
34
35 #include <FBase_StringConverter.h>
36 #include <FAppPkg_PackageManagerImpl.h>
37 #include "FApp_DataControlManager.h"
38
39 using namespace std;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::Base::Runtime;
43 using namespace Tizen::App::Package;
44
45 namespace Tizen { namespace App
46 {
47
48 _DataControlManager* _DataControlManager::__pDataControlManagerInstance = null;
49
50 _DataControlManager::_DataControlManager(void)
51         : __pDataControlRequestList(null)
52         , __pProviderList(null)
53         , __uniqueId(-1)
54 {
55 }
56
57 result
58 _DataControlManager::Construct(void)
59 {
60         unique_ptr< HashMap > pDataControlRequestList(new (std::nothrow) HashMap(SingleObjectDeleter));
61         SysTryReturnResult(NID_APP, pDataControlRequestList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
62
63         result r = pDataControlRequestList->Construct();
64         SysTryReturnResult(NID_APP, !IsFailed(r), r, "Propagating to caller...");
65
66         unique_ptr< LinkedList > pProviderList(new (std::nothrow) LinkedList(SingleObjectDeleter));
67         SysTryReturnResult(NID_APP, pProviderList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
68
69         r = __mutex.Create();
70         SysTryReturnResult(NID_APP, !IsFailed(r), r, "Mutex initialization failed.");
71
72         __pDataControlRequestList = pDataControlRequestList.release();
73         __pProviderList = pProviderList.release();
74
75         return E_SUCCESS;
76 }
77
78 _DataControlManager::~_DataControlManager(void)
79 {
80         delete __pDataControlRequestList;
81         delete __pProviderList;
82 }
83
84 void
85 _DataControlManager::InitSingleton(void)
86 {
87         _DataControlManager* pInst = new (std::nothrow) _DataControlManager();
88         SysTryReturnVoidResult(NID_APP, pInst != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
89
90         result r = pInst->Construct();
91         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
92
93         __pDataControlManagerInstance = pInst;
94
95         std::atexit(DestroySingleton);
96         return;
97
98 CATCH:
99         delete pInst;
100 }
101
102 void
103 _DataControlManager::DestroySingleton(void)
104 {
105         delete __pDataControlManagerInstance;
106 }
107
108 _DataControlManager*
109 _DataControlManager::GetInstance(void)
110 {
111         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
112         
113         if (__pDataControlManagerInstance == null)
114         {
115                 ClearLastResult();
116                 pthread_once(&onceBlock, InitSingleton);
117                 result r = GetLastResult();
118                 if (IsFailed(r))
119                 {
120                         onceBlock = PTHREAD_ONCE_INIT;
121                         SysPropagate(NID_APP, r);
122                 }
123         }
124
125         return __pDataControlManagerInstance;
126 }
127
128 int
129 _DataControlManager::GetRequestCount(void) const
130 {
131         MutexGuard lock(__mutex);
132
133         return __pDataControlRequestList->GetCount();
134 }
135
136 result
137 _DataControlManager::AddRequestInfo(Integer* pReqId, _DataControlRequestInfo* pReqInfo)
138 {
139         //SysLog(NID_APP, "DataControl request list count: %d", __pDataControlRequestList->GetCount());
140         MutexGuard lock(__mutex);
141
142         return __pDataControlRequestList->Add(pReqId, pReqInfo);
143 }
144
145 _DataControlRequestInfo*
146 _DataControlManager::GetRequestInfo(Integer& reqId) 
147 {
148         result r = E_SUCCESS;
149
150         MutexGuard lock(__mutex);
151
152         Object* pObj = __pDataControlRequestList->GetValue(reqId);
153         SysTryReturn(NID_APP, pObj != null, null, GetLastResult(), "[%s] Propagating to caller...", GetErrorMessage(GetLastResult()));
154
155         _DataControlRequestInfo* pReqInfo = dynamic_cast< _DataControlRequestInfo* >(pObj);
156         SysTryReturn(NID_APP, pReqInfo != null, null, r, "[E_SYSTEM] invalid request info");
157
158         return pReqInfo;
159 }
160
161 void
162 _DataControlManager::RemoveRequestInfo(Integer& reqId)
163 {
164         MutexGuard lock(__mutex);
165
166         __pDataControlRequestList->Remove(reqId);
167 }
168
169 void
170 _DataControlManager::RemoveAllRequests(void)
171 {
172         MutexGuard lock(__mutex);
173
174         __pDataControlRequestList->RemoveAll();
175 }
176
177 int
178 _DataControlManager::GetUniqueId(void)
179 {
180         //++__uniqueId;
181         //__sync_fetch_and_add(&__uniqueId, 1);
182         g_atomic_int_inc(&__uniqueId);
183         return __uniqueId;
184 }
185
186 void
187 _DataControlManager::Cache(const AppId& appId)
188 {
189         __pProviderList->Add(new (std::nothrow) String(appId));
190 }
191
192 bool
193 _DataControlManager::IsCached(const AppId& appId)
194 {
195         unique_ptr< IEnumerator > pEnum(__pProviderList->GetEnumeratorN());
196         while (pEnum->MoveNext() == E_SUCCESS)
197         {
198                 String* pCachedAppId = dynamic_cast< String* >(pEnum->GetCurrent());
199                 if (pCachedAppId != null && pCachedAppId->Equals(appId) == true)
200                 {
201                         return true;
202                 }
203         }
204         return false;
205 }
206
207 result
208 _DataControlManager::AllowAccess(const AppId& appId)
209 {
210         //if (IsCached(appId) == false)
211         //{
212                 const PackageId& pkgId = _PackageManagerImpl::GetPackageIdByAppId(appId);
213                 unique_ptr< char[] > pPkgId(_StringConverter::CopyToCharArrayN(pkgId));
214                 SysTryReturnResult(NID_APP, pPkgId != null, E_SYSTEM, "The method cannot proceed due to a severe system error.");
215
216                 int ret = security_server_app_give_access(pPkgId.get(), -1);
217                 SysTryReturnResult(NID_APP, ret == 0, E_SYSTEM,
218                                 "Failed to call security_server_app_give_access(), provider: %s, ret: %d", pPkgId.get(), ret);
219
220         //      Cache(appId);
221         //}
222
223         SysLog(NID_APP, "[DC_CALLER_SEND] Allow %ls to access", appId.GetPointer());
224         return E_SUCCESS;
225 }
226
227 }} // Tizen::App
228