• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_dump.h"
17 
18 #include <getopt.h>
19 
20 #include <cinttypes>
21 
22 #include "securec.h"
23 #include "sensor_errors.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "SensorDump"
27 
28 namespace OHOS {
29 namespace Sensors {
30 using namespace OHOS::HiviewDFX;
31 namespace {
32 constexpr int32_t MAX_DUMP_PARAMETERS = 32;
33 #ifdef BUILD_VARIANT_ENG
34 constexpr uint32_t MAX_DUMP_DATA_SIZE = 10;
35 #endif // BUILD_VARIANT_ENG
36 constexpr uint32_t MS_NS = 1000000;
37 
38 enum {
39     SOLITARIES_DIMENSION = 1,
40     TWO_DIMENSION = 2,
41     COMMON_DIMENSION = 3,
42     VECTOR_DIMENSION = 4,
43     UNCALIBRATED_DIMENSION = 6,
44     SEVEN_DIMENSION = 7,
45     POSE_6DOF_DIMENSION = 15,
46     DEFAULT_DIMENSION = 16,
47 };
48 } // namespace
49 
50 std::unordered_map<int32_t, std::string> SensorDump::sensorMap_ = {
51     { SENSOR_TYPE_ID_ACCELEROMETER, "ACCELEROMETER" },
52     { SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED, "ACCELEROMETER UNCALIBRATED" },
53     { SENSOR_TYPE_ID_LINEAR_ACCELERATION, "LINEAR ACCELERATION" },
54     { SENSOR_TYPE_ID_GRAVITY, "GRAVITY" },
55     { SENSOR_TYPE_ID_GYROSCOPE, "GYROSCOPE" },
56     { SENSOR_TYPE_ID_CAPACITIVE, "CAPACITIVE"},
57     { SENSOR_TYPE_ID_TEMPERATURE, "TEMPERATURE"},
58     { SENSOR_TYPE_ID_GESTURE, "GESTURE"},
59     { SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED, "GYROSCOPE UNCALIBRATED" },
60     { SENSOR_TYPE_ID_SIGNIFICANT_MOTION, "SIGNIFICANT MOTION" },
61     { SENSOR_TYPE_ID_PEDOMETER_DETECTION, "PEDOMETER DETECTION" },
62     { SENSOR_TYPE_ID_PEDOMETER, "PEDOMETER" },
63     { SENSOR_TYPE_ID_AMBIENT_TEMPERATURE, "AMBIENT TEMPERATURE" },
64     { SENSOR_TYPE_ID_MAGNETIC_FIELD, "MAGNETIC FIELD" },
65     { SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED, "MAGNETIC FIELD UNCALIBRATED" },
66     { SENSOR_TYPE_ID_HUMIDITY, "HUMIDITY" },
67     { SENSOR_TYPE_ID_BAROMETER, "BAROMETER" },
68     { SENSOR_TYPE_ID_DEVICE_ORIENTATION, "DEVICE ORIENTATION" },
69     { SENSOR_TYPE_ID_ORIENTATION, "ORIENTATION" },
70     { SENSOR_TYPE_ID_ROTATION_VECTOR, "ROTATION VECTOR" },
71     { SENSOR_TYPE_ID_GAME_ROTATION_VECTOR, "GAME ROTATION VECTOR" },
72     { SENSOR_TYPE_ID_GEOMAGNETIC_ROTATION_VECTOR, "GEOMAGNETIC ROTATION VECTOR" },
73     { SENSOR_TYPE_ID_PROXIMITY, "PROXIMITY" },
74     { SENSOR_TYPE_ID_PROXIMITY1, "SECONDARY PROXIMITY" },
75     { SENSOR_TYPE_ID_AMBIENT_LIGHT, "AMBIENT LIGHT" },
76     { SENSOR_TYPE_ID_AMBIENT_LIGHT1, "SECONDARY AMBIENT LIGHT" },
77     { SENSOR_TYPE_ID_HALL, "HALL" },
78     { SENSOR_TYPE_ID_HALL_EXT, "EXTENDED HALL" },
79     { SENSOR_TYPE_ID_HEART_RATE, "HEART RATE" },
80     { SENSOR_TYPE_ID_WEAR_DETECTION, "WEAR DETECTION" },
81     { SENSOR_TYPE_ID_COLOR, "COLOR" },
82     { SENSOR_TYPE_ID_SAR, "SAR" },
83     { SENSOR_TYPE_ID_POSTURE, "POSTURE" },
84     { SENSOR_TYPE_ID_HEADPOSTURE, "HEAD POSTURE" },
85     { SENSOR_TYPE_ID_DROP_DETECTION, "DROP DETECTION" },
86     { SENSOR_TYPE_ID_RPC, "RPC" },
87 };
88 
RunSensorDump(int32_t fd,int32_t optionIndex,const std::vector<std::string> & args,char ** argv)89 void SensorDump::RunSensorDump(int32_t fd, int32_t optionIndex, const std::vector<std::string> &args, char **argv)
90 {
91     struct option dumpOptions[] = {
92         {"channel", no_argument, 0, 'c'},
93 #ifdef BUILD_VARIANT_ENG
94         {"data", no_argument, 0, 'd'},
95 #endif // BUILD_VARIANT_ENG
96         {"open", no_argument, 0, 'o'},
97         {"help", no_argument, 0, 'h'},
98         {"list", no_argument, 0, 'l'},
99         {NULL, 0, 0, 0}
100     };
101     optind = 1;
102     int32_t c;
103     while ((c = getopt_long(args.size(), argv, "cdohl", dumpOptions, &optionIndex)) != -1) {
104         switch (c) {
105             case 'c': {
106                 DumpSensorChannel(fd, clientInfo_);
107                 break;
108             }
109 #ifdef BUILD_VARIANT_ENG
110             case 'd': {
111                 DumpSensorData(fd, clientInfo_);
112                 break;
113             }
114 #endif // BUILD_VARIANT_ENG
115             case 'o': {
116                 DumpOpeningSensor(fd, sensors_, clientInfo_);
117                 break;
118             }
119             case 'h': {
120                 DumpHelp(fd);
121                 break;
122             }
123             case 'l': {
124                 DumpSensorList(fd, sensors_);
125                 break;
126             }
127             default: {
128                 dprintf(fd, "Unrecognized option, More info with: \"hidumper -s 3601 -a -h\"\n");
129                 break;
130             }
131         }
132     }
133 }
134 
ParseCommand(int32_t fd,const std::vector<std::string> & args,const std::vector<Sensor> & sensors,ClientInfo & clientInfo)135 void SensorDump::ParseCommand(int32_t fd, const std::vector<std::string> &args, const std::vector<Sensor> &sensors,
136     ClientInfo &clientInfo)
137 {
138     int32_t count = 0;
139     for (const auto &str : args) {
140         if (str.find("--") == 0) {
141             ++count;
142             continue;
143         }
144         if (str.find("-") == 0) {
145             count += static_cast<int32_t>(str.size()) - 1;
146             continue;
147         }
148     }
149     if (count > MAX_DUMP_PARAMETERS) {
150         SEN_HILOGE("Cmd param number not more than 32");
151         dprintf(fd, "Cmd param number not more than 32\n");
152         return;
153     }
154     int32_t optionIndex = 0;
155     char **argv = new (std::nothrow) char *[args.size()];
156     CHKPV(argv);
157     if (memset_s(argv, args.size() * sizeof(char *), 0, args.size() * sizeof(char *)) != EOK) {
158         SEN_HILOGE("memset_s failed");
159         delete[] argv;
160         return;
161     }
162     for (size_t i = 0; i < args.size(); ++i) {
163         argv[i] = new (std::nothrow) char[args[i].size() + 1];
164         if (argv[i] == nullptr) {
165             SEN_HILOGE("Alloc failure");
166             goto RELEASE_RES;
167         }
168         if (strcpy_s(argv[i], args[i].size() + 1, args[i].c_str()) != EOK) {
169             SEN_HILOGE("strcpy_s error");
170             goto RELEASE_RES;
171         }
172     }
173     sensors_ = sensors;
174     RunSensorDump(fd, optionIndex, args, argv);
175     RELEASE_RES:
176     for (size_t i = 0; i < args.size(); ++i) {
177         if (argv[i] != nullptr) {
178             delete[] argv[i];
179         }
180     }
181     delete[] argv;
182 }
183 
DumpHelp(int32_t fd)184 void SensorDump::DumpHelp(int32_t fd)
185 {
186     dprintf(fd, "Usage:\n");
187     dprintf(fd, "      -h, --help: dump help\n");
188     dprintf(fd, "      -l, --list: dump the sensor list\n");
189     dprintf(fd, "      -c, --channel: dump the sensor data channel info\n");
190     dprintf(fd, "      -o, --open: dump the opening sensors\n");
191 #ifdef BUILD_VARIANT_ENG
192     dprintf(fd, "      -d, --data: dump the last 10 packages sensor data\n");
193 #endif // BUILD_VARIANT_ENG
194 }
195 
DumpSensorList(int32_t fd,const std::vector<Sensor> & sensors)196 bool SensorDump::DumpSensorList(int32_t fd, const std::vector<Sensor> &sensors)
197 {
198     DumpCurrentTime(fd);
199     dprintf(fd, "Total sensor:%d, Sensor list:\n", int32_t { sensors.size() });
200     for (const auto &sensor : sensors) {
201         auto deviceId = sensor.GetDeviceId();
202         auto sensorTypeId = sensor.GetSensorTypeId();
203         auto sensorId = sensor.GetSensorId();
204         if (sensorMap_.find(sensorTypeId) == sensorMap_.end()) {
205             continue;
206         }
207         dprintf(fd,
208                 "deviceIndex:%d | sensorType:%s |sensorId:%8u  |sensorIndex:%d  | sensorName:%s | vendorName:%s"
209                 "| maxRange:%f| fifoMaxEventCount:%d | minSamplePeriodNs:%" PRId64 ""
210                 "| maxSamplePeriodNs:%" PRId64 "\n",
211                 deviceId, sensorMap_[sensorTypeId].c_str(), sensorTypeId, sensorId, sensor.GetSensorName().c_str(),
212                 sensor.GetVendorName().c_str(), sensor.GetMaxRange(), sensor.GetFifoMaxEventCount(),
213                 sensor.GetMinSamplePeriodNs(), sensor.GetMaxSamplePeriodNs());
214     }
215     return true;
216 }
217 
DumpSensorChannel(int32_t fd,ClientInfo & clientInfo)218 bool SensorDump::DumpSensorChannel(int32_t fd, ClientInfo &clientInfo)
219 {
220     DumpCurrentTime(fd);
221     dprintf(fd, "Sensor channel info:\n");
222     std::vector<SensorChannelInfo> channelInfo;
223     clientInfo.GetSensorChannelInfo(channelInfo);
224     for (const auto &channel : channelInfo) {
225         auto deviceId = channel.GetDeviceId();
226         auto sensorType = channel.GetSensorType();
227         auto sensorId = channel.GetSensorId();
228         if (sensorMap_.find(sensorType) == sensorMap_.end()) {
229             continue;
230         }
231         dprintf(fd,
232                 "uid:%d | packageName:%s | deviceIndex:%d | sensorType:%s |sensorId:%8u |sensorIndex:%d "
233                 "| samplingPeriodNs:%" PRId64 "| fifoCount:%u\n",
234                 channel.GetUid(), channel.GetPackageName().c_str(), deviceId, sensorMap_[sensorType].c_str(),
235                 sensorType, sensorId, channel.GetSamplingPeriodNs(), channel.GetFifoCount());
236     }
237     return true;
238 }
239 
DumpOpeningSensor(int32_t fd,const std::vector<Sensor> & sensors,ClientInfo & clientInfo)240 bool SensorDump::DumpOpeningSensor(int32_t fd, const std::vector<Sensor> &sensors, ClientInfo &clientInfo)
241 {
242     DumpCurrentTime(fd);
243     dprintf(fd, "Opening sensors:\n");
244     for (const auto &sensor : sensors) {
245         auto deviceId = sensor.GetDeviceId();
246         auto sensorTypeId = sensor.GetSensorTypeId();
247         auto sensorId = sensor.GetSensorId();
248         if (sensorMap_.find(sensorTypeId) == sensorMap_.end()) {
249             continue;
250         }
251         if (clientInfo.GetSensorState({sensor.GetDeviceId(), sensorTypeId, sensor.GetSensorId(),
252             sensor.GetLocation()})) {
253             dprintf(fd, "deviceIndex:%d | sensorType:%s |sensorId:%8u |sensorIndex:%d | channelSize: %lu\n",
254                 deviceId, sensorMap_[sensorTypeId].c_str(), sensorTypeId, sensorId, clientInfo.GetSensorChannel({
255                     sensor.GetDeviceId(), sensorTypeId, sensor.GetSensorId(), sensor.GetLocation()}).size());
256         }
257     }
258     return true;
259 }
260 
261 #ifdef BUILD_VARIANT_ENG
DumpSensorData(int32_t fd,ClientInfo & clientInfo)262 bool SensorDump::DumpSensorData(int32_t fd, ClientInfo &clientInfo)
263 {
264     dprintf(fd, "Last 10 packages sensor data:\n");
265     auto dataMap = clientInfo.GetDumpQueue();
266     int32_t j = 0;
267     for (auto &sensorData : dataMap) {
268         if (sensorMap_.find(sensorData.first.sensorType) == sensorMap_.end()) {
269             continue;
270         }
271         dprintf(fd, "deviceIndex:%d | sensorType:%s |sensorId:%8u :\n", sensorData.first.deviceId,
272             sensorMap_[sensorData.first.sensorType].c_str(), sensorData.first.sensorId);
273         for (uint32_t i = 0; i < MAX_DUMP_DATA_SIZE && (!sensorData.second.empty()); i++) {
274             auto data = sensorData.second.front();
275             sensorData.second.pop();
276             timespec time = { 0, 0 };
277             clock_gettime(CLOCK_REALTIME, &time);
278             struct tm *timeinfo = localtime(&(time.tv_sec));
279             CHKPF(timeinfo);
280             dprintf(fd, "      %2d (ts=%.9f, time=%02d:%02d:%02d.%03d) | data:%s", ++j, data.timestamp / 1e9,
281                     timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, int32_t { (time.tv_nsec / MS_NS) },
282                     GetDataBySensorId(sensorData.first.sensorType, data).c_str());
283         }
284     }
285     return true;
286 }
287 #endif // BUILD_VARIANT_ENG
288 
DumpCurrentTime(int32_t fd)289 void SensorDump::DumpCurrentTime(int32_t fd)
290 {
291     timespec curTime = { 0, 0 };
292     clock_gettime(CLOCK_REALTIME, &curTime);
293     struct tm *timeinfo = localtime(&(curTime.tv_sec));
294     CHKPV(timeinfo);
295     dprintf(fd, "Current time: %02d:%02d:%02d.%03d\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec,
296             int32_t { (curTime.tv_nsec / MS_NS) });
297 }
298 
GetDataDimension(int32_t sensorType)299 int32_t SensorDump::GetDataDimension(int32_t sensorType)
300 {
301     switch (sensorType) {
302         case SENSOR_TYPE_ID_BAROMETER:
303         case SENSOR_TYPE_ID_HALL:
304         case SENSOR_TYPE_ID_HALL_EXT:
305         case SENSOR_TYPE_ID_TEMPERATURE:
306         case SENSOR_TYPE_ID_PROXIMITY:
307         case SENSOR_TYPE_ID_PROXIMITY1:
308         case SENSOR_TYPE_ID_HUMIDITY:
309         case SENSOR_TYPE_ID_AMBIENT_TEMPERATURE:
310         case SENSOR_TYPE_ID_SIGNIFICANT_MOTION:
311         case SENSOR_TYPE_ID_PEDOMETER_DETECTION:
312         case SENSOR_TYPE_ID_PEDOMETER:
313         case SENSOR_TYPE_ID_HEART_RATE:
314         case SENSOR_TYPE_ID_WEAR_DETECTION:
315         case SENSOR_TYPE_ID_SAR:
316             return SOLITARIES_DIMENSION;
317         case SENSOR_TYPE_ID_COLOR:
318             return TWO_DIMENSION;
319         case SENSOR_TYPE_ID_ROTATION_VECTOR:
320         case SENSOR_TYPE_ID_HEADPOSTURE:
321             return VECTOR_DIMENSION;
322         case SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED:
323         case SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED:
324         case SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED:
325             return UNCALIBRATED_DIMENSION;
326         case SENSOR_TYPE_ID_POSTURE:
327             return SEVEN_DIMENSION;
328         default:
329             SEN_HILOGW("Unknown sensorType:%{public}d, size:%{public}d", sensorType, COMMON_DIMENSION);
330             return COMMON_DIMENSION;
331     }
332 }
333 
GetDataBySensorId(int32_t sensorType,SensorData & sensorData)334 std::string SensorDump::GetDataBySensorId(int32_t sensorType, SensorData &sensorData)
335 {
336     SEN_HILOGD("sensorType:%{public}u", sensorType);
337     std::string str;
338     int32_t dataLen = GetDataDimension(sensorType);
339     if (sensorData.dataLen < sizeof(float)) {
340         SEN_HILOGE("SensorData dataLen less than float size");
341         return str;
342     }
343     auto data = reinterpret_cast<float *>(sensorData.data);
344     for (int32_t i = 0; i < dataLen; ++i) {
345         str.append(std::to_string(*data));
346         if (i != dataLen - 1) {
347             str.append(",");
348         }
349         ++data;
350     }
351     str.append("\n");
352     return str;
353 }
354 } // namespace Sensors
355 } // namespace OHOS
356