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