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 ALOGI("Sensors initializing");
86 ScopedAStatus result = ScopedAStatus::ok();
87
88 // Ensure that all sensors are disabled.
89 for (auto sensor : mSensors) {
90 sensor.second->activate(false);
91 }
92
93 // Stop the Wake Lock thread if it is currently running
94 if (mReadWakeLockQueueRun.load()) {
95 mReadWakeLockQueueRun = false;
96 mWakeLockThread.join();
97 }
98
99 // Save a reference to the callback
100 mCallback = in_sensorsCallback;
101
102 {
103 // Hold the lock to ensure that re-creation of event flag is atomic
104 std::lock_guard<std::mutex> lock(mWriteLock);
105
106 mEventQueue = std::make_unique<AidlMessageQueue<Event, SynchronizedReadWrite>>(
107 in_eventQueueDescriptor, true /* resetPointers */);
108
109 // Ensure that any existing EventFlag is properly deleted
110 deleteEventFlagLocked();
111
112 // Create the EventFlag that is used to signal to the framework that sensor events have been
113 // written to the Event FMQ
114 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
115 result = ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
116 }
117
118 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
119 // events have been successfully read and handled by the framework.
120 mWakeLockQueue = std::make_unique<AidlMessageQueue<int32_t, SynchronizedReadWrite>>(
121 in_wakeLockDescriptor, true /* resetPointers */);
122
123 if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
124 result = ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
125 }
126 }
127
128 // Start the thread to read events from the Wake Lock FMQ
129 mReadWakeLockQueueRun = true;
130 mWakeLockThread = std::thread(startReadWakeLockThread, this);
131 return result;
132 }
133
injectSensorData(const Event & in_event)134 ScopedAStatus Sensors::injectSensorData(const Event& in_event) {
135 auto sensor = mSensors.find(in_event.sensorHandle);
136 if (sensor != mSensors.end()) {
137 return sensor->second->injectEvent(in_event);
138 }
139 return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(ERROR_BAD_VALUE));
140 }
141
registerDirectChannel(const ISensors::SharedMemInfo &,int32_t * _aidl_return)142 ScopedAStatus Sensors::registerDirectChannel(const ISensors::SharedMemInfo& /* in_mem */,
143 int32_t* _aidl_return) {
144 *_aidl_return = EX_UNSUPPORTED_OPERATION;
145
146 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
147 }
148
setOperationMode(OperationMode in_mode)149 ScopedAStatus Sensors::setOperationMode(OperationMode in_mode) {
150 for (auto sensor : mSensors) {
151 sensor.second->setOperationMode(in_mode);
152 }
153 return ScopedAStatus::ok();
154 }
155
unregisterDirectChannel(int32_t)156 ScopedAStatus Sensors::unregisterDirectChannel(int32_t /* in_channelHandle */) {
157 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
158 }
159
160 } // namespace sensors
161 } // namespace hardware
162 } // namespace android
163 } // namespace aidl
164