diff options
author | Jyoti Bhayana <jbhayana@google.com> | 2020-09-08 14:38:02 -0700 |
---|---|---|
committer | Jyoti Bhayana <jbhayana@google.com> | 2020-09-18 16:56:56 -0700 |
commit | 45a82661021d997dc5042239e58e420ef367d331 (patch) | |
tree | b658c8e24ef3063c741228bcb8a5835e2b1a5d58 /hal | |
parent | 11dfa08a25c7a506257ea39e75e38fc5b180bf4f (diff) | |
download | device_google_trout-45a82661021d997dc5042239e58e420ef367d331.tar.gz device_google_trout-45a82661021d997dc5042239e58e420ef367d331.tar.bz2 device_google_trout-45a82661021d997dc5042239e58e420ef367d331.zip |
Adding support for Sensor configuration and making sure that accel and
gyro comply with Android Car Coordinate system
Bug:163421259
Test: Build and run cts test testAccelerometer_50hz_batching making sure
that MeanVerification test pass
Change-Id: I2612427aa16ac20a8882d89de952aaf14b5b16df
Diffstat (limited to 'hal')
-rw-r--r-- | hal/sensors/2.0/Android.bp | 4 | ||||
-rw-r--r-- | hal/sensors/2.0/Sensor.cpp | 175 | ||||
-rw-r--r-- | hal/sensors/2.0/Sensor.h | 42 | ||||
-rw-r--r-- | hal/sensors/2.0/SensorsSubHal.cpp | 93 | ||||
-rw-r--r-- | hal/sensors/2.0/SensorsSubHal.h | 13 | ||||
-rw-r--r-- | hal/sensors/2.0/config/Android.bp | 20 | ||||
-rw-r--r-- | hal/sensors/2.0/config/api/current.txt | 88 | ||||
-rw-r--r-- | hal/sensors/2.0/config/api/last_current.txt | 0 | ||||
-rw-r--r-- | hal/sensors/2.0/config/api/last_removed.txt | 0 | ||||
-rw-r--r-- | hal/sensors/2.0/config/api/removed.txt | 1 | ||||
-rw-r--r-- | hal/sensors/2.0/config/sensor_hal_configuration.xml | 52 | ||||
-rw-r--r-- | hal/sensors/2.0/config/sensor_hal_configuration.xsd | 78 | ||||
-rw-r--r-- | hal/sensors/2.0/iio_utils.cpp | 1 |
13 files changed, 465 insertions, 102 deletions
diff --git a/hal/sensors/2.0/Android.bp b/hal/sensors/2.0/Android.bp index 2fb5466..bd35203 100644 --- a/hal/sensors/2.0/Android.bp +++ b/hal/sensors/2.0/Android.bp @@ -39,11 +39,13 @@ cc_library { ], static_libs: [ "android.hardware.sensors@2.X-multihal", + "libxml2", ], cflags: [ - "-DLOG_TAG=\"GoogleIIOSensorSubHal\"", "-Wall", "-Wextra", "-Werror", ], + generated_sources: ["sensor_hal_configuration_V1_0"], + generated_headers: ["sensor_hal_configuration_V1_0"], } diff --git a/hal/sensors/2.0/Sensor.cpp b/hal/sensors/2.0/Sensor.cpp index b5288e2..c221039 100644 --- a/hal/sensors/2.0/Sensor.cpp +++ b/hal/sensors/2.0/Sensor.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define LOG_TAG "GoogleIIOSensorSubHal" #include "Sensor.h" #include <hardware/sensors.h> @@ -30,6 +31,7 @@ namespace implementation { using ::android::hardware::sensors::V1_0::MetaDataEventType; using ::android::hardware::sensors::V1_0::SensorFlagBits; using ::android::hardware::sensors::V1_0::SensorStatus; +using ::sensor::hal::configuration::V1_0::Orientation; SensorBase::SensorBase(int32_t sensorHandle, ISensorsEventCallback* callback, SensorType type) : mIsEnabled(false), mSamplingPeriodNs(0), mCallback(callback), mMode(OperationMode::NORMAL) { @@ -69,7 +71,7 @@ SensorBase::~SensorBase() { } HWSensorBase::~HWSensorBase() { - close(mpollfd_iio.fd); + close(mPollFdIio.fd); } const SensorInfo& SensorBase::getSensorInfo() const { @@ -84,10 +86,10 @@ void HWSensorBase::batch(int32_t samplingPeriodNs) { int i = 0; mSamplingPeriodNs = samplingPeriodNs; std::vector<double>::iterator low = - std::lower_bound(miio_data.sampling_freq_avl.begin(), - miio_data.sampling_freq_avl.end(), sampling_frequency); - i = low - miio_data.sampling_freq_avl.begin(); - set_sampling_frequency(miio_data.sysfspath, miio_data.sampling_freq_avl[i]); + std::lower_bound(mIioData.sampling_freq_avl.begin(), + mIioData.sampling_freq_avl.end(), sampling_frequency); + i = low - mIioData.sampling_freq_avl.begin(); + set_sampling_frequency(mIioData.sysfspath, mIioData.sampling_freq_avl[i]); // Wake up the 'run' thread to check if a new event should be generated now mWaitCV.notify_all(); } @@ -97,7 +99,7 @@ void HWSensorBase::activate(bool enable) { std::unique_lock<std::mutex> lock(mRunMutex); if (mIsEnabled != enable) { mIsEnabled = enable; - enable_sensor(miio_data.sysfspath, enable); + enable_sensor(mIioData.sysfspath, enable); mWaitCV.notify_all(); } } @@ -120,27 +122,33 @@ Result SensorBase::flush() { return Result::OK; } +template <size_t N> +float getChannelData(const std::array<float, N>& channelData, int64_t map, bool negate) { + return negate ? -channelData[map] : channelData[map]; +} + void HWSensorBase::processScanData(uint8_t* data, Event* evt) { - float channelData[NUM_OF_CHANNEL_SUPPORTED - 1]; + std::array<float, NUM_OF_DATA_CHANNELS> channelData; unsigned int chanIdx; evt->sensorHandle = mSensorInfo.sensorHandle; evt->sensorType = mSensorInfo.type; - for (auto i = 0u; i < miio_data.channelInfo.size(); i++) { - chanIdx = miio_data.channelInfo[i].index; - const int64_t val = *reinterpret_cast<int64_t*>( - data + chanIdx * miio_data.channelInfo[i].storage_bytes); + for (auto i = 0u; i < mIioData.channelInfo.size(); i++) { + chanIdx = mIioData.channelInfo[i].index; + const int64_t val = + *reinterpret_cast<int64_t*>(data + chanIdx * mIioData.channelInfo[i].storage_bytes); // If the channel index is the last, it is timestamp // else it is sensor data - if (chanIdx == miio_data.channelInfo.size() - 1) { + if (chanIdx == mIioData.channelInfo.size() - 1) { evt->timestamp = val; } else { - channelData[chanIdx] = (static_cast<float>(val) * miio_data.resolution); + channelData[chanIdx] = static_cast<float>(val) * mIioData.resolution; } } - evt->u.vec3.x = channelData[0]; - evt->u.vec3.y = channelData[1]; - evt->u.vec3.z = channelData[2]; + + evt->u.vec3.x = getChannelData(channelData, mXMap, mXNegate); + evt->u.vec3.y = getChannelData(channelData, mYMap, mYNegate); + evt->u.vec3.z = getChannelData(channelData, mZMap, mZNegate); evt->u.vec3.status = SensorStatus::ACCURACY_HIGH; } @@ -157,19 +165,19 @@ void HWSensorBase::run() { return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread); }); } else { - err = poll(&mpollfd_iio, 1, mSamplingPeriodNs * 1000); + err = poll(&mPollFdIio, 1, mSamplingPeriodNs * 1000); if (err <= 0) { - ALOGE("Sensor %s poll returned %d", miio_data.name.c_str(), err); + ALOGE("Sensor %s poll returned %d", mIioData.name.c_str(), err); continue; } - if (mpollfd_iio.revents & POLLIN) { - read_size = read(mpollfd_iio.fd, &msensor_raw_data[0], mscan_size); + if (mPollFdIio.revents & POLLIN) { + read_size = read(mPollFdIio.fd, &mSensorRawData[0], mScanSize); if (read_size <= 0) { - ALOGE("%s: Failed to read data from iio char device.", miio_data.name.c_str()); + ALOGE("%s: Failed to read data from iio char device.", mIioData.name.c_str()); continue; } events.clear(); - processScanData(&msensor_raw_data[0], &event); + processScanData(&mSensorRawData[0], &event); events.push_back(event); mCallback->postEvents(events, isWakeUpSensor()); } @@ -210,15 +218,103 @@ Result SensorBase::injectEvent(const Event& event) { ssize_t HWSensorBase::calculateScanSize() { ssize_t numBytes = 0; - for (auto i = 0u; i < miio_data.channelInfo.size(); i++) { - numBytes += miio_data.channelInfo[i].storage_bytes; + for (auto i = 0u; i < mIioData.channelInfo.size(); i++) { + numBytes += mIioData.channelInfo[i].storage_bytes; } return numBytes; } -HWSensorBase::HWSensorBase(int32_t sensorHandle, ISensorsEventCallback* callback, SensorType type, - const struct iio_device_data& data) - : SensorBase(sensorHandle, callback, type) { +status_t checkAxis(int64_t map) { + if (map < 0 || map >= NUM_OF_DATA_CHANNELS) + return BAD_VALUE; + else + return OK; +} + +std::optional<std::vector<Orientation>> getOrientation( + std::optional<std::vector<Configuration>> config) { + if (!config) return std::nullopt; + if (config->empty()) return std::nullopt; + Configuration& sensorCfg = (*config)[0]; + return sensorCfg.getOrientation(); +} + +status_t checkOrientation(std::optional<std::vector<Configuration>> config) { + status_t ret = OK; + std::optional<std::vector<Orientation>> sensorOrientationList = getOrientation(config); + if (!sensorOrientationList) return OK; + if (sensorOrientationList->empty()) return OK; + Orientation& sensorOrientation = (*sensorOrientationList)[0]; + if (!sensorOrientation.getFirstX() || !sensorOrientation.getFirstY() || + !sensorOrientation.getFirstZ()) + return BAD_VALUE; + + int64_t xMap = sensorOrientation.getFirstX()->getMap(); + ret = checkAxis(xMap); + if (ret != OK) return ret; + int64_t yMap = sensorOrientation.getFirstY()->getMap(); + ret = checkAxis(yMap); + if (ret != OK) return ret; + int64_t zMap = sensorOrientation.getFirstZ()->getMap(); + ret = checkAxis(zMap); + if (ret != OK) return ret; + if (xMap == yMap || yMap == zMap || zMap == xMap) return BAD_VALUE; + return ret; +} + +void HWSensorBase::setAxisDefaultValues() { + mXMap = 0; + mYMap = 1; + mZMap = 2; + mXNegate = mYNegate = mZNegate = false; +} +void HWSensorBase::setOrientation(std::optional<std::vector<Configuration>> config) { + std::optional<std::vector<Orientation>> sensorOrientationList = getOrientation(config); + + if (sensorOrientationList && !sensorOrientationList->empty()) { + Orientation& sensorOrientation = (*sensorOrientationList)[0]; + + if (sensorOrientation.getRotate()) { + mXMap = sensorOrientation.getFirstX()->getMap(); + mXNegate = sensorOrientation.getFirstX()->getNegate(); + mYMap = sensorOrientation.getFirstY()->getMap(); + mYNegate = sensorOrientation.getFirstY()->getNegate(); + mZMap = sensorOrientation.getFirstZ()->getMap(); + mZNegate = sensorOrientation.getFirstZ()->getNegate(); + } else { + setAxisDefaultValues(); + } + } else { + setAxisDefaultValues(); + } +} + +status_t checkIIOData(const struct iio_device_data& iio_data) { + status_t ret = OK; + for (auto i = 0u; i < iio_data.channelInfo.size(); i++) { + if (iio_data.channelInfo[i].index > NUM_OF_DATA_CHANNELS) return BAD_VALUE; + } + return ret; +} +HWSensorBase* HWSensorBase::buildSensor(int32_t sensorHandle, ISensorsEventCallback* callback, + const struct iio_device_data& iio_data, + const std::optional<std::vector<Configuration>>& config) { + if (checkOrientation(config) != OK) { + ALOGE("Orientation of the sensor %s in the configuration file is invalid", + iio_data.name.c_str()); + return nullptr; + } + if (checkIIOData(iio_data) != OK) { + ALOGE("IIO channel index of the sensor %s is invalid", iio_data.name.c_str()); + return nullptr; + } + return new HWSensorBase(sensorHandle, callback, iio_data, config); +} + +HWSensorBase::HWSensorBase(int32_t sensorHandle, ISensorsEventCallback* callback, + const struct iio_device_data& data, + const std::optional<std::vector<Configuration>>& config) + : SensorBase(sensorHandle, callback, data.type) { std::string buffer_path; mSensorInfo.flags |= SensorFlagBits::CONTINUOUS_MODE; mSensorInfo.name = data.name; @@ -226,7 +322,8 @@ HWSensorBase::HWSensorBase(int32_t sensorHandle, ISensorsEventCallback* callback mSensorInfo.maxRange = data.max_range * data.resolution; mSensorInfo.power = (data.power_microwatts / 1000.f) / SENSOR_VOLTAGE_DEFAULT; // converting uW to mA - miio_data = data; + mIioData = data; + setOrientation(config); unsigned int max_sampling_frequency = 0; unsigned int min_sampling_frequency = UINT_MAX; for (auto i = 0u; i < data.sampling_freq_avl.size(); i++) { @@ -237,26 +334,16 @@ HWSensorBase::HWSensorBase(int32_t sensorHandle, ISensorsEventCallback* callback } mSensorInfo.minDelay = frequency_to_us(max_sampling_frequency); mSensorInfo.maxDelay = frequency_to_us(min_sampling_frequency); - mscan_size = calculateScanSize(); + mScanSize = calculateScanSize(); buffer_path = "/dev/iio:device"; - buffer_path.append(std::to_string(miio_data.iio_dev_num)); - mpollfd_iio.fd = open(buffer_path.c_str(), O_RDONLY | O_NONBLOCK); - if (mpollfd_iio.fd < 0) { + buffer_path.append(std::to_string(mIioData.iio_dev_num)); + mPollFdIio.fd = open(buffer_path.c_str(), O_RDONLY | O_NONBLOCK); + if (mPollFdIio.fd < 0) { ALOGE("%s: Failed to open iio char device (%s).", data.name.c_str(), buffer_path.c_str()); return; } - mpollfd_iio.events = POLLIN; - msensor_raw_data.resize(mscan_size); -} - -Accelerometer::Accelerometer(int32_t sensorHandle, ISensorsEventCallback* callback, - const struct iio_device_data& data) - : HWSensorBase(sensorHandle, callback, SensorType::ACCELEROMETER, data) { -} - -Gyroscope::Gyroscope(int32_t sensorHandle, ISensorsEventCallback* callback, - const struct iio_device_data& data) - : HWSensorBase(sensorHandle, callback, SensorType::GYROSCOPE, data) { + mPollFdIio.events = POLLIN; + mSensorRawData.resize(mScanSize); } } // namespace implementation diff --git a/hal/sensors/2.0/Sensor.h b/hal/sensors/2.0/Sensor.h index b8a927b..8f537ad 100644 --- a/hal/sensors/2.0/Sensor.h +++ b/hal/sensors/2.0/Sensor.h @@ -24,14 +24,19 @@ #include <thread> #include <vector> #include "iio_utils.h" +#include "sensor_hal_configuration_V1_0.h" #define NUM_OF_CHANNEL_SUPPORTED 4 +// Subtract the timestamp channel to get the number of data channels +#define NUM_OF_DATA_CHANNELS NUM_OF_CHANNEL_SUPPORTED - 1 using ::android::hardware::sensors::V1_0::Event; using ::android::hardware::sensors::V1_0::OperationMode; using ::android::hardware::sensors::V1_0::Result; using ::android::hardware::sensors::V1_0::SensorInfo; using ::android::hardware::sensors::V1_0::SensorType; +using ::sensor::hal::configuration::V1_0::AxisType; +using ::sensor::hal::configuration::V1_0::Configuration; namespace android { namespace hardware { @@ -90,36 +95,31 @@ class SensorBase { // HWSensorBase represents the actual physical sensor provided as the IIO device class HWSensorBase : public SensorBase { public: - HWSensorBase(int32_t sensorHandle, ISensorsEventCallback* callback, SensorType type, - const struct iio_device_data& iio_data); - virtual ~HWSensorBase() = 0; + static HWSensorBase* buildSensor(int32_t sensorHandle, ISensorsEventCallback* callback, + const struct iio_device_data& iio_data, + const std::optional<std::vector<Configuration>>& config); + ~HWSensorBase(); void batch(int32_t samplingPeriodNs); void activate(bool enable); - - struct iio_device_data miio_data; + struct iio_device_data mIioData; private: - ssize_t mscan_size; - struct pollfd mpollfd_iio; - std::vector<uint8_t> msensor_raw_data; + ssize_t mScanSize; + struct pollfd mPollFdIio; + std::vector<uint8_t> mSensorRawData; + int64_t mXMap, mYMap, mZMap; + bool mXNegate, mYNegate, mZNegate; + + HWSensorBase(int32_t sensorHandle, ISensorsEventCallback* callback, + const struct iio_device_data& iio_data, + const std::optional<std::vector<Configuration>>& config); ssize_t calculateScanSize(); void run(); + void setOrientation(std::optional<std::vector<Configuration>> config); void processScanData(uint8_t* data, Event* evt); + void setAxisDefaultValues(); }; - -class Accelerometer : public HWSensorBase { - public: - Accelerometer(int32_t sensorHandle, ISensorsEventCallback* callback, - const struct iio_device_data& iio_data); -}; - -class Gyroscope : public HWSensorBase { - public: - Gyroscope(int32_t sensorHandle, ISensorsEventCallback* callback, - const struct iio_device_data& iio_data); -}; - } // namespace implementation } // namespace subhal } // namespace V2_0 diff --git a/hal/sensors/2.0/SensorsSubHal.cpp b/hal/sensors/2.0/SensorsSubHal.cpp index 93fc948..4d80d9f 100644 --- a/hal/sensors/2.0/SensorsSubHal.cpp +++ b/hal/sensors/2.0/SensorsSubHal.cpp @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define LOG_TAG "GoogleIIOSensorSubHal" + #include "SensorsSubHal.h" #include <android/hardware/sensors/2.0/types.h> #include <log/log.h> @@ -32,59 +34,87 @@ namespace implementation { using ::android::hardware::Void; using ::android::hardware::sensors::V1_0::Event; -using ::android::hardware::sensors::V1_0::OperationMode; using ::android::hardware::sensors::V1_0::RateLevel; -using ::android::hardware::sensors::V1_0::Result; using ::android::hardware::sensors::V1_0::SharedMemInfo; using ::android::hardware::sensors::V2_0::SensorTimeout; using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock; +using ::sensor::hal::configuration::V1_0::Sensor; +using ::sensor::hal::configuration::V1_0::SensorHalConfiguration; #define SENSOR_SUPPORTED(SENSOR_NAME, SENSOR_TYPE) \ { .name = SENSOR_NAME, .type = SENSOR_TYPE, } +#define SENSOR_XML_CONFIG_FILE_NAME "sensor_hal_configuration.xml" +static const char* gSensorConfigLocationList[] = {"/odm/etc/sensors/", "/vendor/etc/sensors/"}; +static const int gSensorConfigLocationListSize = + (sizeof(gSensorConfigLocationList) / sizeof(gSensorConfigLocationList[0])); + +#define MODULE_NAME "android.hardware.sensors@2.0-Google-IIO-Subhal" + static const std::vector<sensors_supported_hal> sensors_supported = { SENSOR_SUPPORTED("scmi.iio.accel", SensorType::ACCELEROMETER), SENSOR_SUPPORTED("scmi.iio.gyro", SensorType::GYROSCOPE), }; +static std::optional<std::vector<Sensor>> readSensorsConfigFromXml() { + for (int i = 0; i < gSensorConfigLocationListSize; i++) { + const auto sensor_config_file = + std::string(gSensorConfigLocationList[i]) + SENSOR_XML_CONFIG_FILE_NAME; + auto sensorConfig = ::sensor::hal::configuration::V1_0::read(sensor_config_file.c_str()); + if (sensorConfig) { + auto modulesList = sensorConfig->getFirstModules()->get_module(); + for (auto module : modulesList) { + if (module.getHalName().compare(MODULE_NAME) == 0) { + return module.getFirstSensors()->getSensor(); + } + } + } + } + ALOGI("Could not find the sensors configuration for module %s", MODULE_NAME); + return std::nullopt; +} + +static std::optional<std::vector<Configuration>> getSensorConfiguration( + const std::vector<Sensor>& sensor_list, const std::string& name, SensorType type) { + for (auto sensor : sensor_list) { + if ((name.compare(sensor.getName()) == 0) && (type == (SensorType)sensor.getType())) { + return sensor.getConfiguration(); + } + } + ALOGI("Could not find the sensor configuration for %s ", name.c_str()); + return std::nullopt; +} + SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) { int err; std::vector<iio_device_data> iio_devices; + const auto sensors_config_list = readSensorsConfigFromXml(); err = load_iio_devices(&iio_devices, sensors_supported); if (err == 0) { - for (auto i = 0u; i < iio_devices.size(); i++) { - err = scan_elements(iio_devices[i].sysfspath, &iio_devices[i]); + for (auto& iio_device : iio_devices) { + err = scan_elements(iio_device.sysfspath, &iio_device); if (err == 0) { - err = enable_sensor(iio_devices[i].sysfspath, false); + err = enable_sensor(iio_device.sysfspath, false); if (err == 0) { - switch (iio_devices[i].type) { - case SensorType::ACCELEROMETER: - if (iio_devices[i].channelInfo.size() == NUM_OF_CHANNEL_SUPPORTED) { - AddSensor<Accelerometer>(iio_devices[i]); - } else { - ALOGE("Unexpected number of channels for Accelerometer"); - } - break; - - case SensorType::GYROSCOPE: - if (iio_devices[i].channelInfo.size() == NUM_OF_CHANNEL_SUPPORTED) { - AddSensor<Gyroscope>(iio_devices[i]); - } else { - ALOGE("Unexpected number fo channels for Gyroscope"); - } - break; - - default: - break; + std::optional<std::vector<Configuration>> sensor_configuration = std::nullopt; + if (sensors_config_list) + sensor_configuration = getSensorConfiguration( + *sensors_config_list, iio_device.name, iio_device.type); + + if (iio_device.channelInfo.size() == NUM_OF_CHANNEL_SUPPORTED) { + AddSensor(iio_device, sensor_configuration); + } else { + ALOGE("SensorsSubHal(): Unexpected number of channels for sensor %s", + iio_device.sysfspath.c_str()); } } else { ALOGE("SensorsSubHal(): Error in enabling_sensor %s to %d error code %d", - iio_devices[i].sysfspath.c_str(), false, err); + iio_device.sysfspath.c_str(), false, err); } } else { ALOGE("SensorsSubHal(): Error in scanning channels for IIO device %s error code %d", - iio_devices[i].sysfspath.c_str(), err); + iio_device.sysfspath.c_str(), err); } } } else { @@ -185,7 +215,7 @@ Return<void> SensorsSubHal::debug(const hidl_handle& fd, const hidl_vec<hidl_str stream << "handle: " << info.sensorHandle << std::endl; stream << "resolution: " << info.resolution << " minDelay: " << info.minDelay << " maxDelay:" << info.maxDelay << std::endl; - stream << "iio path" << hwSensor->miio_data.sysfspath << std::endl; + stream << "iio path" << hwSensor->mIioData.sysfspath << std::endl; } stream << std::endl; @@ -206,6 +236,15 @@ void SensorsSubHal::postEvents(const std::vector<Event>& events, bool wakeup) { ScopedWakelock wakelock = mCallback->createScopedWakelock(wakeup); mCallback->postEvents(events, std::move(wakelock)); } +void SensorsSubHal::AddSensor(const struct iio_device_data& iio_data, + const std::optional<std::vector<Configuration>>& config) { + HWSensorBase* sensor = HWSensorBase::buildSensor(mNextHandle++ /* sensorHandle */, + this /* callback */, iio_data, config); + if (sensor != nullptr) + mSensors[sensor->getSensorInfo().sensorHandle] = std::unique_ptr<SensorBase>(sensor); + else + ALOGE("Unable to add sensor %s as buildSensor returned null", iio_data.name.c_str()); +} } // namespace implementation } // namespace subhal diff --git a/hal/sensors/2.0/SensorsSubHal.h b/hal/sensors/2.0/SensorsSubHal.h index 47d9f98..26a5aad 100644 --- a/hal/sensors/2.0/SensorsSubHal.h +++ b/hal/sensors/2.0/SensorsSubHal.h @@ -33,6 +33,8 @@ using ::android::hardware::sensors::V1_0::OperationMode; using ::android::hardware::sensors::V1_0::Result; using ::android::hardware::sensors::V2_0::implementation::IHalProxyCallback; using ::android::hardware::sensors::V2_0::subhal::implementation::ISensorsEventCallback; +using ::sensor::hal::configuration::V1_0::Configuration; + /** * Implementation of a ISensorsSubHal that can be used as a reference HAL implementation of sensors * multihal 2.0. See the README file for more details. @@ -80,15 +82,8 @@ class SensorsSubHal : public ISensorsSubHal, public ISensorsEventCallback { void postEvents(const std::vector<Event>& events, bool wakeup) override; protected: - template <class T> - void AddSensor(const struct iio_device_data& iio_data) { - static_assert(std::is_base_of<SensorBase, T>::value == true, - "AddSensor called for Non-Sensor Type!!"); - - std::unique_ptr<T> sensor = std::make_unique<T>(mNextHandle++ /* sensorHandle */, - this /* callback */, iio_data); - mSensors[sensor->getSensorInfo().sensorHandle] = std::move(sensor); - } + void AddSensor(const struct iio_device_data& iio_data, + const std::optional<std::vector<Configuration>>& config); /** * A map of the available sensors diff --git a/hal/sensors/2.0/config/Android.bp b/hal/sensors/2.0/config/Android.bp new file mode 100644 index 0000000..1067e89 --- /dev/null +++ b/hal/sensors/2.0/config/Android.bp @@ -0,0 +1,20 @@ +// +// Copyright (C) 2020 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. + +xsd_config { + name: "sensor_hal_configuration_V1_0", + srcs: ["sensor_hal_configuration.xsd"], + package_name: "sensor.hal.configuration.V1_0", +} diff --git a/hal/sensors/2.0/config/api/current.txt b/hal/sensors/2.0/config/api/current.txt new file mode 100644 index 0000000..ef088c9 --- /dev/null +++ b/hal/sensors/2.0/config/api/current.txt @@ -0,0 +1,88 @@ +// Signature format: 2.0 +package sensor.hal.configuration.V1_0 { + + public class AxisType { + ctor public AxisType(); + method public java.math.BigInteger getMap(); + method public boolean getNegate(); + method public void setMap(java.math.BigInteger); + method public void setNegate(boolean); + } + + public class Configuration { + ctor public Configuration(); + method public sensor.hal.configuration.V1_0.Location getLocation(); + method public sensor.hal.configuration.V1_0.Orientation getOrientation(); + method public void setLocation(sensor.hal.configuration.V1_0.Location); + method public void setOrientation(sensor.hal.configuration.V1_0.Orientation); + } + + public class Location { + ctor public Location(); + method public java.math.BigDecimal getX(); + method public java.math.BigDecimal getY(); + method public java.math.BigDecimal getZ(); + method public void setX(java.math.BigDecimal); + method public void setY(java.math.BigDecimal); + method public void setZ(java.math.BigDecimal); + } + + public class Modules { + ctor public Modules(); + method public java.util.List<sensor.hal.configuration.V1_0.Modules.Module> getModule(); + } + + public static class Modules.Module { + ctor public Modules.Module(); + method public String getHalName(); + method public float getHalVersion(); + method public sensor.hal.configuration.V1_0.Sensors getSensors(); + method public void setHalName(String); + method public void setHalVersion(float); + method public void setSensors(sensor.hal.configuration.V1_0.Sensors); + } + + public class Orientation { + ctor public Orientation(); + method public boolean getRotate(); + method public sensor.hal.configuration.V1_0.AxisType getX(); + method public sensor.hal.configuration.V1_0.AxisType getY(); + method public sensor.hal.configuration.V1_0.AxisType getZ(); + method public void setRotate(boolean); + method public void setX(sensor.hal.configuration.V1_0.AxisType); + method public void setY(sensor.hal.configuration.V1_0.AxisType); + method public void setZ(sensor.hal.configuration.V1_0.AxisType); + } + + public class Sensor { + ctor public Sensor(); + method public sensor.hal.configuration.V1_0.Configuration getConfiguration(); + method public String getName(); + method public java.math.BigInteger getType(); + method public void setConfiguration(sensor.hal.configuration.V1_0.Configuration); + method public void setName(String); + method public void setType(java.math.BigInteger); + } + + public class SensorHalConfiguration { + ctor public SensorHalConfiguration(); + method public sensor.hal.configuration.V1_0.Modules getModules(); + method public float getVersion(); + method public void setModules(sensor.hal.configuration.V1_0.Modules); + method public void setVersion(float); + } + + public class Sensors { + ctor public Sensors(); + method public java.util.List<sensor.hal.configuration.V1_0.Sensor> getSensor(); + } + + public class XmlParser { + ctor public XmlParser(); + method public static sensor.hal.configuration.V1_0.SensorHalConfiguration read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/hal/sensors/2.0/config/api/last_current.txt b/hal/sensors/2.0/config/api/last_current.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/hal/sensors/2.0/config/api/last_current.txt diff --git a/hal/sensors/2.0/config/api/last_removed.txt b/hal/sensors/2.0/config/api/last_removed.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/hal/sensors/2.0/config/api/last_removed.txt diff --git a/hal/sensors/2.0/config/api/removed.txt b/hal/sensors/2.0/config/api/removed.txt new file mode 100644 index 0000000..d802177 --- /dev/null +++ b/hal/sensors/2.0/config/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/hal/sensors/2.0/config/sensor_hal_configuration.xml b/hal/sensors/2.0/config/sensor_hal_configuration.xml new file mode 100644 index 0000000..cdf8732 --- /dev/null +++ b/hal/sensors/2.0/config/sensor_hal_configuration.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- Copyright (C) 2020 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. +--> + +<sensorHalConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> + <modules> + <module halName="android.hardware.sensors@2.0-Google-IIO-Subhal" halVersion="2.0"> + <sensors> + <sensor name="scmi.iio.accel" type="1"> + <configuration> + <orientation rotate="true"> + <x map="0" negate="false"/> + <y map="1" negate="true"/> + <z map="2" negate="true"/> + </orientation> + <location> + <x>0</x> + <y>0</y> + <z>0</z> + </location> + </configuration> + </sensor> + <sensor name="scmi.iio.gyro" type="4"> + <configuration> + <orientation rotate="true"> + <x map="0" negate="false"/> + <y map="1" negate="true"/> + <z map="2" negate="true"/> + </orientation> + <location> + <x>0</x> + <y>0</y> + <z>0</z> + </location> + </configuration> + </sensor> + </sensors> + </module> + </modules> +</sensorHalConfiguration> diff --git a/hal/sensors/2.0/config/sensor_hal_configuration.xsd b/hal/sensors/2.0/config/sensor_hal_configuration.xsd new file mode 100644 index 0000000..78a42e6 --- /dev/null +++ b/hal/sensors/2.0/config/sensor_hal_configuration.xsd @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 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. +--> +<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:complexType name="axisType"> + <xs:attribute name="map" type="xs:positiveInteger" use="required"/> + <xs:attribute name="negate" type="xs:boolean" use="required"/> + </xs:complexType> + <xs:complexType name="orientation"> + <xs:sequence> + <xs:element name="x" type="axisType"/> + <xs:element name="y" type="axisType"/> + <xs:element name="z" type="axisType"/> + </xs:sequence> + <xs:attribute name="rotate" type="xs:boolean" use="required"/> + </xs:complexType> + <xs:complexType name="location"> + <xs:sequence> + <xs:element name="x" type="xs:decimal"/> + <xs:element name="y" type="xs:decimal"/> + <xs:element name="z" type="xs:decimal"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="configuration"> + <xs:sequence> + <xs:element name="orientation" type="orientation" /> + <xs:element name="location" type="location" /> + </xs:sequence> + </xs:complexType> + <!-- attribute type describes the sensor type. Possible values are the Enum + values of SensorType specified in hardware/interfaces/sensors/1.0/types.hal + --> + <xs:complexType name="sensor"> + <xs:sequence> + <xs:element name="configuration" type="configuration"/> + </xs:sequence> + <xs:attribute name="name" type="xs:string" use="required"/> + <xs:attribute name="type" type="xs:positiveInteger" use="required"/> + </xs:complexType> + <xs:complexType name="sensors"> + <xs:sequence> + <xs:element name="sensor" type="sensor" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="modules"> + <xs:sequence> + <xs:element name="module" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="sensors" type="sensors"/> + </xs:sequence> + <xs:attribute name="halName" type="xs:string" use="required"/> + <xs:attribute name="halVersion" type="xs:float" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:element name="sensorHalConfiguration"> + <xs:complexType> + <xs:sequence> + <xs:element name="modules" type="modules"/> + </xs:sequence> + <xs:attribute type="xs:float" name="version" use="required"/> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/hal/sensors/2.0/iio_utils.cpp b/hal/sensors/2.0/iio_utils.cpp index c6ff53a..6e31e5f 100644 --- a/hal/sensors/2.0/iio_utils.cpp +++ b/hal/sensors/2.0/iio_utils.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define LOG_TAG "GoogleIIOSensorSubHal" #include "iio_utils.h" #include <errno.h> |