1 /*
2 * Copyright (C) 2021 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 "sensors-impl/Sensors.h"
18
19 #include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h>
20
21 using ::aidl::android::hardware::common::fmq::MQDescriptor;
22 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
23 using ::aidl::android::hardware::sensors::Event;
24 using ::aidl::android::hardware::sensors::ISensors;
25 using ::aidl::android::hardware::sensors::ISensorsCallback;
26 using ::aidl::android::hardware::sensors::SensorInfo;
27 using ::ndk::ScopedAStatus;
28
29 namespace aidl {
30 namespace android {
31 namespace hardware {
32 namespace sensors {
33
activate(int32_t in_sensorHandle,bool in_enabled)34 ScopedAStatus Sensors::activate(int32_t in_sensorHandle, bool in_enabled) {
35 auto sensor = mSensors.find(in_sensorHandle);
36 if (sensor != mSensors.end()) {
37 sensor->second->activate(in_enabled);
38 return ScopedAStatus::ok();
39 }
40
41 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
42 }
43
batch(int32_t in_sensorHandle,int64_t in_samplingPeriodNs,int64_t)44 ScopedAStatus Sensors::batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs,
45 int64_t /* in_maxReportLatencyNs */) {
46 auto sensor = mSensors.find(in_sensorHandle);
47 if (sensor != mSensors.end()) {
48 sensor->second->batch(in_samplingPeriodNs);
49 return ScopedAStatus::ok();
50 }
51
52 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
53 }
54
configDirectReport(int32_t,int32_t,ISensors::RateLevel,int32_t * _aidl_return)55 ScopedAStatus Sensors::configDirectReport(int32_t /* in_sensorHandle */,
56 int32_t /* in_channelHandle */,
57 ISensors::RateLevel /* in_rate */,
58 int32_t* _aidl_return) {
59 *_aidl_return = EX_UNSUPPORTED_OPERATION;
60
61 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
62 }
63
flush(int32_t in_sensorHandle)64 ScopedAStatus Sensors::flush(int32_t in_sensorHandle) {
65 auto sensor = mSensors.find(in_sensorHandle);
66 if (sensor != mSensors.end()) {
67 return sensor->second->flush();
68 }
69
70 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
71 }
72
getSensorsList(std::vector<SensorInfo> * _aidl_return)73 ScopedAStatus Sensors::getSensorsList(std::vector<SensorInfo>* _aidl_return) {
74 for (const auto& sensor : mSensors) {
75 _aidl_return->push_back(sensor.second->getSensorInfo());
76 }
77 return ScopedAStatus::ok();
78 }
79
initialize(const MQDescriptor<Event,SynchronizedReadWrite> & in_eventQueueDescriptor,const MQDescriptor<int32_t,SynchronizedReadWrite> & in_wakeLockDescriptor,const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> & in_sensorsCallback)80 ScopedAStatus Sensors::initialize(
81 const MQDescriptor<Event, SynchronizedReadWrite>& in_eventQueueDescriptor,
82 const MQDescriptor<int32_t, SynchronizedReadWrite>& in_wakeLockDescriptor,
83 const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>&
84 in_sensorsCallback) {
85 ScopedAStatus result = ScopedAStatus::ok();
86
87 mEventQueue = std::make_unique<AidlMessageQueue<Event, SynchronizedReadWrite>>(
88 in_eventQueueDescriptor, true /* resetPointers */);
89
90 // Ensure that all sensors are disabled.
91 for (auto sensor : mSensors) {
92 sensor.second->activate(false);
93 }
94
95 // Stop the Wake Lock thread if it is currently running
96 if (mReadWakeLockQueueRun.load()) {
97 mReadWakeLockQueueRun = false;
98 mWakeLockThread.join();
99 }
100
101 // Save a reference to the callback
102 mCallback = in_sensorsCallback;
103
104 // Ensure that any existing EventFlag is properly deleted
105 deleteEventFlag();
106
107 // Create the EventFlag that is used to signal to the framework that sensor events have been
108 // written to the Event FMQ
109 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
110 result = ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
111 }
112
113 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
114 // events have been successfully read and handled by the framework.
115 mWakeLockQueue = std::make_unique<AidlMessageQueue<int32_t, SynchronizedReadWrite>>(
116 in_wakeLockDescriptor, true /* resetPointers */);
117
118 if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
119 result = ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
120 }
121
122 // Start the thread to read events from the Wake Lock FMQ
123 mReadWakeLockQueueRun = true;
124 mWakeLockThread = std::thread(startReadWakeLockThread, this);
125 return result;
126 }
127
injectSensorData(const Event & in_event)128 ScopedAStatus Sensors::injectSensorData(const Event& in_event) {
129 auto sensor = mSensors.find(in_event.sensorHandle);
130 if (sensor != mSensors.end()) {
131 return sensor->second->injectEvent(in_event);
132 }
133 return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(ERROR_BAD_VALUE));
134 }
135
registerDirectChannel(const ISensors::SharedMemInfo &,int32_t * _aidl_return)136 ScopedAStatus Sensors::registerDirectChannel(const ISensors::SharedMemInfo& /* in_mem */,
137 int32_t* _aidl_return) {
138 *_aidl_return = EX_UNSUPPORTED_OPERATION;
139
140 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
141 }
142
setOperationMode(OperationMode in_mode)143 ScopedAStatus Sensors::setOperationMode(OperationMode in_mode) {
144 for (auto sensor : mSensors) {
145 sensor.second->setOperationMode(in_mode);
146 }
147 return ScopedAStatus::ok();
148 }
149
unregisterDirectChannel(int32_t)150 ScopedAStatus Sensors::unregisterDirectChannel(int32_t /* in_channelHandle */) {
151 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
152 }
153
154 } // namespace sensors
155 } // namespace hardware
156 } // namespace android
157 } // namespace aidl
158