/* * 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 #include #include #include #include #include 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 sensor); void unregisterSensor(sp 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, 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 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 obj); template int operateSensor(int handle, TF f) const { sp s; { std::lock_guard lk(mLock); const auto i = mMap.find(handle); if (i == mMap.end()) { return BAD_VALUE; } 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 mHandleRange; sensor_t mMetaSensor; bool mMetaSensorActive = false; // 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> mMap; std::unordered_map mReverseMap; mutable std::unordered_map mPendingReport; // daemons std::vector> mDaemonVector; }; } // namespace SensorHalExt } // namespace android #endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H