1 /*
2 * Copyright (c) 2024 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 "print_sensor_data.h"
17
18 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
19 #include "hisysevent.h"
20 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
21
22 #include "sensor_errors.h"
23
24 #undef LOG_TAG
25 #define LOG_TAG "PrintSensorData"
26
27 namespace OHOS {
28 namespace Sensors {
29 using namespace OHOS::HiviewDFX;
30 namespace {
31 enum {
32 ONE_DIMENSION = 1,
33 TWO_DIMENSION = 2,
34 THREE_DIMENSION = 3,
35 FOUR_DIMENSION = 4,
36 SEVEN_DIMENSION = 7,
37 EIGHT_DIMENSION = 8,
38 THIRTEEN_DIMENSION = 13,
39 DEFAULT_DIMENSION = 16
40 };
41 constexpr int64_t LOG_INTERVAL = 60000000000L;
42 constexpr int32_t FIRST_PRINT_TIMES = 20;
43 constexpr float LOG_FORMAT_DIVIDER = 1e9f;
44
45 const std::vector<int32_t> g_triggerSensorType = {
46 SENSOR_TYPE_ID_DROP_DETECTION,
47 SENSOR_TYPE_ID_HALL,
48 SENSOR_TYPE_ID_HALL_EXT,
49 SENSOR_TYPE_ID_PROXIMITY,
50 SENSOR_TYPE_ID_PROXIMITY1,
51 SENSOR_TYPE_ID_WEAR_DETECTION,
52 };
53 const std::vector<int32_t> g_continuousSensorType = {
54 SENSOR_TYPE_ID_ACCELEROMETER,
55 SENSOR_TYPE_ID_AMBIENT_LIGHT,
56 SENSOR_TYPE_ID_AMBIENT_LIGHT1,
57 SENSOR_TYPE_ID_GRAVITY,
58 SENSOR_TYPE_ID_GYROSCOPE,
59 SENSOR_TYPE_ID_MAGNETIC_FIELD,
60 SENSOR_TYPE_ID_ORIENTATION,
61 SENSOR_TYPE_ID_POSTURE,
62 SENSOR_TYPE_ID_ROTATION_VECTOR,
63 };
64 }
65
ControlSensorHdiPrint(const SensorData & sensorData)66 void PrintSensorData::ControlSensorHdiPrint(const SensorData &sensorData)
67 {
68 auto triggerIt = std::find(g_triggerSensorType.begin(), g_triggerSensorType.end(), sensorData.sensorTypeId);
69 if (triggerIt != g_triggerSensorType.end()) {
70 PrintHdiData(sensorData);
71 ProcessHdiDFX(sensorData);
72 }
73 std::lock_guard<std::mutex> hdiLoginfoLock(hdiLoginfoMutex_);
74 auto it = hdiLoginfo_.find(sensorData.sensorTypeId);
75 if (it == hdiLoginfo_.end()) {
76 return;
77 }
78 it->second.hdiTimes++;
79 if (it->second.count < FIRST_PRINT_TIMES) {
80 PrintHdiData(sensorData);
81 if (it->second.count == FIRST_PRINT_TIMES - 1) {
82 it->second.lastTime = sensorData.timestamp;
83 }
84 it->second.count++;
85 } else {
86 if (sensorData.timestamp - it->second.lastTime >= LOG_INTERVAL) {
87 PrintHdiData(sensorData);
88 it->second.lastTime = sensorData.timestamp;
89 }
90 }
91 if (it->second.hdiTimesFlag == 0) {
92 it->second.hdiTimesFlag = sensorData.timestamp;
93 }
94 if (sensorData.timestamp - it->second.hdiTimesFlag >= LOG_INTERVAL) {
95 SEN_HILOGI("sensorType:%{public}d, hdiTimes:%{public}s", sensorData.sensorTypeId,
96 std::to_string(it->second.hdiTimes).c_str());
97 it->second.hdiTimesFlag = sensorData.timestamp;
98 it->second.hdiTimes = 0;
99 }
100 }
101
PrintHdiData(const SensorData & sensorData)102 void PrintSensorData::PrintHdiData(const SensorData &sensorData)
103 {
104 std::string str;
105 str += "deviceId:" + std::to_string(sensorData.deviceId) + ", ";
106 str += "sensorType:" + std::to_string(sensorData.sensorTypeId) + ", ";
107 str += "sensorId:" + std::to_string(sensorData.sensorId) + ", ";
108 str += "location:" + std::to_string(sensorData.location) + ", ";
109 str += "timestamp:" + std::to_string(sensorData.timestamp / LOG_FORMAT_DIVIDER) + ", ";
110 int32_t dataDim = GetDataDimension(sensorData.sensorTypeId);
111 auto data = reinterpret_cast<const float *>(sensorData.data);
112 for (int32_t i = 0; i < dataDim; ++i) {
113 CHKPV(data);
114 str.append(std::to_string(*data));
115 if (i != dataDim - 1) {
116 str.append(", ");
117 }
118 ++data;
119 }
120 str.append("\n");
121 SEN_HILOGI("SensorData:%{public}s", str.c_str());
122 }
123
ProcessHdiDFX(const SensorData & sensorData)124 void PrintSensorData::ProcessHdiDFX(const SensorData &sensorData)
125 {
126 std::string strData;
127 auto data = reinterpret_cast<const float *>(sensorData.data);
128 int32_t dataDim = GetDataDimension(sensorData.sensorTypeId);
129 for (int32_t i = 0; i < dataDim; i++) {
130 CHKPV(data);
131 strData.append(std::to_string(*data));
132 if (i != dataDim - 1) {
133 strData.append(", ");
134 }
135 ++data;
136 }
137 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
138 HiSysEventWrite(HiSysEvent::Domain::SENSOR, "EVENT_REPORT",
139 HiSysEvent::EventType::BEHAVIOR, "SENSOR_ID", sensorData.sensorTypeId, "TIMESTAMP",
140 std::to_string(sensorData.timestamp), "DATA", strData);
141 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
142 }
143
GetDataDimension(int32_t sensorType)144 int32_t PrintSensorData::GetDataDimension(int32_t sensorType)
145 {
146 switch (sensorType) {
147 case SENSOR_TYPE_ID_DROP_DETECTION:
148 case SENSOR_TYPE_ID_HALL:
149 case SENSOR_TYPE_ID_PROXIMITY:
150 case SENSOR_TYPE_ID_WEAR_DETECTION:
151 return ONE_DIMENSION;
152 case SENSOR_TYPE_ID_AMBIENT_LIGHT:
153 case SENSOR_TYPE_ID_AMBIENT_LIGHT1:
154 case SENSOR_TYPE_ID_ACCELEROMETER:
155 case SENSOR_TYPE_ID_GRAVITY:
156 case SENSOR_TYPE_ID_GYROSCOPE:
157 case SENSOR_TYPE_ID_MAGNETIC_FIELD:
158 case SENSOR_TYPE_ID_ORIENTATION:
159 return THREE_DIMENSION;
160 case SENSOR_TYPE_ID_ROTATION_VECTOR:
161 return FOUR_DIMENSION;
162 case SENSOR_TYPE_ID_HALL_EXT:
163 return EIGHT_DIMENSION;
164 case SENSOR_TYPE_ID_POSTURE:
165 return THIRTEEN_DIMENSION;
166 default:
167 SEN_HILOGW("Unknown sensorType:%{public}d, size:%{public}d", sensorType, DEFAULT_DIMENSION);
168 return DEFAULT_DIMENSION;
169 }
170 }
171
ControlSensorClientPrint(const RecordSensorCallback callback,const SensorEvent & event)172 void PrintSensorData::ControlSensorClientPrint(const RecordSensorCallback callback, const SensorEvent &event)
173 {
174 auto triggerIt = std::find(g_triggerSensorType.begin(), g_triggerSensorType.end(), event.sensorTypeId);
175 if (triggerIt != g_triggerSensorType.end()) {
176 PrintClientData(event);
177 ProcessClientDFX(event);
178 }
179
180 auto continuosIt = std::find(g_continuousSensorType.begin(), g_continuousSensorType.end(), event.sensorTypeId);
181 if (continuosIt == g_continuousSensorType.end()) {
182 return;
183 }
184 std::lock_guard<std::mutex> clientLoginfoLock(clientLoginfoMutex_);
185 auto it = clientLoginfo_.find(callback);
186 if (it == clientLoginfo_.end()) {
187 return;
188 }
189 it->second.clientTimes++;
190 if (it->second.count < FIRST_PRINT_TIMES) {
191 PrintClientData(event);
192 if (it->second.count == FIRST_PRINT_TIMES - 1) {
193 it->second.lastTime = event.timestamp;
194 }
195 it->second.count++;
196 } else {
197 if (event.timestamp - it->second.lastTime >= LOG_INTERVAL) {
198 PrintClientData(event);
199 it->second.lastTime = event.timestamp;
200 }
201 }
202 if (it->second.clientTimesFlag == 0) {
203 it->second.clientTimesFlag = event.timestamp;
204 }
205 if (event.timestamp - it->second.clientTimesFlag >= LOG_INTERVAL) {
206 SEN_HILOGI("sensorType:%{public}d, clientTimes:%{public}s", event.sensorTypeId,
207 std::to_string(it->second.clientTimes).c_str());
208 it->second.clientTimesFlag = event.timestamp;
209 it->second.clientTimes = 0;
210 }
211 }
212
PrintClientData(const SensorEvent & event)213 void PrintSensorData::PrintClientData(const SensorEvent &event)
214 {
215 std::string str;
216 str += "deviceId:" + std::to_string(event.deviceId) + ", ";
217 str += "sensorType:" + std::to_string(event.sensorTypeId) + ", ";
218 str += "sensorId:" + std::to_string(event.sensorId) + ", ";
219 str += "location:" + std::to_string(event.location) + ", ";
220 str += "timestamp:" + std::to_string(event.timestamp / LOG_FORMAT_DIVIDER) + ", ";
221 int32_t dataDim = GetDataDimension(event.sensorTypeId);
222 auto data = reinterpret_cast<const float *>(event.data);
223 for (int32_t i = 0; i < dataDim; ++i) {
224 CHKPV(data);
225 str.append(std::to_string(*data));
226 if (i != dataDim - 1) {
227 str.append(", ");
228 }
229 ++data;
230 }
231 str.append("\n");
232 SEN_HILOGI("SensorData:%{public}s", str.c_str());
233 }
234
ProcessClientDFX(const SensorEvent & event)235 void PrintSensorData::ProcessClientDFX(const SensorEvent &event)
236 {
237 std::string strData;
238 auto data = reinterpret_cast<const float *>(event.data);
239 int32_t dataDim = GetDataDimension(event.sensorTypeId);
240 for (int32_t i = 0; i < dataDim; i++) {
241 CHKPV(data);
242 strData.append(std::to_string(*data));
243 if (i != dataDim - 1) {
244 strData.append(", ");
245 }
246 ++data;
247 }
248 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
249 HiSysEventWrite(HiSysEvent::Domain::SENSOR, "EVENT_REPORT",
250 HiSysEvent::EventType::BEHAVIOR, "SENSOR_ID", event.sensorTypeId, "TIMESTAMP",
251 std::to_string(event.timestamp), "DATA", strData);
252 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
253 }
254
IsContinuousType(int32_t sensorType)255 bool PrintSensorData::IsContinuousType(int32_t sensorType)
256 {
257 return std::find(g_continuousSensorType.begin(), g_continuousSensorType.end(),
258 sensorType) != g_continuousSensorType.end();
259 }
260
SavePrintUserInfo(const RecordSensorCallback callback)261 void PrintSensorData::SavePrintUserInfo(const RecordSensorCallback callback)
262 {
263 CHKPV(callback);
264 std::lock_guard<std::mutex> clientLoginfoLock(clientLoginfoMutex_);
265 if (clientLoginfo_.find(callback) != clientLoginfo_.end()) {
266 return;
267 }
268 LogPrintInfo info;
269 auto status = clientLoginfo_.insert(std::make_pair(callback, info));
270 if (!status.second) {
271 SEN_HILOGD("callback has been saved");
272 }
273 }
274
RemovePrintUserInfo(const RecordSensorCallback callback)275 void PrintSensorData::RemovePrintUserInfo(const RecordSensorCallback callback)
276 {
277 CHKPV(callback);
278 std::lock_guard<std::mutex> clientLoginfoLock(clientLoginfoMutex_);
279 if (clientLoginfo_.find(callback) == clientLoginfo_.end()) {
280 return;
281 }
282 clientLoginfo_.erase(callback);
283 }
284
ResetHdiCounter(int32_t sensorType)285 void PrintSensorData::ResetHdiCounter(int32_t sensorType)
286 {
287 std::lock_guard<std::mutex> hdiLoginfoLock(hdiLoginfoMutex_);
288 auto it = hdiLoginfo_.find(sensorType);
289 if (it == hdiLoginfo_.end()) {
290 return;
291 }
292 it->second.count = 0;
293 it->second.lastTime = 0;
294 }
295
ResetHdiTimes(int32_t sensorType)296 void PrintSensorData::ResetHdiTimes(int32_t sensorType)
297 {
298 std::lock_guard<std::mutex> hdiLoginfoLock(hdiLoginfoMutex_);
299 auto it = hdiLoginfo_.find(sensorType);
300 if (it == hdiLoginfo_.end()) {
301 return;
302 }
303 it->second.hdiTimes = 0;
304 it->second.hdiTimesFlag = 0;
305 }
306
PrintSensorDataLog(const std::string & name,const SensorData & data)307 void PrintSensorData::PrintSensorDataLog(const std::string &name, const SensorData &data)
308 {
309 std::string str;
310 str += "deviceId:" + std::to_string(data.deviceId) + ", ";
311 str += "sensorType:" + std::to_string(data.sensorTypeId) + ", ";
312 str += "sensorId:" + std::to_string(data.sensorId) + ", ";
313 str += "location:" + std::to_string(data.location) + ", ";
314 str += "timestamp:" + std::to_string(data.timestamp / LOG_FORMAT_DIVIDER) + ", ";
315 int32_t dataDim = GetDataDimension(data.sensorTypeId);
316 auto tempData = reinterpret_cast<const float *>(data.data);
317 for (int32_t i = 0; i < dataDim; ++i) {
318 CHKPV(tempData);
319 str.append(std::to_string(*tempData));
320 if (i != dataDim - 1) {
321 str.append(", ");
322 }
323 ++tempData;
324 }
325 str.append("\n");
326 SEN_HILOGI("%{public}s SensorData:%{public}s", name.c_str(), str.c_str());
327 }
328
PrintSensorInfo(SensorInfo * sensorInfos,int32_t sensorInfoCount)329 void PrintSensorData::PrintSensorInfo(SensorInfo *sensorInfos, int32_t sensorInfoCount)
330 {
331 std::string combineSensorIds = "";
332 for (int32_t i = 0; i < sensorInfoCount; ++i) {
333 combineSensorIds = combineSensorIds + std::to_string(sensorInfos[i].sensorTypeId) + " ";
334 }
335 SEN_HILOGI("PrintSensorInfo success, sensorIds:%{public}s, sensorInfoCount:%{public}d", combineSensorIds.c_str(),
336 sensorInfoCount);
337 }
338 } // namespace Sensors
339 } // namespace OHOS
340