1 /*
2 * Copyright (C) 2016 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 "chre/core/event_loop_manager.h"
18 #include "chre/core/sensor_request.h"
19 #include "chre/util/macros.h"
20 #include "chre/util/time.h"
21 #include "chre_api/chre/sensor.h"
22
23 using chre::EventLoopManager;
24 using chre::EventLoopManagerSingleton;
25 using chre::Nanoseconds;
26 using chre::SensorMode;
27 using chre::SensorRequest;
28
29 using chre::getSensorModeFromEnum;
30
31 #if defined(CHRE_SLPI_SEE) && defined(CHRE_SLPI_UIMG_ENABLED)
32 namespace {
33 constexpr uint8_t kBigImageAccelSensorType =
34 (CHRE_SENSOR_TYPE_VENDOR_START + 3);
35 constexpr uint8_t kBigImageUncalAccelSensorType =
36 (CHRE_SENSOR_TYPE_VENDOR_START + 6);
37 constexpr uint8_t kBigImageUncalGyroSensorType =
38 (CHRE_SENSOR_TYPE_VENDOR_START + 7);
39 constexpr uint8_t kBigImageUncalMagSensorType =
40 (CHRE_SENSOR_TYPE_VENDOR_START + 8);
41 constexpr uint8_t kBigImageLightSensorType =
42 (CHRE_SENSOR_TYPE_VENDOR_START + 9);
43
isBigImageSensorType(uint8_t sensorType)44 bool isBigImageSensorType(uint8_t sensorType) {
45 return (sensorType == kBigImageAccelSensorType ||
46 sensorType == kBigImageUncalAccelSensorType ||
47 sensorType == kBigImageUncalGyroSensorType ||
48 sensorType == kBigImageUncalMagSensorType ||
49 sensorType == kBigImageLightSensorType);
50 }
51
52 /**
53 * Rewrites the provided sensorType to its big-image counterpart if it exists.
54 */
rewriteToBigImageSensorType(uint8_t * sensorType)55 void rewriteToBigImageSensorType(uint8_t *sensorType) {
56 CHRE_ASSERT(sensorType);
57
58 if (*sensorType == CHRE_SENSOR_TYPE_ACCELEROMETER) {
59 *sensorType = kBigImageAccelSensorType;
60 } else if (*sensorType == CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER) {
61 *sensorType = kBigImageUncalAccelSensorType;
62 } else if (*sensorType == CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE) {
63 *sensorType = kBigImageUncalGyroSensorType;
64 } else if (*sensorType == CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD) {
65 *sensorType = kBigImageUncalMagSensorType;
66 } else if (*sensorType == CHRE_SENSOR_TYPE_LIGHT) {
67 *sensorType = kBigImageLightSensorType;
68 }
69 }
70
71 /**
72 * Rewrites a big-image sensorType to its regular CHRE counterpart.
73 */
rewriteToChreSensorType(uint8_t * sensorType)74 void rewriteToChreSensorType(uint8_t *sensorType) {
75 CHRE_ASSERT(sensorType);
76
77 if (*sensorType == kBigImageAccelSensorType) {
78 *sensorType = CHRE_SENSOR_TYPE_ACCELEROMETER;
79 } else if (*sensorType == kBigImageUncalAccelSensorType) {
80 *sensorType = CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER;
81 } else if (*sensorType == kBigImageUncalGyroSensorType) {
82 *sensorType = CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE;
83 } else if (*sensorType == kBigImageUncalMagSensorType) {
84 *sensorType = CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD;
85 } else if (*sensorType == kBigImageLightSensorType) {
86 *sensorType = CHRE_SENSOR_TYPE_LIGHT;
87 }
88 }
89 } // anonymous namespace
90 #endif // defined(CHRE_SLPI_SEE) && defined(CHRE_SLPI_UIMG_ENABLED)
91
chreSensorFindDefault(uint8_t sensorType,uint32_t * handle)92 DLL_EXPORT bool chreSensorFindDefault(uint8_t sensorType, uint32_t *handle) {
93 #if defined(CHRE_SLPI_SEE) && defined(CHRE_SLPI_UIMG_ENABLED)
94 // HACK: as SEE does not support software batching in uimg via QCM/uQSockets,
95 // reroute requests for accel and uncal accel/gyro/mag from a big image
96 // nanoapp to a separate sensor type internally. These are the only always-on
97 // sensors used today by big image nanoapps, and this change allows these
98 // requests to transparently go to a separate sensor implementation that
99 // supports uimg batching via CM/QMI.
100 // TODO(P2-5673a9): work with QC to determine a better long-term solution
101 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
102 if (!nanoapp->isUimgApp()) {
103 // Since we have an accompanying hack in PlatformNanoapp::handleEvent(),
104 // hide the vendor sensor type from big image nanoapps as we're unable to
105 // deliver events for it
106 if (isBigImageSensorType(sensorType)) {
107 return false;
108 }
109 rewriteToBigImageSensorType(&sensorType);
110 }
111 #endif // defined(CHRE_SLPI_SEE) && defined(CHRE_SLPI_UIMG_ENABLED)
112
113 return EventLoopManagerSingleton::get()
114 ->getSensorRequestManager()
115 .getSensorHandle(sensorType, handle);
116 }
117
chreGetSensorInfo(uint32_t sensorHandle,struct chreSensorInfo * info)118 DLL_EXPORT bool chreGetSensorInfo(uint32_t sensorHandle,
119 struct chreSensorInfo *info) {
120 CHRE_ASSERT(info);
121
122 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
123
124 bool success = false;
125 if (info != nullptr) {
126 success = EventLoopManagerSingleton::get()
127 ->getSensorRequestManager()
128 .getSensorInfo(sensorHandle, *nanoapp, info);
129
130 // The distinction between big/uimg accel and uncal accel/gyro/mag should
131 // be abstracted away from big image nanoapps, so overwrite any platform
132 // implementation here.
133 #if defined(CHRE_SLPI_SEE) && defined(CHRE_SLPI_UIMG_ENABLED)
134 if (!nanoapp->isUimgApp()) {
135 rewriteToChreSensorType(&info->sensorType);
136 }
137 #endif // defined(CHRE_SLPI_SEE) && defined(CHRE_SLPI_UIMG_ENABLED)
138 }
139 return success;
140 }
141
chreGetSensorSamplingStatus(uint32_t sensorHandle,struct chreSensorSamplingStatus * status)142 DLL_EXPORT bool chreGetSensorSamplingStatus(
143 uint32_t sensorHandle, struct chreSensorSamplingStatus *status) {
144 CHRE_ASSERT(status);
145
146 bool success = false;
147 if (status != nullptr) {
148 success = EventLoopManagerSingleton::get()
149 ->getSensorRequestManager()
150 .getSensorSamplingStatus(sensorHandle, status);
151 }
152 return success;
153 }
154
chreSensorConfigure(uint32_t sensorHandle,enum chreSensorConfigureMode mode,uint64_t interval,uint64_t latency)155 DLL_EXPORT bool chreSensorConfigure(uint32_t sensorHandle,
156 enum chreSensorConfigureMode mode,
157 uint64_t interval, uint64_t latency) {
158 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
159 SensorMode sensorMode = getSensorModeFromEnum(mode);
160 SensorRequest sensorRequest(nanoapp->getInstanceId(), sensorMode,
161 Nanoseconds(interval), Nanoseconds(latency));
162 return EventLoopManagerSingleton::get()
163 ->getSensorRequestManager()
164 .setSensorRequest(nanoapp, sensorHandle, sensorRequest);
165 }
166
chreSensorConfigureBiasEvents(uint32_t sensorHandle,bool enable)167 DLL_EXPORT bool chreSensorConfigureBiasEvents(uint32_t sensorHandle,
168 bool enable) {
169 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
170 return EventLoopManagerSingleton::get()
171 ->getSensorRequestManager()
172 .configureBiasEvents(nanoapp, sensorHandle, enable);
173 }
174
chreSensorGetThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias)175 DLL_EXPORT bool chreSensorGetThreeAxisBias(
176 uint32_t sensorHandle, struct chreSensorThreeAxisData *bias) {
177 return EventLoopManagerSingleton::get()
178 ->getSensorRequestManager()
179 .getThreeAxisBias(sensorHandle, bias);
180 }
181
chreSensorFlushAsync(uint32_t sensorHandle,const void * cookie)182 DLL_EXPORT bool chreSensorFlushAsync(uint32_t sensorHandle,
183 const void *cookie) {
184 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
185 return EventLoopManagerSingleton::get()->getSensorRequestManager().flushAsync(
186 nanoapp, sensorHandle, cookie);
187 }
188