1 /*
2 * Copyright (C) 2018 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/platform/shared/platform_sensor_util.h"
18
19 #include <cinttypes>
20
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/core/sensor.h"
23 #include "chre/platform/assert.h"
24 #include "chre/util/memory.h"
25
26 namespace chre {
27
updateLastEvent(SensorType sensorType,const void * eventData)28 void updateLastEvent(SensorType sensorType, const void *eventData) {
29 CHRE_ASSERT(eventData);
30
31 auto *header = static_cast<const chreSensorDataHeader *>(eventData);
32 if (header->readingCount != 1) {
33 // TODO: better error handling when there are more than one samples.
34 LOGE("%" PRIu16 " samples in an event for on-change sensor %" PRIu8,
35 header->readingCount, static_cast<uint8_t>(sensorType));
36 } else {
37 struct CallbackData {
38 SensorType sensorType;
39 const ChreSensorData *event;
40 };
41 auto *callbackData = memoryAlloc<CallbackData>();
42 if (callbackData == nullptr) {
43 LOG_OOM();
44 } else {
45 callbackData->sensorType = sensorType;
46 callbackData->event = static_cast<const ChreSensorData *>(eventData);
47
48 auto callback = [](uint16_t /* type */, void *data) {
49 auto *cbData = static_cast<CallbackData *>(data);
50
51 Sensor *sensor = EventLoopManagerSingleton::get()
52 ->getSensorRequestManager().getSensor(cbData->sensorType);
53
54 // Mark last event as valid only if the sensor is enabled. Event data
55 // may arrive after sensor is disabled.
56 if (sensor != nullptr
57 && sensor->getRequest().getMode() != SensorMode::Off) {
58 sensor->setLastEvent(cbData->event);
59 }
60 memoryFree(cbData);
61 };
62
63 // Schedule a deferred callback.
64 EventLoopManagerSingleton::get()->deferCallback(
65 SystemCallbackType::SensorLastEventUpdate, callbackData, callback);
66 }
67 }
68 }
69
sensorDataEventFree(uint16_t eventType,void * eventData)70 void sensorDataEventFree(uint16_t eventType, void *eventData) {
71 // TODO: Consider using a MemoryPool.
72 memoryFree(eventData);
73
74 // Remove all requests if it's a one-shot sensor and only after data has been
75 // delivered to all clients.
76 SensorType sensorType = getSensorTypeForSampleEventType(eventType);
77 if (sensorTypeIsOneShot(sensorType)) {
78 EventLoopManagerSingleton::get()
79 ->getSensorRequestManager()
80 .removeAllRequests(sensorType);
81 }
82 }
83
84 } // namespace chre
85