• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_callback_vdi.h"
17 #include "osal_mem.h"
18 #include <securec.h>
19 #include <unordered_map>
20 
21 #define HDF_LOG_TAG cb
22 
23 namespace OHOS {
24 namespace HDI {
25 namespace Sensor {
26 namespace V3_0 {
27 namespace {
28     constexpr int32_t DATA_LEN = 256;
29     constexpr int64_t REPOPRT_TIME = 60000000000;
30     constexpr int64_t INIT_DATA_COUNT = 1;
31     constexpr double DEFAULT_ERROR_RATIO = 0.1; // 10% error ratio
32     constexpr int64_t DEFAULT_ACCEPTABLE_ERROR = 2;
33     constexpr double COMMON_REPORT_FREQUENCY = 1000000000.0;
34     constexpr int32_t ONE_SECOND = 1000;
35     static std::unordered_map<SensorHandle, int64_t> firstTimestampMap_;
36     static std::unordered_map<SensorHandle, int64_t> lastTimestampMap_;
37     const std::vector<int32_t> NEED_PRINT_COUNT_SENSOR = {
38         HDF_SENSOR_TYPE_ACCELEROMETER, HDF_SENSOR_TYPE_GYROSCOPE, HDF_SENSOR_TYPE_MAGNETIC_FIELD,
39         HDF_SENSOR_TYPE_LINEAR_ACCELERATION, HDF_SENSOR_TYPE_ROTATION_VECTOR, HDF_SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
40         HDF_SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED};
41 }
42 
OnDataEventVdi(const OHOS::HDI::Sensor::V1_1::HdfSensorEventsVdi & eventVdi)43 int32_t SensorCallbackVdi::OnDataEventVdi(const OHOS::HDI::Sensor::V1_1::HdfSensorEventsVdi& eventVdi)
44 {
45     HITRACE_METER_FMT(HITRACE_TAG_HDF, "%s: sensorId %d", __func__, eventVdi.sensorId);
46     struct V3_0::HdfSensorEvents event;
47     event.version = eventVdi.version;
48     event.timestamp = eventVdi.timestamp;
49     event.option = eventVdi.option;
50     event.mode = eventVdi.mode;
51     event.data = eventVdi.data;
52     event.dataLen = eventVdi.dataLen;
53 #ifdef TV_FLAG
54     event.deviceSensorInfo = eventVdi.deviceSensorInfo;
55 #else
56     event.deviceSensorInfo = {DEFAULT_DEVICE_ID, eventVdi.sensorId, DEFAULT_SENSOR_ID, DEFAULT_LOCATION};
57 #endif
58     int32_t ret = OnDataEvent(event);
59     return ret;
60 }
61 
OnDataEvent(const V3_0::HdfSensorEvents & event)62 int32_t SensorCallbackVdi::OnDataEvent(const V3_0::HdfSensorEvents& event)
63 {
64     SensorHandle sensorHandle = {event.deviceSensorInfo.deviceId, event.deviceSensorInfo.sensorType,
65                                  event.deviceSensorInfo.sensorId, event.deviceSensorInfo.location};
66     HITRACE_METER_FMT(HITRACE_TAG_HDF, "%s: sensorHandle %s", __func__, SENSOR_HANDLE_TO_C_STR(event.deviceSensorInfo));
67     SensorClientsManager::GetInstance()->CopyEventData(event);
68     const std::string reportResult = SensorClientsManager::GetInstance()->ReportEachClient(event);
69     HDF_LOGD("%{public}s sensorHandle=%{public}s, %{public}s", __func__, SENSOR_HANDLE_TO_C_STR(event.deviceSensorInfo),
70              reportResult.c_str());
71     PrintData(event, reportResult, sensorHandle);
72     return HDF_SUCCESS;
73 }
74 
PrintData(const HdfSensorEvents & event,const std::string & reportResult,const SensorHandle & sensorHandle)75 void SensorCallbackVdi::PrintData(const HdfSensorEvents &event, const std::string &reportResult,
76                                   const SensorHandle& sensorHandle)
77 {
78     SENSOR_TRACE;
79     bool isPrint = SensorClientsManager::GetInstance()->IsSensorNeedPrint(sensorHandle);
80     int64_t samplingInterval = SensorClientsManager::GetInstance()->GetSensorBestSamplingInterval(sensorHandle);
81 
82     std::unique_lock<std::mutex> lock(timestampMapMutex_);
83     static std::unordered_map<SensorHandle, int64_t> sensorDataCountMap;
84     auto it = sensorDataCountMap.find(sensorHandle);
85     int64_t dataCount = INIT_DATA_COUNT;
86     if (it == sensorDataCountMap.end()) {
87         sensorDataCountMap[sensorHandle] = INIT_DATA_COUNT;
88     } else {
89         it->second++;
90         dataCount = it->second;
91     }
92     if (NeedPrintCount(sensorHandle)) {
93         PrintCount(sensorHandle, sensorDataCountMap, samplingInterval);
94     }
95     bool result = isPrint;
96     if (!isPrint) {
97         if (firstTimestampMap_[sensorHandle] == 0) {
98             firstTimestampMap_[sensorHandle] = event.timestamp;
99             result = true;
100         } else {
101             lastTimestampMap_[sensorHandle] = event.timestamp;
102         }
103         if (lastTimestampMap_[sensorHandle] - firstTimestampMap_[sensorHandle] >= REPOPRT_TIME) {
104             firstTimestampMap_[sensorHandle] = lastTimestampMap_[sensorHandle];
105             result = true;
106         }
107     }
108 
109     if (result) {
110         std::string st = {0};
111         DataToStr(st, event);
112         st += " sampling=" + std::to_string(dataCount);
113         st += reportResult;
114         HDF_LOGI("%{public}s:%{public}s", __func__, st.c_str());
115     }
116 }
117 
DataToStr(std::string & str,const HdfSensorEvents & event)118 void SensorCallbackVdi::DataToStr(std::string &str, const HdfSensorEvents &event)
119 {
120     if (event.dataLen < static_cast<int>(sizeof(float)) || event.dataLen > DATA_LEN) {
121         HDF_LOGE("%{public}s: invalid dataLen: %d", __func__, event.dataLen);
122         return;
123     }
124     void *origin = OsalMemCalloc(sizeof(uint8_t) * (event.dataLen));
125     if (origin == nullptr) {
126         HDF_LOGE("%{public}s: OsalMemCalloc failed", __func__);
127         return;
128     }
129 
130     uint8_t *eventData = static_cast<uint8_t*>(origin);
131     std::copy(event.data.begin(), event.data.end(), eventData);
132     float *data = reinterpret_cast<float*>(eventData);
133     int32_t dataLen = event.dataLen;
134     int32_t dataDimension = static_cast<int32_t>(dataLen / sizeof(float));
135     std::string dataStr = {0};
136     char arrayStr[DATA_LEN] = {0};
137 
138     for (int32_t i = 0; i < dataDimension; i++) {
139         int32_t ilen = DATA_LEN - strlen(arrayStr) - 1;
140         if (ilen <= 0) {
141             HDF_LOGE("%{public}s: bufferover failed", __func__);
142             OsalMemFree(origin);
143             return;
144         }
145         if (sprintf_s(arrayStr + strlen(arrayStr), ilen, "[%f]", data[i]) < 0) {
146             HDF_LOGE("%{public}s: sprintf_s failed", __func__);
147             OsalMemFree(origin);
148             return;
149         }
150     }
151 
152     dataStr = arrayStr;
153     str = SENSOR_HANDLE_TO_STRING(event.deviceSensorInfo) + " ts " +
154         std::to_string(event.timestamp / 1e9) + " data " + dataStr;
155 
156     OsalMemFree(origin);
157     return;
158 }
159 
NeedPrintCount(SensorHandle sensorHandle)160 bool SensorCallbackVdi::NeedPrintCount(SensorHandle sensorHandle)
161 {
162     return std::find(NEED_PRINT_COUNT_SENSOR.begin(), NEED_PRINT_COUNT_SENSOR.end(),
163         sensorHandle.sensorType) != NEED_PRINT_COUNT_SENSOR.end();
164 }
165 
PrintCount(const SensorHandle & sensorHandle,const std::unordered_map<SensorHandle,int64_t> & sensorDataCountMap,const int64_t & samplingInterval)166 void SensorCallbackVdi::PrintCount(const SensorHandle& sensorHandle,
167     const std::unordered_map<SensorHandle, int64_t> &sensorDataCountMap, const int64_t &samplingInterval)
168 {
169     static std::unordered_map<SensorHandle, std::chrono::steady_clock::time_point> lastRecordTimeMap;
170     static std::unordered_map<SensorHandle, int64_t> lastDataCountMap;
171 
172     //Get the last recorded time and number of records
173     auto lastRecordTimeIt = lastRecordTimeMap.find(sensorHandle);
174     if (lastRecordTimeIt == lastRecordTimeMap.end()) {
175         lastRecordTimeIt = lastRecordTimeMap.emplace(sensorHandle, std::chrono::steady_clock::now()).first;
176     }
177     auto lastDataCountIt = lastDataCountMap.find(sensorHandle);
178     if (lastDataCountIt == lastDataCountMap.end()) {
179         lastDataCountIt = lastDataCountMap.emplace(sensorHandle, 0).first;
180     }
181     std::chrono::steady_clock::time_point &lastRecordTime = lastRecordTimeIt->second;
182     int64_t &lastDataCount = lastDataCountIt->second;
183 
184     //Get the current record time and number of records
185     std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now();
186     int64_t currentDataCount = 0;
187     auto sensorDataCountIt = sensorDataCountMap.find(sensorHandle);
188     if (sensorDataCountIt != sensorDataCountMap.end()) {
189         currentDataCount = sensorDataCountIt->second;
190     }
191 
192     //Calculate the sensor data and allowable error that should be reported based on frequency
193     int64_t targetCount = 0;
194     if (samplingInterval > 0) {
195         targetCount = std::ceil(COMMON_REPORT_FREQUENCY / (double)samplingInterval);
196     }
197     int64_t acceptablError = std::ceil((double)targetCount * DEFAULT_ERROR_RATIO);
198     if (acceptablError == 0) {
199         acceptablError = DEFAULT_ACCEPTABLE_ERROR; // Ensure there's always some tolerance
200     }
201 
202     //Check if the current record time exceeds one second
203     if (std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRecordTime).count() >= ONE_SECOND) {
204         int64_t perSecondCount = currentDataCount - lastDataCount;
205 
206         lastRecordTime += std::chrono::milliseconds(ONE_SECOND);
207         lastDataCount = currentDataCount;
208 
209         if (perSecondCount >= targetCount - acceptablError && perSecondCount <= targetCount + acceptablError) {
210             return; // Skip logging if the count is within acceptable range
211         }
212         HDF_LOGE("%{public}s: %{public}s perSecondCount %{public}s targetCount %{public}s~%{public}s samplingInterval "
213             "%{public}s", __func__, SENSOR_HANDLE_TO_C_STR(sensorHandle), std::to_string(perSecondCount).c_str(),
214             std::to_string(targetCount - acceptablError).c_str(), std::to_string(targetCount + acceptablError).c_str(),
215             std::to_string(samplingInterval / ONE_MILLION).c_str());
216     }
217 }
218 
HandleCallbackDeath()219 sptr<IRemoteObject> SensorCallbackVdi::HandleCallbackDeath()
220 {
221     sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<V3_0::ISensorCallback>(sensorCallback_);
222 
223     return remote;
224 }
225 } // V3_0
226 } // Sensor
227 } // HDI
228 } // OHOS
229