• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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