Merge branch 'tizen_2.1' of ssh://tizendev.org:29418/framework/osp/appfw into tizen_2.1
[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
34 #include <FBase_StringConverter.h>
35 #include "FApp_DataControlManager.h"
36
37 using namespace std;
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40
41 namespace Tizen { namespace App
42 {
43
44 _DataControlManager* _DataControlManager::__pDataControlManagerInstance = null;
45
46 _DataControlManager::_DataControlManager(void)
47         : __pDataControlRequestList(null)
48         , __pProviderList(null)
49         , __uniqueId(-1)
50 {
51         __pDataControlRequestList = new (std::nothrow) HashMap(SingleObjectDeleter);
52         SysTryReturnVoidResult(NID_APP, __pDataControlRequestList != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
53         __pDataControlRequestList->Construct();
54
55         __pProviderList = new (std::nothrow) LinkedList(SingleObjectDeleter);
56         SysTryReturnVoidResult(NID_APP, __pProviderList != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
57 }
58
59 _DataControlManager::~_DataControlManager(void)
60 {
61         delete __pDataControlRequestList;
62         delete __pProviderList;
63 }
64
65 void
66 _DataControlManager::InitSingleton(void)
67 {
68         _DataControlManager* pInst = new (std::nothrow) _DataControlManager();
69         SysTryReturnVoidResult(NID_APP, pInst != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
70
71         __pDataControlManagerInstance = pInst;
72                 
73         std::atexit(DestroySingleton);
74         return;
75 }
76
77 void
78 _DataControlManager::DestroySingleton(void)
79 {
80         delete __pDataControlManagerInstance;
81 }
82
83 _DataControlManager*
84 _DataControlManager::GetInstance(void)
85 {
86         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
87         
88         if (__pDataControlManagerInstance == null)
89         {
90                 ClearLastResult();
91                 pthread_once(&onceBlock, InitSingleton);
92                 result r = GetLastResult();
93                 if (IsFailed(r))
94                 {
95                         onceBlock = PTHREAD_ONCE_INIT;
96                         SysPropagate(NID_APP, r);
97                 }
98         }
99
100         return __pDataControlManagerInstance;
101 }
102
103 int
104 _DataControlManager::GetRequestCount(void) const
105 {
106         return __pDataControlRequestList->GetCount();
107 }
108
109 result
110 _DataControlManager::AddRequestInfo(Integer* pReqId, _DataControlRequestInfo* pReqInfo)
111 {
112         //SysLog(NID_APP, "DataControl request list count: %d", __pDataControlRequestList->GetCount());
113         return __pDataControlRequestList->Add(pReqId, pReqInfo);
114 }
115
116 _DataControlRequestInfo*
117 _DataControlManager::GetRequestInfo(Integer& reqId) 
118 {
119         result r = E_SUCCESS;
120
121         Object* pObj = __pDataControlRequestList->GetValue(reqId);
122         SysTryReturn(NID_APP, pObj != null, null, GetLastResult(), "[%s] Propagating to caller...", GetErrorMessage(GetLastResult()));
123
124         _DataControlRequestInfo* pReqInfo = dynamic_cast< _DataControlRequestInfo* >(pObj);
125         SysTryReturn(NID_APP, pReqInfo != null, null, r, "[E_SYSTEM] invalid request info");
126
127         return pReqInfo;
128 }
129
130 void
131 _DataControlManager::RemoveRequestInfo(Integer& reqId)
132 {
133         __pDataControlRequestList->Remove(reqId);
134 }
135
136 void
137 _DataControlManager::RemoveAllRequests(void)
138 {
139         __pDataControlRequestList->RemoveAll();
140 }
141
142 int
143 _DataControlManager::GetUniqueId(void)
144 {
145         //++__uniqueId;
146         //__sync_fetch_and_add(&__uniqueId, 1);
147         g_atomic_int_inc(&__uniqueId);
148         return __uniqueId;
149 }
150
151 void
152 _DataControlManager::Cache(String& appId)
153 {
154         __pProviderList->Add(new (std::nothrow) String(appId));
155 }
156
157 bool
158 _DataControlManager::IsCached(String& appId)
159 {
160         unique_ptr< IEnumerator > pEnum(__pProviderList->GetEnumeratorN());
161         while (pEnum->MoveNext() == E_SUCCESS)
162         {
163                 String* pCachedAppId = dynamic_cast< String* >(pEnum->GetCurrent());
164                 if (pCachedAppId != null && pCachedAppId->Equals(appId) == true)
165                 {
166                         return true;
167                 }
168         }
169         return false;
170 }
171
172 result
173 _DataControlManager::AllowAccess(String& appId)
174 {
175         if (IsCached(appId) == false)
176         {
177                 unique_ptr< char[] > pPkgId(_StringConverter::CopyToCharArrayN(appId));
178                 SysTryReturnResult(NID_APP, pPkgId != null, E_SYSTEM, "The method cannot proceed due to a severe system error.");
179                 pPkgId.get()[10] = '\0';
180
181                 int ret = security_server_app_give_access(pPkgId.get(), -1);
182                 SysTryReturnResult(NID_APP, ret == 0, E_SYSTEM,
183                                 "Failed to call security_server_app_give_access(), provider: %s, ret: %d", pPkgId.get(), ret);
184
185                 Cache(appId);
186         }
187
188         SysLog(NID_APP, "[DC_CALLER_SEND] Allow %ls to access", appId.GetPointer());
189         return E_SUCCESS;
190 }
191
192 }} // Tizen::App
193