1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <math.h>
18 #include <stdint.h>
19 #include <sys/types.h>
20 
21 #include <utils/Errors.h>
22 
23 #include <hardware/sensors.h>
24 
25 #include "LimitedAxesImuSensor.h"
26 #include "SensorDevice.h"
27 #include "SensorFusion.h"
28 #include "SensorServiceUtils.h"
29 
30 namespace android {
31 
32 namespace {
33 const sensor_t DUMMY_SENSOR = {.name = "",
34                                .vendor = "",
35                                .stringType = "",
36                                .requiredPermission = ""};
37 } // unnamed namespace
38 
LimitedAxesImuSensor(sensor_t const * list,size_t count,int32_t imu3dSensorType)39 LimitedAxesImuSensor::LimitedAxesImuSensor(sensor_t const* list, size_t count,
40                                            int32_t imu3dSensorType)
41       : BaseSensor(DUMMY_SENSOR) {
42     for (size_t i = 0; i < count; i++) {
43         if (list[i].type == imu3dSensorType) {
44             mImu3dSensor = Sensor(list + i);
45             break;
46         }
47     }
48 
49     const int32_t imuLimitedAxesSensorType = convertImu3dToLimitedAxesSensorType(imu3dSensorType);
50 
51     const sensor_t sensor = {
52             .name = convertLimitedAxesSensorTypeToName(imuLimitedAxesSensorType),
53             .vendor = "AOSP",
54             .version = 1,
55             .handle = convertLimitedAxesSensorTypeToHandle(imuLimitedAxesSensorType),
56             .type = imuLimitedAxesSensorType,
57             .maxRange = mImu3dSensor.getMaxValue(),
58             .resolution = mImu3dSensor.getResolution(),
59             .power = mImu3dSensor.getPowerUsage(),
60             .minDelay = mImu3dSensor.getMinDelay(),
61     };
62     mSensor = Sensor(&sensor);
63 }
64 
process(sensors_event_t * outEvent,const sensors_event_t & event)65 bool LimitedAxesImuSensor::process(sensors_event_t* outEvent, const sensors_event_t& event) {
66     if (event.type == mImu3dSensor.getType()) {
67         *outEvent = event;
68         size_t imu3dDataSize = SensorServiceUtil::eventSizeBySensorType(mImu3dSensor.getType());
69         outEvent->data[0 + imu3dDataSize] = 1;
70         outEvent->data[1 + imu3dDataSize] = 1;
71         outEvent->data[2 + imu3dDataSize] = 1;
72         outEvent->sensor = mSensor.getHandle();
73         outEvent->type = mSensor.getType();
74         return true;
75     }
76     return false;
77 }
78 
activate(void * ident,bool enabled)79 status_t LimitedAxesImuSensor::activate(void* ident, bool enabled) {
80     return mSensorDevice.activate(ident, mImu3dSensor.getHandle(), enabled);
81 }
82 
setDelay(void * ident,int,int64_t ns)83 status_t LimitedAxesImuSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {
84     return mSensorDevice.setDelay(ident, mImu3dSensor.getHandle(), ns);
85 }
86 
convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType)87 int32_t LimitedAxesImuSensor::convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType) {
88     switch (imu3dSensorType) {
89         case SENSOR_TYPE_ACCELEROMETER:
90             return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES;
91         case SENSOR_TYPE_GYROSCOPE:
92             return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES;
93         case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED:
94             return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED;
95         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
96             return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED;
97         default:
98             return 0;
99     }
100 }
101 
convertLimitedAxesSensorTypeToHandle(int32_t imuLimitedAxesSensorType)102 int32_t LimitedAxesImuSensor::convertLimitedAxesSensorTypeToHandle(
103         int32_t imuLimitedAxesSensorType) {
104     switch (imuLimitedAxesSensorType) {
105         case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
106             return '_ala';
107         case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
108             return '_gla';
109         case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
110             return '_alc';
111         case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
112             return '_glc';
113         default:
114             return 0;
115     }
116 }
117 
convertLimitedAxesSensorTypeToName(int32_t imuLimitedAxesSensorType)118 const char* LimitedAxesImuSensor::convertLimitedAxesSensorTypeToName(
119         int32_t imuLimitedAxesSensorType) {
120     switch (imuLimitedAxesSensorType) {
121         case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
122             return "Accelerometer Limited Axes Sensor";
123         case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
124             return "Gyroscope Limited Axes Sensor";
125         case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
126             return "Accelerometer Limited Axes Uncalibrated Sensor";
127         case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
128             return "Gyroscope Limited Axes Uncalibrated Sensor";
129         default:
130             return "";
131     }
132 }
133 
134 }; // namespace android
135