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