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