1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "sensor_data_processer.h"
17
18 #include <cinttypes>
19 #include <sys/prctl.h>
20 #include <sys/socket.h>
21 #include <thread>
22
23 #include "hisysevent.h"
24 #include "print_sensor_data.h"
25 #include "permission_util.h"
26 #include "securec.h"
27 #include "sensor_basic_data_channel.h"
28 #include "sensor_errors.h"
29 #include "system_ability_definition.h"
30
31 #undef LOG_TAG
32 #define LOG_TAG "SensorDataProcesser"
33
34 namespace OHOS {
35 namespace Sensors {
36 using namespace OHOS::HiviewDFX;
37
38 namespace {
39 const std::string SENSOR_REPORT_THREAD_NAME = "OS_SenProducer";
40 } // namespace
41
SensorDataProcesser(const std::unordered_map<int32_t,Sensor> & sensorMap)42 SensorDataProcesser::SensorDataProcesser(const std::unordered_map<int32_t, Sensor> &sensorMap)
43 {
44 sensorMap_.insert(sensorMap.begin(), sensorMap.end());
45 SEN_HILOGD("sensorMap_.size:%{public}d", int32_t { sensorMap_.size() });
46 }
47
~SensorDataProcesser()48 SensorDataProcesser::~SensorDataProcesser()
49 {
50 dataCountMap_.clear();
51 sensorMap_.clear();
52 }
53
SendNoneFifoCacheData(std::unordered_map<int32_t,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> & channel,SensorData & data,uint64_t periodCount)54 void SensorDataProcesser::SendNoneFifoCacheData(std::unordered_map<int32_t, SensorData> &cacheBuf,
55 sptr<SensorBasicDataChannel> &channel, SensorData &data,
56 uint64_t periodCount)
57 {
58 std::vector<SensorData> sendEvents;
59 std::lock_guard<std::mutex> dataCountLock(dataCountMutex_);
60 sendEvents.push_back(data);
61 auto dataCountIt = dataCountMap_.find(data.sensorTypeId);
62 if (dataCountIt == dataCountMap_.end()) {
63 std::vector<sptr<FifoCacheData>> channelFifoList;
64 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
65 CHKPV(fifoCacheData);
66 fifoCacheData->SetChannel(channel);
67 channelFifoList.push_back(fifoCacheData);
68 dataCountMap_.insert(std::make_pair(data.sensorTypeId, channelFifoList));
69 SendRawData(cacheBuf, channel, sendEvents);
70 return;
71 }
72 bool channelExist = false;
73 for (auto fifoIt = dataCountIt->second.begin(); fifoIt != dataCountIt->second.end();) {
74 auto fifoCacheData = *fifoIt;
75 CHKPC(fifoCacheData);
76 auto fifoChannel = fifoCacheData->GetChannel();
77 if (fifoChannel == nullptr) {
78 fifoIt = dataCountIt->second.erase(fifoIt);
79 continue;
80 }
81 ++fifoIt;
82 if (fifoChannel != channel) {
83 continue;
84 }
85 channelExist = true;
86 uint64_t curCount = fifoCacheData->GetPeriodCount();
87 curCount++;
88 fifoCacheData->SetPeriodCount(curCount);
89 if (periodCount != 0 && fifoCacheData->GetPeriodCount() % periodCount != 0UL) {
90 continue;
91 }
92 SendRawData(cacheBuf, channel, sendEvents);
93 fifoCacheData->SetPeriodCount(0);
94 return;
95 }
96 if (!channelExist) {
97 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
98 CHKPV(fifoCacheData);
99 fifoCacheData->SetChannel(channel);
100 dataCountIt->second.push_back(fifoCacheData);
101 SendRawData(cacheBuf, channel, sendEvents);
102 }
103 }
104
SendFifoCacheData(std::unordered_map<int32_t,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> & channel,SensorData & data,uint64_t periodCount,uint64_t fifoCount)105 void SensorDataProcesser::SendFifoCacheData(std::unordered_map<int32_t, SensorData> &cacheBuf,
106 sptr<SensorBasicDataChannel> &channel, SensorData &data,
107 uint64_t periodCount, uint64_t fifoCount)
108 {
109 std::lock_guard<std::mutex> dataCountLock(dataCountMutex_);
110 auto dataCountIt = dataCountMap_.find(data.sensorTypeId);
111 // there is no channelFifoList
112 if (dataCountIt == dataCountMap_.end()) {
113 std::vector<sptr<FifoCacheData>> channelFifoList;
114 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
115 CHKPV(fifoCacheData);
116 fifoCacheData->SetChannel(channel);
117 channelFifoList.push_back(fifoCacheData);
118 dataCountMap_.insert(std::make_pair(data.sensorTypeId, channelFifoList));
119 return;
120 }
121 // find channel in channelFifoList
122 bool channelExist = false;
123 for (auto fifoIt = dataCountIt->second.begin(); fifoIt != dataCountIt->second.end();) {
124 auto fifoData = *fifoIt;
125 CHKPC(fifoData);
126 auto fifoChannel = fifoData->GetChannel();
127 if (fifoChannel == nullptr) {
128 fifoIt = dataCountIt->second.erase(fifoIt);
129 continue;
130 }
131 ++fifoIt;
132 if (fifoChannel != channel) {
133 continue;
134 }
135 channelExist = true;
136 uint64_t curCount = fifoData->GetPeriodCount();
137 curCount++;
138 fifoData->SetPeriodCount(curCount);
139 if (fifoData->GetPeriodCount() % periodCount != 0UL) {
140 continue;
141 }
142 fifoData->SetPeriodCount(0);
143 std::vector<SensorData> fifoDataList = fifoData->GetFifoCacheData();
144 fifoDataList.push_back(data);
145 fifoData->SetFifoCacheData(fifoDataList);
146 if ((fifoData->GetFifoCacheData()).size() != fifoCount) {
147 continue;
148 }
149 SendRawData(cacheBuf, channel, fifoData->GetFifoCacheData());
150 fifoData->InitFifoCache();
151 return;
152 }
153 // cannot find channel in channelFifoList
154 if (!channelExist) {
155 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
156 CHKPV(fifoCacheData);
157 fifoCacheData->SetChannel(channel);
158 dataCountIt->second.push_back(fifoCacheData);
159 }
160 }
161
ReportData(sptr<SensorBasicDataChannel> & channel,SensorData & data)162 void SensorDataProcesser::ReportData(sptr<SensorBasicDataChannel> &channel, SensorData &data)
163 {
164 CHKPV(channel);
165 int32_t sensorId = data.sensorTypeId;
166 if (sensorId == SENSOR_TYPE_ID_HALL_EXT) {
167 PrintSensorData::GetInstance().PrintSensorDataLog("ReportData", data);
168 }
169 auto &cacheBuf = const_cast<std::unordered_map<int32_t, SensorData> &>(channel->GetDataCacheBuf());
170 if (ReportNotContinuousData(cacheBuf, channel, data)) {
171 return;
172 }
173 uint64_t periodCount = clientInfo_.ComputeBestPeriodCount(sensorId, channel);
174 if (periodCount == 0UL) {
175 SEN_HILOGE("periodCount is zero");
176 return;
177 }
178 auto fifoCount = clientInfo_.ComputeBestFifoCount(sensorId, channel);
179 if (fifoCount <= 1) {
180 SendNoneFifoCacheData(cacheBuf, channel, data, periodCount);
181 return;
182 }
183 SendFifoCacheData(cacheBuf, channel, data, periodCount, fifoCount);
184 }
185
ReportNotContinuousData(std::unordered_map<int32_t,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> & channel,SensorData & data)186 bool SensorDataProcesser::ReportNotContinuousData(std::unordered_map<int32_t, SensorData> &cacheBuf,
187 sptr<SensorBasicDataChannel> &channel, SensorData &data)
188 {
189 int32_t sensorId = data.sensorTypeId;
190 std::lock_guard<std::mutex> sensorLock(sensorMutex_);
191 auto sensor = sensorMap_.find(sensorId);
192 if (sensor == sensorMap_.end()) {
193 SEN_HILOGE("Data's sensorId is not supported");
194 return false;
195 }
196 sensor->second.SetFlags(data.mode);
197 if (((SENSOR_ON_CHANGE & sensor->second.GetFlags()) == SENSOR_ON_CHANGE) ||
198 ((SENSOR_ONE_SHOT & sensor->second.GetFlags()) == SENSOR_ONE_SHOT)) {
199 std::vector<SensorData> sendEvents;
200 sendEvents.push_back(data);
201 if (sensorId == SENSOR_TYPE_ID_HALL_EXT) {
202 PrintSensorData::GetInstance().PrintSensorDataLog("ReportNotContinuousData", data);
203 }
204 SendRawData(cacheBuf, channel, sendEvents);
205 return true;
206 }
207 return false;
208 }
209
SendRawData(std::unordered_map<int32_t,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> channel,std::vector<SensorData> events)210 void SensorDataProcesser::SendRawData(std::unordered_map<int32_t, SensorData> &cacheBuf,
211 sptr<SensorBasicDataChannel> channel, std::vector<SensorData> events)
212 {
213 CHKPV(channel);
214 if (events.empty()) {
215 return;
216 }
217 size_t eventSize = events.size();
218 auto ret = channel->SendData(events.data(), eventSize * sizeof(SensorData));
219 if (ret != ERR_OK) {
220 SEN_HILOGE("Send data failed, ret:%{public}d, sensorId:%{public}d, timestamp:%{public}" PRId64,
221 ret, events[eventSize - 1].sensorTypeId, events[eventSize - 1].timestamp);
222 int32_t sensorId = events[eventSize - 1].sensorTypeId;
223 cacheBuf[sensorId] = events[eventSize - 1];
224 }
225 }
226
CacheSensorEvent(const SensorData & data,sptr<SensorBasicDataChannel> & channel)227 int32_t SensorDataProcesser::CacheSensorEvent(const SensorData &data, sptr<SensorBasicDataChannel> &channel)
228 {
229 CHKPR(channel, INVALID_POINTER);
230 int32_t ret = ERR_OK;
231 auto &cacheBuf = const_cast<std::unordered_map<int32_t, SensorData> &>(channel->GetDataCacheBuf());
232 int32_t sensorId = data.sensorTypeId;
233 if (sensorId == SENSOR_TYPE_ID_HALL_EXT) {
234 PrintSensorData::GetInstance().PrintSensorDataLog("CacheSensorEvent", data);
235 }
236 auto cacheEvent = cacheBuf.find(sensorId);
237 if (cacheEvent != cacheBuf.end()) {
238 // Try to send the last failed value, if it still fails, replace the previous cache directly
239 const SensorData &cacheData = cacheEvent->second;
240 ret = channel->SendData(&cacheData, sizeof(SensorData));
241 if (ret != ERR_OK) {
242 SEN_HILOGE("retry send cache data failed, ret:%{public}d, sensorId:%{public}d, timestamp:%{public}" PRId64,
243 ret, cacheData.sensorTypeId, cacheData.timestamp);
244 }
245 ret = channel->SendData(&data, sizeof(SensorData));
246 if (ret != ERR_OK) {
247 SEN_HILOGE("retry send data failed, ret:%{public}d, sensorId:%{public}d, timestamp:%{public}" PRId64,
248 ret, data.sensorTypeId, data.timestamp);
249 cacheBuf[sensorId] = data;
250 } else {
251 cacheBuf.erase(cacheEvent);
252 }
253 } else {
254 ret = channel->SendData(&data, sizeof(SensorData));
255 if (ret != ERR_OK) {
256 SEN_HILOGE("directly retry failed, ret:%{public}d, sensorId:%{public}d, timestamp:%{public}" PRId64,
257 ret, data.sensorTypeId, data.timestamp);
258 cacheBuf[sensorId] = data;
259 }
260 }
261 return ret;
262 }
263
EventFilter(CircularEventBuf & eventsBuf)264 void SensorDataProcesser::EventFilter(CircularEventBuf &eventsBuf)
265 {
266 int32_t sensorId = eventsBuf.circularBuf[eventsBuf.readPos].sensorTypeId;
267 if (sensorId == SENSOR_TYPE_ID_HALL_EXT) {
268 PrintSensorData::GetInstance().PrintSensorDataLog("EventFilter", eventsBuf.circularBuf[eventsBuf.readPos]);
269 }
270 std::vector<sptr<SensorBasicDataChannel>> channelList = clientInfo_.GetSensorChannel(sensorId);
271 for (auto &channel : channelList) {
272 if (!channel->GetSensorStatus()) {
273 SEN_HILOGW("Sensor status is not active");
274 continue;
275 }
276 SendEvents(channel, eventsBuf.circularBuf[eventsBuf.readPos]);
277 }
278 }
279
ProcessEvents(sptr<ReportDataCallback> dataCallback)280 int32_t SensorDataProcesser::ProcessEvents(sptr<ReportDataCallback> dataCallback)
281 {
282 CHKPR(dataCallback, INVALID_POINTER);
283 std::unique_lock<std::mutex> lk(ISensorHdiConnection::dataMutex_);
284 ISensorHdiConnection::dataCondition_.wait(lk, [this] { return ISensorHdiConnection::dataReady_.load(); });
285 ISensorHdiConnection::dataReady_.store(false);
286 auto &eventsBuf = dataCallback->GetEventData();
287 if (eventsBuf.eventNum <= 0) {
288 SEN_HILOGE("Data cannot be empty");
289 return NO_EVENT;
290 }
291 int32_t eventNum = eventsBuf.eventNum;
292 for (int32_t i = 0; i < eventNum; i++) {
293 EventFilter(eventsBuf);
294 eventsBuf.readPos++;
295 if (eventsBuf.readPos >= CIRCULAR_BUF_LEN) {
296 eventsBuf.readPos = 0;
297 }
298 eventsBuf.eventNum--;
299 }
300 return SUCCESS;
301 }
302
SendEvents(sptr<SensorBasicDataChannel> & channel,SensorData & data)303 int32_t SensorDataProcesser::SendEvents(sptr<SensorBasicDataChannel> &channel, SensorData &data)
304 {
305 CHKPR(channel, INVALID_POINTER);
306 clientInfo_.UpdateDataQueue(data.sensorTypeId, data);
307 auto &cacheBuf = channel->GetDataCacheBuf();
308 if (cacheBuf.empty()) {
309 ReportData(channel, data);
310 } else {
311 CacheSensorEvent(data, channel);
312 }
313 clientInfo_.StoreEvent(data);
314 return SUCCESS;
315 }
316
DataThread(sptr<SensorDataProcesser> dataProcesser,sptr<ReportDataCallback> dataCallback)317 int32_t SensorDataProcesser::DataThread(sptr<SensorDataProcesser> dataProcesser, sptr<ReportDataCallback> dataCallback)
318 {
319 CALL_LOG_ENTER;
320 prctl(PR_SET_NAME, SENSOR_REPORT_THREAD_NAME.c_str());
321 do {
322 if (dataProcesser == nullptr || dataCallback == nullptr) {
323 SEN_HILOGE("dataProcesser or dataCallback is nullptr");
324 return INVALID_POINTER;
325 }
326 if (dataProcesser->ProcessEvents(dataCallback) == INVALID_POINTER) {
327 SEN_HILOGE("Callback cannot be null");
328 return INVALID_POINTER;
329 }
330 } while (1);
331 }
332 } // namespace Sensors
333 } // namespace OHOS
334