• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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