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
22 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
23 #include "hisysevent.h"
24 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
25 #include "motion_plugin.h"
26 #include "print_sensor_data.h"
27
28 #undef LOG_TAG
29 #define LOG_TAG "SensorDataProcesser"
30
31 namespace OHOS {
32 namespace Sensors {
33 using namespace OHOS::HiviewDFX;
34
35 namespace {
36 const std::string SENSOR_REPORT_THREAD_NAME = "OS_SenProducer";
37 const std::set<int32_t> g_noNeedMotionTransform = {
38 SENSOR_TYPE_ID_POSTURE, SENSOR_TYPE_ID_HALL, SENSOR_TYPE_ID_HALL_EXT,
39 SENSOR_TYPE_ID_PROXIMITY, SENSOR_TYPE_ID_PROXIMITY1, SENSOR_TYPE_ID_AMBIENT_LIGHT
40 };
41 } // namespace
42
SensorDataProcesser(const std::unordered_map<SensorDescription,Sensor> & sensorMap)43 SensorDataProcesser::SensorDataProcesser(const std::unordered_map<SensorDescription, Sensor> &sensorMap)
44 {
45 sensorMap_.insert(sensorMap.begin(), sensorMap.end());
46 SEN_HILOGD("sensorMap_.size:%{public}d", int32_t { sensorMap_.size() });
47 }
48
~SensorDataProcesser()49 SensorDataProcesser::~SensorDataProcesser()
50 {
51 dataCountMap_.clear();
52 sensorMap_.clear();
53 }
54
UpdateSensorMap(const std::unordered_map<SensorDescription,Sensor> & sensorMap)55 void SensorDataProcesser::UpdateSensorMap(const std::unordered_map<SensorDescription, Sensor> &sensorMap)
56 {
57 sensorMap_.clear();
58 sensorMap_.insert(sensorMap.begin(), sensorMap.end());
59 SEN_HILOGD("sensorMap_.size:%{public}d", int32_t { sensorMap_.size() });
60 }
61
SendNoneFifoCacheData(std::unordered_map<SensorDescription,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> & channel,SensorData & data,uint64_t periodCount)62 void SensorDataProcesser::SendNoneFifoCacheData(std::unordered_map<SensorDescription, SensorData> &cacheBuf,
63 sptr<SensorBasicDataChannel> &channel, SensorData &data,
64 uint64_t periodCount)
65 {
66 std::vector<SensorData> sendEvents;
67 std::lock_guard<std::mutex> dataCountLock(dataCountMutex_);
68 sendEvents.push_back(data);
69 auto dataCountIt = dataCountMap_.find({data.deviceId, data.sensorTypeId, data.sensorId, data.location});
70 if (dataCountIt == dataCountMap_.end()) {
71 std::vector<sptr<FifoCacheData>> channelFifoList;
72 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
73 CHKPV(fifoCacheData);
74 fifoCacheData->SetChannel(channel);
75 channelFifoList.push_back(fifoCacheData);
76 dataCountMap_.insert(std::pair<SensorDescription, std::vector<sptr<FifoCacheData>>>(
77 {data.deviceId, data.sensorTypeId, data.sensorId, data.location}, channelFifoList));
78 SendRawData(cacheBuf, channel, sendEvents);
79 return;
80 }
81 bool channelExist = false;
82 for (auto fifoIt = dataCountIt->second.begin(); fifoIt != dataCountIt->second.end();) {
83 auto fifoCacheData = *fifoIt;
84 CHKPC(fifoCacheData);
85 auto fifoChannel = fifoCacheData->GetChannel();
86 if (fifoChannel == nullptr) {
87 fifoIt = dataCountIt->second.erase(fifoIt);
88 continue;
89 }
90 ++fifoIt;
91 if (fifoChannel != channel) {
92 continue;
93 }
94 channelExist = true;
95 uint64_t curCount = fifoCacheData->GetPeriodCount();
96 curCount++;
97 fifoCacheData->SetPeriodCount(curCount);
98 if (periodCount != 0 && fifoCacheData->GetPeriodCount() % periodCount != 0UL) {
99 continue;
100 }
101 SendRawData(cacheBuf, channel, sendEvents);
102 fifoCacheData->SetPeriodCount(0);
103 return;
104 }
105 if (!channelExist) {
106 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
107 CHKPV(fifoCacheData);
108 fifoCacheData->SetChannel(channel);
109 dataCountIt->second.push_back(fifoCacheData);
110 SendRawData(cacheBuf, channel, sendEvents);
111 }
112 }
113
SendFifoCacheData(std::unordered_map<SensorDescription,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> & channel,SensorData & data,uint64_t periodCount,uint64_t fifoCount)114 void SensorDataProcesser::SendFifoCacheData(std::unordered_map<SensorDescription, SensorData> &cacheBuf,
115 sptr<SensorBasicDataChannel> &channel, SensorData &data,
116 uint64_t periodCount, uint64_t fifoCount)
117 {
118 std::lock_guard<std::mutex> dataCountLock(dataCountMutex_);
119 auto dataCountIt = dataCountMap_.find({data.deviceId, data.sensorTypeId, data.sensorId, data.location});
120 // there is no channelFifoList
121 if (dataCountIt == dataCountMap_.end()) {
122 std::vector<sptr<FifoCacheData>> channelFifoList;
123 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
124 CHKPV(fifoCacheData);
125 fifoCacheData->SetChannel(channel);
126 channelFifoList.push_back(fifoCacheData);
127 dataCountMap_.insert(std::pair<SensorDescription, std::vector<sptr<FifoCacheData>>>(
128 {data.deviceId, data.sensorTypeId, data.sensorId, data.location}, channelFifoList));
129 return;
130 }
131 // find channel in channelFifoList
132 bool channelExist = false;
133 for (auto fifoIt = dataCountIt->second.begin(); fifoIt != dataCountIt->second.end();) {
134 auto fifoData = *fifoIt;
135 CHKPC(fifoData);
136 auto fifoChannel = fifoData->GetChannel();
137 if (fifoChannel == nullptr) {
138 fifoIt = dataCountIt->second.erase(fifoIt);
139 continue;
140 }
141 ++fifoIt;
142 if (fifoChannel != channel) {
143 continue;
144 }
145 channelExist = true;
146 uint64_t curCount = fifoData->GetPeriodCount();
147 curCount++;
148 fifoData->SetPeriodCount(curCount);
149 if (fifoData->GetPeriodCount() % periodCount != 0UL) {
150 continue;
151 }
152 fifoData->SetPeriodCount(0);
153 std::vector<SensorData> fifoDataList = fifoData->GetFifoCacheData();
154 fifoDataList.push_back(data);
155 fifoData->SetFifoCacheData(fifoDataList);
156 if ((fifoData->GetFifoCacheData()).size() != fifoCount) {
157 continue;
158 }
159 SendRawData(cacheBuf, channel, fifoData->GetFifoCacheData());
160 fifoData->InitFifoCache();
161 return;
162 }
163 // cannot find channel in channelFifoList
164 if (!channelExist) {
165 UpdataFifoDataChannel(channel, dataCountIt->second);
166 }
167 }
168
UpdataFifoDataChannel(sptr<SensorBasicDataChannel> & channel,std::vector<sptr<FifoCacheData>> & dataCount)169 void SensorDataProcesser::UpdataFifoDataChannel(sptr<SensorBasicDataChannel> &channel,
170 std::vector<sptr<FifoCacheData>> &dataCount)
171 {
172 sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
173 CHKPV(fifoCacheData);
174 fifoCacheData->SetChannel(channel);
175 dataCount.push_back(fifoCacheData);
176 }
177
ReportData(sptr<SensorBasicDataChannel> & channel,SensorData & data)178 void SensorDataProcesser::ReportData(sptr<SensorBasicDataChannel> &channel, SensorData &data)
179 {
180 CHKPV(channel);
181 int32_t sensorTypeId = data.sensorTypeId;
182 if (sensorTypeId == SENSOR_TYPE_ID_HALL_EXT) {
183 PrintSensorData::GetInstance().PrintSensorDataLog("ReportData", data);
184 }
185 auto &cacheBuf = const_cast<std::unordered_map<SensorDescription, SensorData> &>(channel->GetDataCacheBuf());
186 if (ReportNotContinuousData(cacheBuf, channel, data)) {
187 return;
188 }
189 uint64_t periodCount = clientInfo_.ComputeBestPeriodCount({data.deviceId, data.sensorTypeId, data.sensorId,
190 data.location}, channel);
191 if (periodCount == 0UL) {
192 SEN_HILOGE("periodCount is zero");
193 return;
194 }
195 auto fifoCount = clientInfo_.ComputeBestFifoCount({data.deviceId, data.sensorTypeId, data.sensorId,
196 data.location}, channel);
197 if (fifoCount <= 1) {
198 SendNoneFifoCacheData(cacheBuf, channel, data, periodCount);
199 return;
200 }
201 SendFifoCacheData(cacheBuf, channel, data, periodCount, fifoCount);
202 }
203
ReportNotContinuousData(std::unordered_map<SensorDescription,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> & channel,SensorData & data)204 bool SensorDataProcesser::ReportNotContinuousData(std::unordered_map<SensorDescription, SensorData> &cacheBuf,
205 sptr<SensorBasicDataChannel> &channel, SensorData &data)
206 {
207 int32_t sensorTypeId = data.sensorTypeId;
208 std::lock_guard<std::mutex> sensorLock(sensorMutex_);
209 auto sensor = sensorMap_.find({data.deviceId, data.sensorTypeId, data.sensorId, data.location});
210 if (sensor == sensorMap_.end()) {
211 SEN_HILOGE("Data's SensorDesc is not supported");
212 return false;
213 }
214 sensor->second.SetFlags(data.mode);
215 if (((SENSOR_ON_CHANGE & sensor->second.GetFlags()) == SENSOR_ON_CHANGE) ||
216 ((SENSOR_ONE_SHOT & sensor->second.GetFlags()) == SENSOR_ONE_SHOT)) {
217 std::vector<SensorData> sendEvents;
218 sendEvents.push_back(data);
219 if (sensorTypeId == SENSOR_TYPE_ID_HALL_EXT) {
220 PrintSensorData::GetInstance().PrintSensorDataLog("ReportNotContinuousData", data);
221 }
222 SendRawData(cacheBuf, channel, sendEvents);
223 return true;
224 }
225 return false;
226 }
227
SendRawData(std::unordered_map<SensorDescription,SensorData> & cacheBuf,sptr<SensorBasicDataChannel> channel,std::vector<SensorData> events)228 void SensorDataProcesser::SendRawData(std::unordered_map<SensorDescription, SensorData> &cacheBuf,
229 sptr<SensorBasicDataChannel> channel, std::vector<SensorData> events)
230 {
231 CHKPV(channel);
232 if (events.empty()) {
233 return;
234 }
235 size_t eventSize = events.size();
236 auto ret = channel->SendData(events.data(), eventSize * sizeof(SensorData));
237 if (ret != ERR_OK) {
238 SEN_HILOGE("Send data failed, ret:%{public}d, sensorTypeId:%{public}d, timestamp:%{public}" PRId64,
239 ret, events[eventSize - 1].sensorTypeId, events[eventSize - 1].timestamp);
240 cacheBuf[{events[eventSize - 1].deviceId, events[eventSize - 1].sensorTypeId,
241 events[eventSize - 1].sensorId, events[eventSize - 1].location}] = events[eventSize - 1];
242 }
243 }
244
CacheSensorEvent(const SensorData & data,sptr<SensorBasicDataChannel> & channel)245 int32_t SensorDataProcesser::CacheSensorEvent(const SensorData &data, sptr<SensorBasicDataChannel> &channel)
246 {
247 CHKPR(channel, INVALID_POINTER);
248 int32_t ret = ERR_OK;
249 auto &cacheBuf = const_cast<std::unordered_map<SensorDescription, SensorData> &>(channel->GetDataCacheBuf());
250 if (data.sensorTypeId == SENSOR_TYPE_ID_HALL_EXT) {
251 PrintSensorData::GetInstance().PrintSensorDataLog("CacheSensorEvent", data);
252 }
253 auto cacheEvent = cacheBuf.find({data.deviceId, data.sensorTypeId, data.sensorId, data.location});
254 if (cacheEvent != cacheBuf.end()) {
255 // Try to send the last failed value, if it still fails, replace the previous cache directly
256 const SensorData &cacheData = cacheEvent->second;
257 ret = channel->SendData(&cacheData, sizeof(SensorData));
258 if (ret != ERR_OK) {
259 SEN_HILOGE("retry send cacheData failed, ret:%{public}d, sensorType:%{public}d, timestamp:%{public}" PRId64,
260 ret, cacheData.sensorTypeId, cacheData.timestamp);
261 }
262 ret = channel->SendData(&data, sizeof(SensorData));
263 if (ret != ERR_OK) {
264 SEN_HILOGE("retry send data failed, ret:%{public}d, sensorType:%{public}d, timestamp:%{public}" PRId64,
265 ret, data.sensorTypeId, data.timestamp);
266 cacheBuf[{data.deviceId, data.sensorTypeId, data.sensorId, data.location}] = data;
267 } else {
268 cacheBuf.erase(cacheEvent);
269 }
270 } else {
271 ret = channel->SendData(&data, sizeof(SensorData));
272 if (ret != ERR_OK) {
273 SEN_HILOGE("directly retry failed, ret:%{public}d, sensorType:%{public}d, timestamp:%{public}" PRId64,
274 ret, data.sensorTypeId, data.timestamp);
275 cacheBuf[{data.deviceId, data.sensorTypeId, data.sensorId, data.location}] = data;
276 }
277 }
278 return ret;
279 }
280
EventFilter(CircularEventBuf & eventsBuf)281 void SensorDataProcesser::EventFilter(CircularEventBuf &eventsBuf)
282 {
283 if (eventsBuf.circularBuf[eventsBuf.readPos].sensorTypeId == SENSOR_TYPE_ID_HALL_EXT) {
284 PrintSensorData::GetInstance().PrintSensorDataLog("EventFilter", eventsBuf.circularBuf[eventsBuf.readPos]);
285 }
286 std::vector<sptr<SensorBasicDataChannel>> channelList = clientInfo_.GetSensorChannel({
287 eventsBuf.circularBuf[eventsBuf.readPos].deviceId, eventsBuf.circularBuf[eventsBuf.readPos].sensorTypeId,
288 eventsBuf.circularBuf[eventsBuf.readPos].sensorId, eventsBuf.circularBuf[eventsBuf.readPos].location});
289 for (auto &channel : channelList) {
290 if (channel == nullptr) {
291 SEN_HILOGE("channel is null");
292 continue;
293 }
294 if (!channel->GetSensorStatus()) {
295 SEN_HILOGW("Sensor status is not active");
296 continue;
297 }
298 SensorData sensorData = eventsBuf.circularBuf[eventsBuf.readPos];
299 #ifdef MSDP_MOTION_ENABLE
300 if (g_noNeedMotionTransform.find(sensorData.sensorTypeId) == g_noNeedMotionTransform.end()) {
301 MotionTransformIfRequired(channel->GetPackageName(), clientInfo_.GetDeviceStatus(), &sensorData);
302 }
303 #endif // MSDP_MOTION_ENABLE
304 SendEvents(channel, sensorData);
305 }
306 }
307
ProcessEvents(sptr<ReportDataCallback> dataCallback)308 int32_t SensorDataProcesser::ProcessEvents(sptr<ReportDataCallback> dataCallback)
309 {
310 CHKPR(dataCallback, INVALID_POINTER);
311 std::unique_lock<std::mutex> lk(ISensorHdiConnection::dataMutex_);
312 ISensorHdiConnection::dataCondition_.wait(lk, [this] { return ISensorHdiConnection::dataReady_.load(); });
313 ISensorHdiConnection::dataReady_.store(false);
314 auto &eventsBuf = dataCallback->GetEventData();
315 if (eventsBuf.eventNum <= 0) {
316 SEN_HILOGE("Data cannot be empty");
317 return NO_EVENT;
318 }
319 int32_t eventNum = eventsBuf.eventNum;
320 for (int32_t i = 0; i < eventNum; i++) {
321 EventFilter(eventsBuf);
322 eventsBuf.readPos++;
323 if (eventsBuf.readPos >= CIRCULAR_BUF_LEN) {
324 eventsBuf.readPos = 0;
325 }
326 eventsBuf.eventNum--;
327 }
328 return SUCCESS;
329 }
330
SendEvents(sptr<SensorBasicDataChannel> & channel,SensorData & data)331 int32_t SensorDataProcesser::SendEvents(sptr<SensorBasicDataChannel> &channel, SensorData &data)
332 {
333 CHKPR(channel, INVALID_POINTER);
334 clientInfo_.UpdateDataQueue(data.sensorTypeId, data);
335 auto &cacheBuf = channel->GetDataCacheBuf();
336 if (cacheBuf.empty()) {
337 ReportData(channel, data);
338 } else {
339 CacheSensorEvent(data, channel);
340 }
341 clientInfo_.StoreEvent(data);
342 return SUCCESS;
343 }
344
DataThread(sptr<SensorDataProcesser> dataProcesser,sptr<ReportDataCallback> dataCallback)345 int32_t SensorDataProcesser::DataThread(sptr<SensorDataProcesser> dataProcesser, sptr<ReportDataCallback> dataCallback)
346 {
347 CALL_LOG_ENTER;
348 prctl(PR_SET_NAME, SENSOR_REPORT_THREAD_NAME.c_str());
349 do {
350 if (dataProcesser == nullptr || dataCallback == nullptr) {
351 SEN_HILOGE("dataProcesser or dataCallback is nullptr");
352 return INVALID_POINTER;
353 }
354 if (dataProcesser->ProcessEvents(dataCallback) == INVALID_POINTER) {
355 SEN_HILOGE("Callback cannot be null");
356 return INVALID_POINTER;
357 }
358 } while (1);
359 }
360 } // namespace Sensors
361 } // namespace OHOS
362