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