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 #include <string>
19 #include <vector>
20 
21 #include "sensor_errors.h"
22 
23 #undef LOG_TAG
24 #define LOG_TAG "PrintSensorData"
25 
26 namespace OHOS {
27 namespace Sensors {
28 namespace {
29 enum {
30     ONE_DIMENSION = 1,
31     TWO_DIMENSION = 2,
32     THREE_DIMENSION = 3,
33     SEVEN_DIMENSION = 7,
34     DEFAULT_DIMENSION = 16
35 };
36 constexpr int64_t LOG_INTERVAL = 60000000000L;
37 constexpr int32_t FIRST_PRINT_TIMES = 20;
38 constexpr float LOG_FORMAT_DIVIDER = 1e9f;
39 
40 const std::vector<int32_t> g_triggerSensorType = {
41     SENSOR_TYPE_ID_HALL_EXT,
42     SENSOR_TYPE_ID_PROXIMITY,
43     SENSOR_TYPE_ID_HALL,
44     SENSOR_TYPE_ID_WEAR_DETECTION,
45 };
46 const std::vector<int32_t> g_continuousSensorType = {
47     SENSOR_TYPE_ID_ACCELEROMETER,
48     SENSOR_TYPE_ID_POSTURE,
49     SENSOR_TYPE_ID_AMBIENT_LIGHT,
50     SENSOR_TYPE_ID_AMBIENT_LIGHT1,
51     SENSOR_TYPE_ID_GYROSCOPE,
52     SENSOR_TYPE_ID_MAGNETIC_FIELD,
53 };
54 }
55 
ControlSensorHdiPrint(const SensorData & sensorData)56 void PrintSensorData::ControlSensorHdiPrint(const SensorData &sensorData)
57 {
58     auto triggerIt = std::find(g_triggerSensorType.begin(), g_triggerSensorType.end(), sensorData.sensorTypeId);
59     if (triggerIt != g_triggerSensorType.end()) {
60         PrintHdiData(sensorData);
61     }
62     std::lock_guard<std::mutex> hdiLoginfoLock(hdiLoginfoMutex_);
63     auto it = hdiLoginfo_.find(sensorData.sensorTypeId);
64     if (it == hdiLoginfo_.end()) {
65         return;
66     }
67     if (it->second.count < FIRST_PRINT_TIMES) {
68         PrintHdiData(sensorData);
69         if (it->second.count == FIRST_PRINT_TIMES - 1) {
70             it->second.lastTime = sensorData.timestamp;
71         }
72         it->second.count++;
73     } else {
74         if (sensorData.timestamp - it->second.lastTime >= LOG_INTERVAL) {
75             PrintHdiData(sensorData);
76             it->second.lastTime = sensorData.timestamp;
77         }
78     }
79 }
80 
PrintHdiData(const SensorData & sensorData)81 void PrintSensorData::PrintHdiData(const SensorData &sensorData)
82 {
83     std::string str;
84     str += "sensorId: " + std::to_string(sensorData.sensorTypeId) + ", ";
85     str += "timestamp: " + std::to_string(sensorData.timestamp / LOG_FORMAT_DIVIDER) + ", ";
86     int32_t dataDim = GetDataDimension(sensorData.sensorTypeId);
87     auto data = reinterpret_cast<const float *>(sensorData.data);
88     for (int32_t i = 0; i < dataDim; ++i) {
89         CHKPV(data);
90         str.append(std::to_string(*data));
91         if (i != dataDim - 1) {
92             str.append(", ");
93         }
94         ++data;
95     }
96     str.append("\n");
97     SEN_HILOGI("SensorData: %{public}s", str.c_str());
98 }
99 
GetDataDimension(int32_t sensorId)100 int32_t PrintSensorData::GetDataDimension(int32_t sensorId)
101 {
102     switch (sensorId) {
103         case SENSOR_TYPE_ID_HALL:
104         case SENSOR_TYPE_ID_PROXIMITY:
105         case SENSOR_TYPE_ID_WEAR_DETECTION:
106             return ONE_DIMENSION;
107         case SENSOR_TYPE_ID_HALL_EXT:
108             return TWO_DIMENSION;
109         case SENSOR_TYPE_ID_POSTURE:
110             return SEVEN_DIMENSION;
111         case SENSOR_TYPE_ID_AMBIENT_LIGHT:
112         case SENSOR_TYPE_ID_AMBIENT_LIGHT1:
113         case SENSOR_TYPE_ID_ACCELEROMETER:
114         case SENSOR_TYPE_ID_GYROSCOPE:
115         case SENSOR_TYPE_ID_MAGNETIC_FIELD:
116             return THREE_DIMENSION;
117         default:
118             SEN_HILOGW("Unknown sensorId:%{public}d, size:%{public}d", sensorId, DEFAULT_DIMENSION);
119             return DEFAULT_DIMENSION;
120     }
121 }
122 
ControlSensorClientPrint(const RecordSensorCallback callback,const SensorEvent & event)123 void PrintSensorData::ControlSensorClientPrint(const RecordSensorCallback callback, const SensorEvent &event)
124 {
125     auto triggerIt = std::find(g_triggerSensorType.begin(), g_triggerSensorType.end(), event.sensorTypeId);
126     if (triggerIt != g_triggerSensorType.end()) {
127         PrintClientData(event);
128     }
129 
130     auto continuosIt = std::find(g_continuousSensorType.begin(), g_continuousSensorType.end(), event.sensorTypeId);
131     if (continuosIt == g_continuousSensorType.end()) {
132         return;
133     }
134     std::lock_guard<std::mutex> clientLoginfoLock(clientLoginfoMutex_);
135     auto it = clientLoginfo_.find(callback);
136     if (it == clientLoginfo_.end()) {
137         return;
138     }
139     if (it->second.count < FIRST_PRINT_TIMES) {
140         PrintClientData(event);
141         if (it->second.count == FIRST_PRINT_TIMES - 1) {
142             it->second.lastTime = event.timestamp;
143         }
144         it->second.count++;
145     } else {
146         if (event.timestamp - it->second.lastTime >= LOG_INTERVAL) {
147             PrintClientData(event);
148             it->second.lastTime = event.timestamp;
149         }
150     }
151 }
152 
PrintClientData(const SensorEvent & event)153 void PrintSensorData::PrintClientData(const SensorEvent &event)
154 {
155     std::string str;
156     str += "sensorId: " + std::to_string(event.sensorTypeId) + ", ";
157     str += "timestamp: " + std::to_string(event.timestamp / LOG_FORMAT_DIVIDER) + ", ";
158     int32_t dataDim = GetDataDimension(event.sensorTypeId);
159     auto data = reinterpret_cast<const float *>(event.data);
160     for (int32_t i = 0; i < dataDim; ++i) {
161         CHKPV(data);
162         str.append(std::to_string(*data));
163         if (i != dataDim - 1) {
164             str.append(", ");
165         }
166         ++data;
167     }
168     str.append("\n");
169     SEN_HILOGI("SensorData: %{public}s", str.c_str());
170 }
171 
IsContinuousType(int32_t sensorId)172 bool PrintSensorData::IsContinuousType(int32_t sensorId)
173 {
174     return std::find(g_continuousSensorType.begin(), g_continuousSensorType.end(),
175         sensorId) != g_continuousSensorType.end();
176 }
177 
SavePrintUserInfo(const RecordSensorCallback callback)178 void PrintSensorData::SavePrintUserInfo(const RecordSensorCallback callback)
179 {
180     CHKPV(callback);
181     std::lock_guard<std::mutex> clientLoginfoLock(clientLoginfoMutex_);
182     if (clientLoginfo_.find(callback) != clientLoginfo_.end()) {
183         return;
184     }
185     LogPrintInfo info;
186     auto status = clientLoginfo_.insert(std::make_pair(callback, info));
187     if (!status.second) {
188         SEN_HILOGD("callback has been saved");
189     }
190 }
191 
RemovePrintUserInfo(const RecordSensorCallback callback)192 void PrintSensorData::RemovePrintUserInfo(const RecordSensorCallback callback)
193 {
194     CHKPV(callback);
195     std::lock_guard<std::mutex> clientLoginfoLock(clientLoginfoMutex_);
196     if (clientLoginfo_.find(callback) == clientLoginfo_.end()) {
197         return;
198     }
199     clientLoginfo_.erase(callback);
200 }
201 
ResetHdiCounter(int32_t sensorId)202 void PrintSensorData::ResetHdiCounter(int32_t sensorId)
203 {
204     std::lock_guard<std::mutex> hdiLoginfoLock(hdiLoginfoMutex_);
205     auto it = hdiLoginfo_.find(sensorId);
206     if (it == hdiLoginfo_.end()) {
207         return;
208     }
209     it->second.count = 0;
210     it->second.lastTime = 0;
211 }
212 
PrintSensorDataLog(const std::string & name,const SensorData & data)213 void PrintSensorData::PrintSensorDataLog(const std::string &name, const SensorData &data)
214 {
215     std::string str;
216     str += "sensorId: " + std::to_string(data.sensorTypeId) + ", ";
217     str += "timestamp: " + std::to_string(data.timestamp / LOG_FORMAT_DIVIDER) + ", ";
218     int32_t dataDim = GetDataDimension(data.sensorTypeId);
219     auto tempData = reinterpret_cast<const float *>(data.data);
220     for (int32_t i = 0; i < dataDim; ++i) {
221         CHKPV(tempData);
222         str.append(std::to_string(*tempData));
223         if (i != dataDim - 1) {
224             str.append(", ");
225         }
226         ++tempData;
227     }
228     str.append("\n");
229     SEN_HILOGI("%{public}s SensorData: %{public}s", name.c_str(), str.c_str());
230 }
231 } // namespace Sensors
232 } // namespace OHOS