• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "chre/pal/sensor.h"
18 
19 #include "chre/platform/memory.h"
20 #include "chre/util/macros.h"
21 #include "chre/util/memory.h"
22 #include "chre/util/unique_ptr.h"
23 
24 #include <chrono>
25 #include <cinttypes>
26 #include <cstdint>
27 #include <future>
28 #include <thread>
29 
30 /**
31  * A simulated implementation of the Sensor PAL for the linux platform.
32  */
33 namespace {
34 const struct chrePalSystemApi *gSystemApi = nullptr;
35 const struct chrePalSensorCallbacks *gCallbacks = nullptr;
36 
37 struct chreSensorInfo gSensors[] = {
38     // Sensor 0 - Accelerometer.
39     {
40         .sensorName = "Test Accelerometer",
41         .sensorType = CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER,
42         .isOnChange = 0,
43         .isOneShot = 0,
44         .reportsBiasEvents = 0,
45         .supportsPassiveMode = 0,
46         .minInterval = 0,
47         .sensorIndex = CHRE_SENSOR_INDEX_DEFAULT,
48     },
49 };
50 
51 //! Thread to deliver asynchronous sensor data after a CHRE request.
52 std::thread gSensor0Thread;
53 std::promise<void> gStopSensor0Thread;
54 bool gIsSensor0Enabled = false;
55 
stopSensor0Thread()56 void stopSensor0Thread() {
57   if (gSensor0Thread.joinable()) {
58     gStopSensor0Thread.set_value();
59     gSensor0Thread.join();
60   }
61 }
62 
chrePalSensorApiClose()63 void chrePalSensorApiClose() {
64   stopSensor0Thread();
65 }
66 
chrePalSensorApiOpen(const struct chrePalSystemApi * systemApi,const struct chrePalSensorCallbacks * callbacks)67 bool chrePalSensorApiOpen(const struct chrePalSystemApi *systemApi,
68                           const struct chrePalSensorCallbacks *callbacks) {
69   chrePalSensorApiClose();
70 
71   if (systemApi != nullptr && callbacks != nullptr) {
72     gSystemApi = systemApi;
73     gCallbacks = callbacks;
74     return true;
75   }
76 
77   return false;
78 }
79 
chrePalSensorApiGetSensors(const struct chreSensorInfo ** sensors,uint32_t * arraySize)80 bool chrePalSensorApiGetSensors(const struct chreSensorInfo **sensors,
81                                 uint32_t *arraySize) {
82   if (sensors != nullptr) {
83     *sensors = gSensors;
84   }
85   if (arraySize != nullptr) {
86     *arraySize = ARRAY_SIZE(gSensors);
87   }
88   return true;
89 }
90 
sendSensor0StatusUpdate(uint64_t intervalNs,bool enabled)91 void sendSensor0StatusUpdate(uint64_t intervalNs, bool enabled) {
92   auto status = chre::MakeUniqueZeroFill<struct chreSensorSamplingStatus>();
93   status->interval = intervalNs;
94   status->latency = 0;
95   status->enabled = enabled;
96   gCallbacks->samplingStatusUpdateCallback(0, status.release());
97 }
98 
sendSensor0Events(uint64_t intervalNs)99 void sendSensor0Events(uint64_t intervalNs) {
100   std::future<void> signal = gStopSensor0Thread.get_future();
101   while (signal.wait_for(std::chrono::nanoseconds(intervalNs)) ==
102          std::future_status::timeout) {
103     auto data = chre::MakeUniqueZeroFill<struct chreSensorThreeAxisData>();
104 
105     data->header.baseTimestamp = gSystemApi->getCurrentTime();
106     data->header.sensorHandle = 0;
107     data->header.readingCount = 1;
108     data->header.accuracy = CHRE_SENSOR_ACCURACY_UNRELIABLE;
109     data->header.reserved = 0;
110 
111     gCallbacks->dataEventCallback(0, data.release());
112   }
113 }
114 
chrePalSensorApiConfigureSensor(uint32_t sensorInfoIndex,enum chreSensorConfigureMode mode,uint64_t intervalNs,uint64_t latencyNs)115 bool chrePalSensorApiConfigureSensor(uint32_t sensorInfoIndex,
116                                      enum chreSensorConfigureMode mode,
117                                      uint64_t intervalNs, uint64_t latencyNs) {
118   UNUSED_VAR(latencyNs);
119   if (sensorInfoIndex > ARRAY_SIZE(gSensors) - 1) {
120     return false;
121   }
122 
123   if (sensorInfoIndex != 0) {
124     // Only sensor 0 is supported for now.
125     return false;
126   }
127 
128   if (mode == CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS) {
129     stopSensor0Thread();
130     gIsSensor0Enabled = true;
131     sendSensor0StatusUpdate(intervalNs, true /*enabled*/);
132     gStopSensor0Thread = std::promise<void>();
133     gSensor0Thread = std::thread(sendSensor0Events, intervalNs);
134     return true;
135   }
136 
137   if (mode == CHRE_SENSOR_CONFIGURE_MODE_DONE) {
138     stopSensor0Thread();
139     gIsSensor0Enabled = false;
140     sendSensor0StatusUpdate(intervalNs, false /*enabled*/);
141     return true;
142   }
143 
144   return false;
145 }
146 
chrePalSensorApiFlush(uint32_t sensorInfoIndex,uint32_t * flushRequestId)147 bool chrePalSensorApiFlush(uint32_t sensorInfoIndex, uint32_t *flushRequestId) {
148   UNUSED_VAR(sensorInfoIndex);
149   UNUSED_VAR(flushRequestId);
150   return false;
151 }
152 
chrePalSensorApiConfigureBiasEvents(uint32_t sensorInfoIndex,bool enable,uint64_t latencyNs)153 bool chrePalSensorApiConfigureBiasEvents(uint32_t sensorInfoIndex, bool enable,
154                                          uint64_t latencyNs) {
155   UNUSED_VAR(sensorInfoIndex);
156   UNUSED_VAR(enable);
157   UNUSED_VAR(latencyNs);
158   return false;
159 }
160 
chrePalSensorApiGetThreeAxisBias(uint32_t sensorInfoIndex,struct chreSensorThreeAxisData * bias)161 bool chrePalSensorApiGetThreeAxisBias(uint32_t sensorInfoIndex,
162                                       struct chreSensorThreeAxisData *bias) {
163   UNUSED_VAR(sensorInfoIndex);
164   UNUSED_VAR(bias);
165   return false;
166 }
167 
chrePalSensorApiReleaseSensorDataEvent(void * data)168 void chrePalSensorApiReleaseSensorDataEvent(void *data) {
169   chre::memoryFree(data);
170 }
171 
chrePalSensorApiReleaseSamplingStatusEvent(struct chreSensorSamplingStatus * status)172 void chrePalSensorApiReleaseSamplingStatusEvent(
173     struct chreSensorSamplingStatus *status) {
174   chre::memoryFree(status);
175 }
176 
chrePalSensorApiReleaseBiasEvent(void * bias)177 void chrePalSensorApiReleaseBiasEvent(void *bias) {
178   chre::memoryFree(bias);
179 }
180 
181 }  // namespace
182 
chrePalSensorIsSensor0Enabled()183 bool chrePalSensorIsSensor0Enabled() {
184   return gIsSensor0Enabled;
185 }
186 
chrePalSensorGetApi(uint32_t requestedApiVersion)187 const chrePalSensorApi *chrePalSensorGetApi(uint32_t requestedApiVersion) {
188   static const struct chrePalSensorApi kApi = {
189       .moduleVersion = CHRE_PAL_SENSOR_API_CURRENT_VERSION,
190       .open = chrePalSensorApiOpen,
191       .close = chrePalSensorApiClose,
192       .getSensors = chrePalSensorApiGetSensors,
193       .configureSensor = chrePalSensorApiConfigureSensor,
194       .flush = chrePalSensorApiFlush,
195       .configureBiasEvents = chrePalSensorApiConfigureBiasEvents,
196       .getThreeAxisBias = chrePalSensorApiGetThreeAxisBias,
197       .releaseSensorDataEvent = chrePalSensorApiReleaseSensorDataEvent,
198       .releaseSamplingStatusEvent = chrePalSensorApiReleaseSamplingStatusEvent,
199       .releaseBiasEvent = chrePalSensorApiReleaseBiasEvent,
200 
201   };
202 
203   if (!CHRE_PAL_VERSIONS_ARE_COMPATIBLE(kApi.moduleVersion,
204                                         requestedApiVersion)) {
205     return nullptr;
206   } else {
207     return &kApi;
208   }
209 }