| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H |
| #define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H |
| |
| #include "SensorEventCallback.h" |
| #include "RingBuffer.h" |
| #include <hardware/sensors.h> |
| #include <utils/RefBase.h> |
| |
| #include <mutex> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| namespace android { |
| namespace SensorHalExt { |
| |
| class BaseDynamicSensorDaemon; |
| |
| class DynamicSensorManager : public SensorEventCallback { |
| public: |
| // handleBase is reserved for the dynamic sensor meta sensor. |
| // handleMax must be greater than handleBase + 1. |
| // This class has two operation mode depending on callback: 1) extension, 2) stand-alone. |
| // In extension mode, callback must not be nullptr. Sensor event generated will be submitted to |
| // buffer of primary sensor HAL implementation. In stand-alone mode, callback must be nullptr. |
| // Generated sensor events will be added into internal buffer waiting for poll() function to |
| // pick up. |
| // |
| static DynamicSensorManager* createInstance( |
| int handleBase, int handleCount, SensorEventCallback *callback); |
| virtual ~DynamicSensorManager(); |
| |
| // calls to add or remove sensor, called from sensor daemon |
| bool registerSensor(sp<BaseSensorObject> sensor); |
| void unregisterSensor(sp<BaseSensorObject> sensor); |
| |
| // Determine if a sensor handle is in the range defined in constructor. |
| // It does not test if sensor handle is valid. |
| bool owns(int handle) const; |
| |
| // handles sensor hal requests. |
| int activate(int handle, bool enable); |
| int batch(int handle, nsecs_t sample_period, nsecs_t batch_period); |
| int setDelay(int handle, nsecs_t sample_period); |
| int flush(int handle); |
| int poll(sensors_event_t * data, int count); |
| |
| // SensorEventCallback |
| virtual int submitEvent(sp<BaseSensorObject>, const sensors_event_t &e) override; |
| |
| // get meta sensor struct |
| const sensor_t& getDynamicMetaSensor() const; |
| protected: |
| DynamicSensorManager(int handleBase, int handleMax, SensorEventCallback* callback); |
| private: |
| // a helper class used for generate connection and disconnection report |
| class ConnectionReport { |
| public: |
| ConnectionReport() {} |
| ConnectionReport(int handle, sp<BaseSensorObject> sensor); |
| ~ConnectionReport(); |
| const sensors_event_t& generateConnectionEvent(int metaHandle); |
| static void fillDisconnectionEvent(sensors_event_t* event, int metaHandle, int handle); |
| private: |
| sensor_t mSensor; |
| std::string mName; |
| std::string mVendor; |
| std::string mPermission; |
| std::string mStringType; |
| sensors_event_t mEvent; |
| uint8_t mUuid[16]; |
| bool mGenerated; |
| DISALLOW_EVIL_CONSTRUCTORS(ConnectionReport); |
| }; |
| |
| // returns next available handle to use upon a new sensor connection, or -1 if we run out. |
| int getNextAvailableHandle(); |
| |
| // TF: int foo(sp<BaseSensorObject> obj); |
| template <typename TF> |
| int operateSensor(int handle, TF f) const { |
| std::lock_guard<std::mutex> lk(mLock); |
| const auto i = mMap.find(handle); |
| if (i == mMap.end()) { |
| return BAD_VALUE; |
| } |
| sp<BaseSensorObject> s = i->second.promote(); |
| if (s == nullptr) { |
| // sensor object is already gone |
| return BAD_VALUE; |
| } |
| return f(s); |
| } |
| |
| // available sensor handle space |
| const std::pair<int, int> mHandleRange; |
| sensor_t mMetaSensor; |
| |
| // immutable pointer to event callback, used in extention mode. |
| SensorEventCallback * const mCallback; |
| |
| // RingBuffer used in standalone mode |
| static constexpr size_t kFifoSize = 4096; //4K events |
| mutable std::mutex mFifoLock; |
| RingBuffer mFifo; |
| |
| // mapping between handle and SensorObjects |
| mutable std::mutex mLock; |
| int mNextHandle; |
| std::unordered_map<int, wp<BaseSensorObject>> mMap; |
| std::unordered_map<void *, int> mReverseMap; |
| mutable std::unordered_map<int, ConnectionReport> mPendingReport; |
| |
| // daemons |
| std::vector<sp<BaseDynamicSensorDaemon>> mDaemonVector; |
| }; |
| |
| } // namespace SensorHalExt |
| } // namespace android |
| |
| #endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H |