Update for attribute changed callback and attribute getter
[platform/core/system/sensord.git] / src / server / sensor_handler.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "sensor_handler.h"
21
22 #include <message.h>
23 #include <sensor_log.h>
24 #include <sensor_utils.h>
25 #include <sensor_types_private.h>
26 #include <command_types.h>
27 #include <sensor_listener_proxy.h>
28
29 using namespace sensor;
30
31 sensor_handler::sensor_handler(const sensor_info &info)
32 : m_info(info)
33 , m_prev_interval(0)
34 , m_prev_latency(0)
35 , m_need_to_notify_attribute_changed(false)
36 {
37         const char *priv = sensor::utils::get_privilege(m_info.get_uri());
38         m_info.set_privilege(priv);
39
40         sensor_type_t type = sensor::utils::get_type(m_info.get_uri());
41         m_info.set_type(type);
42
43         /* TODO: temporary walkaround for sensors that require multiple privileges */
44         switch (m_info.get_type()) {
45         case EXTERNAL_EXERCISE_SENSOR:
46         case EXERCISE_STANDALONE_SENSOR:
47                 m_info.add_privilege(PRIVILEGE_LOCATION_URI);
48                 break;
49         case GPS_CTRL_SENSOR:
50                 m_info.add_privilege(PRIVILEGE_PLATFORM_URI);
51                 break;
52         default:
53                 break;
54         }
55 }
56
57 bool sensor_handler::has_observer(sensor_observer *ob)
58 {
59         for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
60                 if ((*it) == ob)
61                         return true;
62         }
63
64         return false;
65 }
66
67 bool sensor_handler::add_observer(sensor_observer *ob)
68 {
69         retv_if(has_observer(ob), false);
70
71         m_observers.push_back(ob);
72         return true;
73 }
74
75 void sensor_handler::remove_observer(sensor_observer *ob)
76 {
77         m_observers.remove(ob);
78 }
79
80 int sensor_handler::notify(const char *uri, sensor_data_t *data, int len)
81 {
82         if (observer_count() == 0)
83                 return OP_ERROR;
84
85         auto msg = ipc::message::create((char *)data, len);
86
87         retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
88
89         for (auto it = m_observers.begin(); it != m_observers.end(); ++it)
90                 (*it)->update(uri, msg);
91
92         set_cache(data, len);
93
94         return OP_SUCCESS;
95 }
96
97 uint32_t sensor_handler::observer_count(void)
98 {
99         return m_observers.size();
100 }
101
102 void sensor_handler::set_cache(sensor_data_t *data, int size)
103 {
104         char* p = (char*) data;
105
106         try {
107                 m_sensor_data_cache.reserve(size);
108         } catch (...) {
109                 _E("Memory allocation failed");
110                 return;
111         }
112         m_sensor_data_cache.clear();
113         m_sensor_data_cache.insert(m_sensor_data_cache.begin(), p, p + size);
114 }
115
116 int sensor_handler::get_cache(sensor_data_t **data, int *len)
117 {
118         auto size = m_sensor_data_cache.size();
119         retv_if(size == 0, -ENODATA);
120
121         char* temp = (char *)malloc(size);
122         retvm_if(temp == NULL, -ENOMEM, "Memory allocation failed");
123         std::copy(m_sensor_data_cache.begin(), m_sensor_data_cache.end(), temp);
124
125         *len = size;
126         *data = (sensor_data_t *)temp;
127
128         return 0;
129 }
130
131 bool sensor_handler::notify_attribute_changed(uint32_t id, int32_t attribute, int32_t value)
132 {
133         if (observer_count() == 0)
134                 return OP_ERROR;
135
136         cmd_listener_attr_int_t buf;
137         buf.listener_id = id;
138         buf.attribute = attribute;
139         buf.value = value;
140
141         auto msg = ipc::message::create();
142
143         retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
144
145         msg->set_type(CMD_LISTENER_SET_ATTR_INT);
146         msg->enclose((char *)&buf, sizeof(buf));
147
148         sensor_listener_proxy *proxy = NULL;
149         for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
150                 proxy = dynamic_cast<sensor_listener_proxy *>(*it);
151                 if (proxy && proxy->get_id() != id) {
152                         proxy->on_attribute_changed(msg);
153                 }
154         }
155
156         return OP_SUCCESS;
157 }
158
159 bool sensor_handler::notify_attribute_changed(uint32_t id, int32_t attribute, const char *value, int len)
160 {
161         if (observer_count() == 0)
162                 return OP_ERROR;
163
164         cmd_listener_attr_str_t *buf;
165         size_t size;
166         size = sizeof(cmd_listener_attr_str_t) + len;
167         buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size];
168         retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
169
170         auto msg = ipc::message::create();
171         retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
172
173         buf->listener_id = id;
174         buf->attribute = attribute;
175         memcpy(buf->value, value, len);
176         buf->len = len;
177
178         msg->set_type(CMD_LISTENER_SET_ATTR_STR);
179         msg->enclose((char *)buf, size);
180
181         _I("notify attribute changed by listener[%zu]\n", id);
182         sensor_listener_proxy *proxy = NULL;
183         for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
184                 proxy = dynamic_cast<sensor_listener_proxy *>(*it);
185                 if (proxy) {
186                         proxy->on_attribute_changed(msg);
187                 }
188         }
189
190         delete[] buf;
191
192         return OP_SUCCESS;
193 }
194
195 int sensor_handler::delete_batch_latency(sensor_observer *ob)
196 {
197         return 0;
198 }
199
200 int sensor_handler::get_attribute(int32_t attr, int32_t* value)
201 {
202         auto it = m_attributes_int.find(attr);
203         retv_if(it == m_attributes_int.end(), OP_ERROR);
204
205         *value = it->second;
206         return OP_SUCCESS;
207 }
208
209 void sensor_handler::update_attribute(int32_t attr, int32_t value)
210 {
211         auto it = m_attributes_int.find(attr);
212         if(it != m_attributes_int.end()) {
213                 if (it->second != value) {
214                         set_need_to_notify_attribute_changed(true);
215                 }
216         } else {
217                 set_need_to_notify_attribute_changed(true);
218         }
219         if (need_to_notify_attribute_changed()) {
220                 m_attributes_int[attr] = value;
221                 _I("[%s] attributes(int) attr[%d] value[%d] attributes size[%zu]", m_info.get_uri().c_str(), attr, value, m_attributes_int.size());
222         }
223 }
224
225 int sensor_handler::get_attribute(int32_t attr, char **value, int *len)
226 {
227         auto it = m_attributes_str.find(attr);
228         retv_if(it == m_attributes_str.end(), OP_ERROR);
229
230         *len = it->second.size();
231         *value = new(std::nothrow) char[*len];
232         std::copy(it->second.begin(), it->second.end(), *value);
233
234         return OP_SUCCESS;
235 }
236
237 void sensor_handler::update_attribute(int32_t attr, const char *value, int len)
238 {
239         auto it = m_attributes_str.find(attr);
240         if(it != m_attributes_str.end()) {
241                 if (it->second.size() != (size_t)len) {
242                         set_need_to_notify_attribute_changed(true);
243                 } else {
244                         for(int i = 0 ; i < len; i++) {
245                                 if (value[i] != it->second[i]) {
246                                         set_need_to_notify_attribute_changed(true);
247                                         break;
248                                 }
249                         }
250                 }
251         } else {
252                 set_need_to_notify_attribute_changed(true);
253         }
254         if (need_to_notify_attribute_changed()) {
255                 m_attributes_str[attr].clear();
256                 m_attributes_str[attr].insert(m_attributes_str[attr].begin(), value, value + len);
257                 _I("[%s] attributes(int) attr[%d] value[%s] attributes size[%zu]", m_info.get_uri().c_str(), attr, value, m_attributes_str.size());
258         }
259 }
260
261 bool sensor_handler::need_to_notify_attribute_changed()
262 {
263         return m_need_to_notify_attribute_changed;
264 }
265
266 void sensor_handler::set_need_to_notify_attribute_changed(bool value)
267 {
268         m_need_to_notify_attribute_changed = value;
269 }
270
271 void sensor_handler::update_prev_interval(int32_t interval)
272 {
273         if (m_prev_interval != interval) {
274                 m_prev_interval = interval;
275                 set_need_to_notify_attribute_changed(true);
276                 _I("Set interval[%d] to sensor[%s]", m_prev_interval, m_info.get_uri().c_str());
277         }
278 }
279
280 void sensor_handler::update_prev_latency(int32_t latency)
281 {
282         if (m_prev_latency != latency) {
283                 m_prev_latency = latency;
284                 set_need_to_notify_attribute_changed(true);
285                 _I("Set interval[%d] to sensor[%s]", m_prev_latency, m_info.get_uri().c_str());
286         }
287 }