Update wrt-plugins-common_0.3.53
[framework/web/wrt-plugins-common.git] / src / Commons / WrtAccess / WrtAccess.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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  * @author      Grzegorz Krawczyk (g.krawczyk@samsung.com)
18  * @version     0.1
19  * @brief
20  */
21
22 #include <memory>
23 #include <sstream>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27
28 #include <dpl/log/log.h>
29 #include <dpl/scoped_array.h>
30 #include <dpl/scoped_resource.h>
31 #include <dpl/assert.h>
32 #include <Commons/Exception.h>
33 #include "WrtAccess.h"
34 #include <ace_api_client.h>
35 #include <dpl/singleton_safe_impl.h>
36
37 IMPLEMENT_SAFE_SINGLETON(WrtDeviceApis::Commons::WrtAccess)
38
39 namespace {
40
41 /**
42  * Helper class - single parameter and its value
43  */
44 struct AceParam
45 {
46     const char *name;
47     const char *value;
48
49     AceParam():
50         name(NULL), value(NULL)
51     {}
52
53     AceParam(const char *name, const char *value):
54         name(name), value(value)
55     {}
56 };
57
58 /**
59  * Helper class - list of params for single dev cap
60  */
61 struct AceParamList
62 {
63     size_t    count;
64     AceParam* param;
65     AceParamList():
66         count(0),
67         param(NULL)
68     {}
69 };
70
71 struct DeviceCapParamPolicy
72 {
73     typedef AceParamList* Type;
74     static Type NullValue()
75     {
76         return NULL;
77     }
78     static void Destroy(Type ptr)
79     {
80         if (ptr) {
81             delete[] ptr->param;
82         }
83         delete[] ptr;
84     }
85 };
86
87 /**
88  * Helper class - modified ScopedArray for ace_param_list_t
89  */
90 class ScopedDeviceCapArray : public DPL::ScopedResource<DeviceCapParamPolicy>
91 {
92   public:
93     explicit ScopedDeviceCapArray(AceParamList *ptr =
94                 DeviceCapParamPolicy::NullValue()) :
95         DPL::ScopedResource<DeviceCapParamPolicy>(ptr)
96     {
97     }
98
99     AceParamList & operator [](std::ptrdiff_t k) const
100     {
101         Assert(this->m_value != DeviceCapParamPolicy::NullValue() &&
102                "Dereference of scoped NULL array!");
103         Assert(k >= 0 && "Negative array index");
104
105         return this->m_value[k];
106     }
107 };
108 } // namespace
109
110 namespace WrtDeviceApis {
111 namespace Commons {
112
113 WrtAccess::WrtAccess() :
114         m_initialized(false),
115         m_sessionId(GenerateSessionId())
116 {
117 }
118
119 WrtAccess::~WrtAccess()
120 {
121 }
122
123 WrtAccess::SessionId WrtAccess::GenerateSessionId()
124 {
125     const size_t SESSION_ID_LENGTH = 32;
126
127     std::ostringstream pid;
128     pid << static_cast<int> (getpid());
129
130     std::string session_id = pid.str();
131
132     session_id.reserve(session_id.length() + SESSION_ID_LENGTH);
133
134     for (size_t i = 0; i < SESSION_ID_LENGTH; ++i)
135     {
136         int c = random() % 16;
137
138         session_id +=  (c < 10 ?
139                         static_cast<char>('0' + c) :
140                         static_cast<char>('A' + c - 10));
141     }
142     return session_id;
143 }
144
145 void WrtAccess::initialize(int widgetId)
146 {
147     LogDebug("initialize");
148     if (widgetId < 0)
149     {
150         LogDebug("Invalid widget id");
151         Throw(Exception);
152     }
153     // TODO: implement UI handler
154     ace_return_t ret = ace_client_initialize(NULL);
155     // Assert(ACE_OK == ret); // This is commented because UI handler is not
156     // implemented, ace client will work, but initialization will return
157     // ACE_INVALID_ARGUMENTS
158     m_initialized = true;
159     m_widgetId = widgetId;
160 }
161
162 void WrtAccess::deinitialize(int /*widgetId*/)
163 {
164     LogDebug("deinitialize");
165     m_initialized = false;
166     ace_return_t ret = ace_client_shutdown();
167     Assert(ACE_OK == ret);
168 }
169
170 int WrtAccess::getWidgetId() const
171 {
172     return m_widgetId;
173 }
174
175 bool WrtAccess::checkAccessControl(const AceFunction& aceFunction) const
176 {
177     Assert(m_initialized && "WrtAccessSingleton needs to be initialized with"
178             "WidgetId during on_widget_start_callback in each plugin");
179     size_t deviceCount = aceFunction.deviceCapabilities.size();
180
181     DPL::ScopedArray <const char *> deviceScopedArray;
182     ScopedDeviceCapArray paramsScopedArray;
183
184     if (deviceCount) {
185         deviceScopedArray.Reset(new const char*[deviceCount]);
186         paramsScopedArray.Reset(new AceParamList[deviceCount]);
187
188         for (size_t i = 0; i < deviceCount; ++i) {
189             deviceScopedArray[i] =
190                 aceFunction.deviceCapabilities.at(i).devCapName.c_str();
191             paramsScopedArray[i].count =
192                 aceFunction.deviceCapabilities.at(i).devCapParams.size();
193
194             paramsScopedArray[i].param =
195                 new AceParam[paramsScopedArray[i].count];
196
197             for (size_t j = 0; j < paramsScopedArray[i].count; ++j) {
198                 paramsScopedArray[i].param[j].name =
199                     aceFunction.deviceCapabilities.at(i).
200                         devCapParams[j].name.c_str();
201                 paramsScopedArray[i].param[j].value =
202                     aceFunction.deviceCapabilities.at(i).
203                         devCapParams[j].value.c_str();
204             }
205         }
206     }
207
208     size_t featuresCount = aceFunction.features.size();
209
210     DPL::ScopedArray <const char*> featureScopedArray;
211     if (featuresCount) {
212         featureScopedArray.Reset(new const char*[featuresCount]);
213
214         for (size_t i = 0; i < featuresCount; ++i) {
215             featureScopedArray[i] =
216                 aceFunction.features.at(i).name.c_str();
217         }
218     }
219
220     LogDebug("constructing ACE request");
221
222     ace_request_t aceRequest;
223     aceRequest.session_id = const_cast<const ace_session_id_t>(m_sessionId.c_str());
224     aceRequest.widget_handle = getWidgetId();
225     aceRequest.feature_list.count = featuresCount;
226     aceRequest.feature_list.items = const_cast<ace_string_t*>(featureScopedArray.Get());
227     aceRequest.dev_cap_list.count = deviceCount;
228     aceRequest.dev_cap_list.items = new ace_dev_cap_t[deviceCount];
229
230     const char**  devCapNames = deviceScopedArray.Get();
231     AceParamList* paramList = paramsScopedArray.Get();
232
233     unsigned int i;
234     for (i = 0; i < deviceCount; ++i) {
235         aceRequest.dev_cap_list.items[i].name =
236                 const_cast<const ace_string_t>(devCapNames[i]);
237         aceRequest.dev_cap_list.items[i].param_list.count = paramList[i].count;
238         aceRequest.dev_cap_list.items[i].param_list.items =
239                 new ace_param_t[paramList[i].count];
240         unsigned int j;
241         for (j = 0; j < paramList[i].count; ++j) {
242             aceRequest.dev_cap_list.items[i].param_list.items[j].name =
243                     const_cast<ace_string_t>(paramList[i].param[j].name);
244             aceRequest.dev_cap_list.items[i].param_list.items[j].value =
245                     const_cast<ace_string_t>(paramList[i].param[j].value);
246         }
247     }
248
249     ace_bool_t aceCheckResult = ACE_FALSE;
250     ace_return_t ret = ace_check_access(&aceRequest, &aceCheckResult);
251
252     for (i = 0; i < deviceCount; ++i) {
253         delete [] aceRequest.dev_cap_list.items[i].param_list.items;
254     }
255     delete [] aceRequest.dev_cap_list.items;
256
257     if (ACE_OK != ret) {
258         LogError("Error in ace check: " << static_cast<int>(ret));
259         return false;
260     }
261     return ACE_TRUE == aceCheckResult;
262 }
263
264 }
265 } // WrtDeviceApisCommon