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