Loading services/sensorservice/Android.mk +1 −13 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \ OrientationSensor.cpp \ RecentEventLogger.cpp \ RotationVectorSensor.cpp \ SensorDevice.cpp \ SensorDirectConnection.cpp \ SensorEventConnection.cpp \ SensorFusion.cpp \ Loading @@ -25,13 +26,6 @@ LOCAL_CFLAGS += -Wall -Werror -Wextra LOCAL_CFLAGS += -fvisibility=hidden ifeq ($(ENABLE_TREBLE), true) LOCAL_SRC_FILES += SensorDeviceTreble.cpp LOCAL_CFLAGS += -DENABLE_TREBLE=1 else LOCAL_SRC_FILES += SensorDevice.cpp endif LOCAL_SHARED_LIBRARIES := \ libcutils \ libhardware \ Loading @@ -42,10 +36,6 @@ LOCAL_SHARED_LIBRARIES := \ libui \ libgui \ libcrypto \ ifeq ($(ENABLE_TREBLE), true) LOCAL_SHARED_LIBRARIES += \ libbase \ libhidlbase \ libhidltransport \ Loading @@ -55,8 +45,6 @@ LOCAL_SHARED_LIBRARIES += \ LOCAL_STATIC_LIBRARIES := \ android.hardware.sensors@1.0-convert endif # ENABLE_TREBLE LOCAL_MODULE:= libsensorservice include $(BUILD_SHARED_LIBRARY) Loading services/sensorservice/SensorDevice.cpp +306 −201 Original line number Diff line number Diff line Loading @@ -14,138 +14,167 @@ * limitations under the License. */ #include <inttypes.h> #include <math.h> #include <stdint.h> #include <sys/types.h> #include <android-base/logging.h> #include <utils/Atomic.h> #include <utils/Errors.h> #include <utils/Singleton.h> #include "SensorDevice.h" #include "SensorService.h" #include <sensors/convert.h> #include <binder/BinderService.h> #include <binder/Parcel.h> #include <binder/IServiceManager.h> #include <cutils/ashmem.h> #include <hardware/sensors.h> #include <utils/Atomic.h> #include <utils/Errors.h> #include <utils/Singleton.h> using android::hardware::hidl_vec; #include <inttypes.h> #include <math.h> #include <sys/mman.h> #include <stdint.h> #include <sys/types.h> #include <sstream> #include <unistd.h> using namespace android::hardware::sensors::V1_0; using namespace android::hardware::sensors::V1_0::implementation; namespace android { // --------------------------------------------------------------------------- ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice) SensorDevice::SensorDevice() : mSensorDevice(0), mSensorModule(0) { status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); static status_t StatusFromResult(Result result) { switch (result) { case Result::OK: return OK; case Result::BAD_VALUE: return BAD_VALUE; case Result::PERMISSION_DENIED: return PERMISSION_DENIED; case Result::INVALID_OPERATION: return INVALID_OPERATION; case Result::NO_MEMORY: return NO_MEMORY; } } ALOGE_IF(err, "couldn't load %s module (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); SensorDevice::SensorDevice() { mSensors = ISensors::getService(); if (mSensorModule) { err = sensors_open_1(&mSensorModule->common, &mSensorDevice); if (mSensors == NULL) { return; } ALOGE_IF(err, "couldn't open device for module %s (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); mSensors->getSensorsList( [&](const auto &list) { const size_t count = list.size(); if (mSensorDevice) { mActivationCount.setCapacity(count); Info model; for (size_t i=0 ; i < count; i++) { sensor_t sensor; convertToSensor(list[i], &sensor); mSensorList.push_back(sensor); sensor_t const* list; ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); mActivationCount.add(list[i].sensorHandle, model); if (mSensorDevice->common.version < SENSORS_DEVICE_API_VERSION_1_3) { ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3, ignoring sensors reported by this device"); count = 0; mSensors->activate(list[i].sensorHandle, 0 /* enabled */); } }); mActivationCount.setCapacity(count); Info model; for (size_t i=0 ; i<size_t(count) ; i++) { mActivationCount.add(list[i].handle, model); mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), list[i].handle, 0); } } } mIsDirectReportSupported = (mSensors->unregisterDirectChannel(-1) != Result::INVALID_OPERATION); } void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) { if (connected) { Info model; mActivationCount.add(handle, model); mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0); mSensors->activate(handle, 0 /* enabled */); } else { mActivationCount.removeItem(handle); } } std::string SensorDevice::dump() const { if (!mSensorModule) return "HAL not initialized\n"; if (mSensors == NULL) return "HAL not initialized\n"; String8 result; sensor_t const* list; int count = mSensorModule->get_sensors_list(mSensorModule, &list); mSensors->getSensorsList([&](const auto &list) { const size_t count = list.size(); result.appendFormat("HAL: %s (%s), version %#010x\n", mSensorModule->common.name, mSensorModule->common.author, getHalDeviceVersion()); result.appendFormat("Total %d h/w sensors, %zu running:\n", count, mActivationCount.size()); result.appendFormat( "Total %zu h/w sensors, %zu running:\n", count, mActivationCount.size()); Mutex::Autolock _l(mLock); for (int i = 0 ; i < count ; i++) { const Info& info = mActivationCount.valueFor(list[i].handle); for (size_t i = 0 ; i < count ; i++) { const Info& info = mActivationCount.valueFor( list[i].sensorHandle); if (info.batchParams.isEmpty()) continue; result.appendFormat("0x%08x) active-count = %zu; ", list[i].handle, result.appendFormat( "0x%08x) active-count = %zu; ", list[i].sensorHandle, info.batchParams.size()); result.append("sampling_period(ms) = {"); for (size_t j = 0; j < info.batchParams.size(); j++) { const BatchParams& params = info.batchParams.valueAt(j); result.appendFormat("%.1f%s", params.batchDelay / 1e6f, result.appendFormat( "%.1f%s", params.batchDelay / 1e6f, j < info.batchParams.size() - 1 ? ", " : ""); } result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f); result.appendFormat( "}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f); result.append("batching_period(ms) = {"); for (size_t j = 0; j < info.batchParams.size(); j++) { BatchParams params = info.batchParams.valueAt(j); result.appendFormat("%.1f%s", params.batchTimeout / 1e6f, result.appendFormat( "%.1f%s", params.batchTimeout / 1e6f, j < info.batchParams.size() - 1 ? ", " : ""); } result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f); result.appendFormat( "}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f); } }); return result.string(); } ssize_t SensorDevice::getSensorList(sensor_t const** list) { if (!mSensorModule) return NO_INIT; ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list); return count; *list = &mSensorList[0]; return mSensorList.size(); } status_t SensorDevice::initCheck() const { return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT; return mSensors != NULL ? NO_ERROR : NO_INIT; } ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { if (!mSensorDevice) return NO_INIT; ssize_t c; do { c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), buffer, count); } while (c == -EINTR); return c; if (mSensors == NULL) return NO_INIT; ssize_t err; mSensors->poll( count, [&](auto result, const auto &events, const auto &dynamicSensorsAdded) { if (result == Result::OK) { convertToSensorEvents(events, dynamicSensorsAdded, buffer); err = (ssize_t)events.size(); } else { err = StatusFromResult(result); } }); return err; } void SensorDevice::autoDisable(void *ident, int handle) { Loading @@ -155,7 +184,8 @@ void SensorDevice::autoDisable(void *ident, int handle) { } status_t SensorDevice::activate(void* ident, int handle, int enabled) { if (!mSensorDevice) return NO_INIT; if (mSensors == NULL) return NO_INIT; status_t err(NO_ERROR); bool actuateHardware = false; Loading Loading @@ -187,13 +217,19 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { } else { ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident)); // If a connected dynamic sensor is deactivated, remove it from the // dictionary. auto it = mConnectedDynamicSensors.find(handle); if (it != mConnectedDynamicSensors.end()) { delete it->second; mConnectedDynamicSensors.erase(it); } if (info.removeBatchParamsForIdent(ident) >= 0) { if (info.numActiveClients() == 0) { // This is the last connection, we need to de-activate the underlying h/w sensor. actuateHardware = true; } else { const int halVersion = getHalDeviceVersion(); if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { // Call batch for this sensor with the previously calculated best effort // batch_rate and timeout. One of the apps has unregistered for sensor // events, and the best effort batch parameters might have changed. Loading @@ -201,11 +237,11 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags, mSensors->batch( handle, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); } } } else { // sensor wasn't enabled for this ident } Loading @@ -218,8 +254,7 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { if (actuateHardware) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled); err = mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled); err = StatusFromResult(mSensors->activate(handle, enabled)); ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle, strerror(-err)); Loading @@ -229,31 +264,21 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { } } // On older devices which do not support batch, call setDelay(). if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle, info.bestBatchParams.batchDelay); mSensorDevice->setDelay( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, info.bestBatchParams.batchDelay); } return err; } status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs, status_t SensorDevice::batch( void* ident, int handle, int flags, int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs) { if (!mSensorDevice) return NO_INIT; if (mSensors == NULL) return NO_INIT; if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { samplingPeriodNs = MINIMUM_EVENTS_PERIOD; } const int halVersion = getHalDeviceVersion(); if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) { // Batch is not supported on older devices return invalid operation. return INVALID_OPERATION; } ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64, ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs); Loading Loading @@ -282,21 +307,17 @@ status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplin status_t err(NO_ERROR); // If the min period or min timeout has changed since the last batch call, call batch. if (prevBestBatchParams != info.bestBatchParams) { if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags, err = StatusFromResult( mSensors->batch( handle, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); } else { // For older devices which do not support batch, call setDelay() after activate() is // called. Some older devices may not support calling setDelay before activate(), so // call setDelay in SensorDevice::activate() method. } info.bestBatchParams.batchTimeout)); if (err != NO_ERROR) { ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s", mSensorDevice, handle, mSensors.get(), handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout, strerror(-err)); info.removeBatchParamsForIdent(ident); Loading @@ -306,7 +327,7 @@ status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplin } status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) { if (!mSensorDevice) return NO_INIT; if (mSensors == NULL) return NO_INIT; if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { samplingPeriodNs = MINIMUM_EVENTS_PERIOD; } Loading @@ -325,22 +346,20 @@ status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodN BatchParams& params = info.batchParams.editValueAt(index); params.batchDelay = samplingPeriodNs; info.selectBatchParams(); return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, info.bestBatchParams.batchDelay); return StatusFromResult( mSensors->batch(handle, info.bestBatchParams.batchDelay, 0)); } int SensorDevice::getHalDeviceVersion() const { if (!mSensorDevice) return -1; return mSensorDevice->common.version; if (mSensors == NULL) return -1; return SENSORS_DEVICE_API_VERSION_1_4; } status_t SensorDevice::flush(void* ident, int handle) { if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) { return INVALID_OPERATION; } if (isClientDisabled(ident)) return INVALID_OPERATION; ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle); return mSensorDevice->flush(mSensorDevice, handle); return StatusFromResult(mSensors->flush(handle)); } bool SensorDevice::isClientDisabled(void* ident) { Loading @@ -356,7 +375,6 @@ void SensorDevice::enableAllSensors() { Mutex::Autolock _l(mLock); mDisabledClients.clear(); ALOGI("cleared mDisabledClients"); const int halVersion = getHalDeviceVersion(); for (size_t i = 0; i< mActivationCount.size(); ++i) { Info& info = mActivationCount.editValueAt(i); if (info.batchParams.isEmpty()) continue; Loading @@ -364,27 +382,18 @@ void SensorDevice::enableAllSensors() { const int sensor_handle = mActivationCount.keyAt(i); ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ", sensor_handle); status_t err(NO_ERROR); if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) { err = mSensorDevice->batch(mSensorDevice, sensor_handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); status_t err = StatusFromResult( mSensors->batch( sensor_handle, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout)); ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err)); } if (err == NO_ERROR) { err = mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), sensor_handle, 1); err = StatusFromResult( mSensors->activate(sensor_handle, 1 /* enabled */)); ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err)); } if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) { err = mSensorDevice->setDelay( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), sensor_handle, info.bestBatchParams.batchDelay); ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err)); } } } Loading @@ -397,9 +406,8 @@ void SensorDevice::disableAllSensors() { const int sensor_handle = mActivationCount.keyAt(i); ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ", sensor_handle); mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), sensor_handle, 0); mSensors->activate(sensor_handle, 0 /* enabled */); // Add all the connections that were registered for this sensor to the disabled // clients list. for (size_t j = 0; j < info.batchParams.size(); ++j) { Loading @@ -410,7 +418,8 @@ void SensorDevice::disableAllSensors() { } } status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) { status_t SensorDevice::injectSensorData( const sensors_event_t *injected_sensor_event) { ALOGD_IF(DEBUG_CONNECTIONS, "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f", injected_sensor_event->sensor, Loading @@ -418,17 +427,18 @@ status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_e injected_sensor_event->data[1], injected_sensor_event->data[2], injected_sensor_event->data[3], injected_sensor_event->data[4], injected_sensor_event->data[5]); if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) { return INVALID_OPERATION; } return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event); Event ev; convertFromSensorEvent(*injected_sensor_event, &ev); return StatusFromResult(mSensors->injectSensorData(ev)); } status_t SensorDevice::setMode(uint32_t mode) { if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) { return INVALID_OPERATION; } return mSensorModule->set_operation_mode(mode); return StatusFromResult( mSensors->setOperationMode( static_cast<hardware::sensors::V1_0::OperationMode>(mode))); } // --------------------------------------------------------------------------- Loading Loading @@ -491,44 +501,139 @@ void SensorDevice::notifyConnectionDestroyed(void* ident) { } int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) { Mutex::Autolock _l(mLock); if (!isDirectReportSupported()) { return INVALID_OPERATION; SharedMemType type; switch (memory->type) { case SENSOR_DIRECT_MEM_TYPE_ASHMEM: type = SharedMemType::ASHMEM; break; case SENSOR_DIRECT_MEM_TYPE_GRALLOC: type = SharedMemType::GRALLOC; break; default: return BAD_VALUE; } SharedMemFormat format; if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { return BAD_VALUE; } format = SharedMemFormat::SENSORS_EVENT; SharedMemInfo mem = { .type = type, .format = format, .size = static_cast<uint32_t>(memory->size), .memoryHandle = memory->handle, }; int32_t ret; mSensors->registerDirectChannel(mem, [&ret](auto result, auto channelHandle) { if (result == Result::OK) { ret = channelHandle; } else { ret = StatusFromResult(result); } }); return ret; } void SensorDevice::unregisterDirectChannel(int32_t channelHandle) { Mutex::Autolock _l(mLock); int32_t channelHandle = mSensorDevice->register_direct_channel( mSensorDevice, memory, -1 /*channel_handle*/); return channelHandle; mSensors->unregisterDirectChannel(channelHandle); } void SensorDevice::unregisterDirectChannel(int32_t channelHandle) { int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle, const struct sensors_direct_cfg_t *config) { Mutex::Autolock _l(mLock); mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle); RateLevel rate; switch(config->rate_level) { case SENSOR_DIRECT_RATE_STOP: rate = RateLevel::STOP; break; case SENSOR_DIRECT_RATE_NORMAL: rate = RateLevel::NORMAL; break; case SENSOR_DIRECT_RATE_FAST: rate = RateLevel::FAST; break; case SENSOR_DIRECT_RATE_VERY_FAST: rate = RateLevel::VERY_FAST; break; default: return BAD_VALUE; } int32_t ret; mSensors->configDirectReport(sensorHandle, channelHandle, rate, [&ret, rate] (auto result, auto token) { if (rate == RateLevel::STOP) { ret = StatusFromResult(result); } else { if (result == Result::OK) { ret = token; } else { ret = StatusFromResult(result); } } }); int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle, const struct sensors_direct_cfg_t *config) { return ret; } if (!isDirectReportSupported()) { return INVALID_OPERATION; bool SensorDevice::isDirectReportSupported() const { return mIsDirectReportSupported; } Mutex::Autolock _l(mLock); void SensorDevice::convertToSensorEvent( const Event &src, sensors_event_t *dst) { ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent( src, dst); int32_t ret = mSensorDevice->config_direct_report( mSensorDevice, sensorHandle, channelHandle, config); ALOGE_IF(ret < 0, "SensorDevice::configureDirectChannel ret %d", ret); return ret; if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) { const DynamicSensorInfo &dyn = src.u.dynamic; dst->dynamic_sensor_meta.connected = dyn.connected; dst->dynamic_sensor_meta.handle = dyn.sensorHandle; if (dyn.connected) { auto it = mConnectedDynamicSensors.find(dyn.sensorHandle); CHECK(it != mConnectedDynamicSensors.end()); dst->dynamic_sensor_meta.sensor = it->second; memcpy(dst->dynamic_sensor_meta.uuid, dyn.uuid.data(), sizeof(dst->dynamic_sensor_meta.uuid)); } } } bool SensorDevice::isDirectReportSupported() const { bool ret = mSensorDevice->register_direct_channel != nullptr && mSensorDevice->config_direct_report != nullptr; return ret; void SensorDevice::convertToSensorEvents( const hidl_vec<Event> &src, const hidl_vec<SensorInfo> &dynamicSensorsAdded, sensors_event_t *dst) { // Allocate a sensor_t structure for each dynamic sensor added and insert // it into the dictionary of connected dynamic sensors keyed by handle. for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) { const SensorInfo &info = dynamicSensorsAdded[i]; auto it = mConnectedDynamicSensors.find(info.sensorHandle); CHECK(it == mConnectedDynamicSensors.end()); sensor_t *sensor = new sensor_t; convertToSensor(info, sensor); mConnectedDynamicSensors.insert( std::make_pair(sensor->handle, sensor)); } for (size_t i = 0; i < src.size(); ++i) { convertToSensorEvent(src[i], &dst[i]); } } // --------------------------------------------------------------------------- }; // namespace android Loading
services/sensorservice/Android.mk +1 −13 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \ OrientationSensor.cpp \ RecentEventLogger.cpp \ RotationVectorSensor.cpp \ SensorDevice.cpp \ SensorDirectConnection.cpp \ SensorEventConnection.cpp \ SensorFusion.cpp \ Loading @@ -25,13 +26,6 @@ LOCAL_CFLAGS += -Wall -Werror -Wextra LOCAL_CFLAGS += -fvisibility=hidden ifeq ($(ENABLE_TREBLE), true) LOCAL_SRC_FILES += SensorDeviceTreble.cpp LOCAL_CFLAGS += -DENABLE_TREBLE=1 else LOCAL_SRC_FILES += SensorDevice.cpp endif LOCAL_SHARED_LIBRARIES := \ libcutils \ libhardware \ Loading @@ -42,10 +36,6 @@ LOCAL_SHARED_LIBRARIES := \ libui \ libgui \ libcrypto \ ifeq ($(ENABLE_TREBLE), true) LOCAL_SHARED_LIBRARIES += \ libbase \ libhidlbase \ libhidltransport \ Loading @@ -55,8 +45,6 @@ LOCAL_SHARED_LIBRARIES += \ LOCAL_STATIC_LIBRARIES := \ android.hardware.sensors@1.0-convert endif # ENABLE_TREBLE LOCAL_MODULE:= libsensorservice include $(BUILD_SHARED_LIBRARY) Loading
services/sensorservice/SensorDevice.cpp +306 −201 Original line number Diff line number Diff line Loading @@ -14,138 +14,167 @@ * limitations under the License. */ #include <inttypes.h> #include <math.h> #include <stdint.h> #include <sys/types.h> #include <android-base/logging.h> #include <utils/Atomic.h> #include <utils/Errors.h> #include <utils/Singleton.h> #include "SensorDevice.h" #include "SensorService.h" #include <sensors/convert.h> #include <binder/BinderService.h> #include <binder/Parcel.h> #include <binder/IServiceManager.h> #include <cutils/ashmem.h> #include <hardware/sensors.h> #include <utils/Atomic.h> #include <utils/Errors.h> #include <utils/Singleton.h> using android::hardware::hidl_vec; #include <inttypes.h> #include <math.h> #include <sys/mman.h> #include <stdint.h> #include <sys/types.h> #include <sstream> #include <unistd.h> using namespace android::hardware::sensors::V1_0; using namespace android::hardware::sensors::V1_0::implementation; namespace android { // --------------------------------------------------------------------------- ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice) SensorDevice::SensorDevice() : mSensorDevice(0), mSensorModule(0) { status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); static status_t StatusFromResult(Result result) { switch (result) { case Result::OK: return OK; case Result::BAD_VALUE: return BAD_VALUE; case Result::PERMISSION_DENIED: return PERMISSION_DENIED; case Result::INVALID_OPERATION: return INVALID_OPERATION; case Result::NO_MEMORY: return NO_MEMORY; } } ALOGE_IF(err, "couldn't load %s module (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); SensorDevice::SensorDevice() { mSensors = ISensors::getService(); if (mSensorModule) { err = sensors_open_1(&mSensorModule->common, &mSensorDevice); if (mSensors == NULL) { return; } ALOGE_IF(err, "couldn't open device for module %s (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); mSensors->getSensorsList( [&](const auto &list) { const size_t count = list.size(); if (mSensorDevice) { mActivationCount.setCapacity(count); Info model; for (size_t i=0 ; i < count; i++) { sensor_t sensor; convertToSensor(list[i], &sensor); mSensorList.push_back(sensor); sensor_t const* list; ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); mActivationCount.add(list[i].sensorHandle, model); if (mSensorDevice->common.version < SENSORS_DEVICE_API_VERSION_1_3) { ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3, ignoring sensors reported by this device"); count = 0; mSensors->activate(list[i].sensorHandle, 0 /* enabled */); } }); mActivationCount.setCapacity(count); Info model; for (size_t i=0 ; i<size_t(count) ; i++) { mActivationCount.add(list[i].handle, model); mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), list[i].handle, 0); } } } mIsDirectReportSupported = (mSensors->unregisterDirectChannel(-1) != Result::INVALID_OPERATION); } void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) { if (connected) { Info model; mActivationCount.add(handle, model); mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0); mSensors->activate(handle, 0 /* enabled */); } else { mActivationCount.removeItem(handle); } } std::string SensorDevice::dump() const { if (!mSensorModule) return "HAL not initialized\n"; if (mSensors == NULL) return "HAL not initialized\n"; String8 result; sensor_t const* list; int count = mSensorModule->get_sensors_list(mSensorModule, &list); mSensors->getSensorsList([&](const auto &list) { const size_t count = list.size(); result.appendFormat("HAL: %s (%s), version %#010x\n", mSensorModule->common.name, mSensorModule->common.author, getHalDeviceVersion()); result.appendFormat("Total %d h/w sensors, %zu running:\n", count, mActivationCount.size()); result.appendFormat( "Total %zu h/w sensors, %zu running:\n", count, mActivationCount.size()); Mutex::Autolock _l(mLock); for (int i = 0 ; i < count ; i++) { const Info& info = mActivationCount.valueFor(list[i].handle); for (size_t i = 0 ; i < count ; i++) { const Info& info = mActivationCount.valueFor( list[i].sensorHandle); if (info.batchParams.isEmpty()) continue; result.appendFormat("0x%08x) active-count = %zu; ", list[i].handle, result.appendFormat( "0x%08x) active-count = %zu; ", list[i].sensorHandle, info.batchParams.size()); result.append("sampling_period(ms) = {"); for (size_t j = 0; j < info.batchParams.size(); j++) { const BatchParams& params = info.batchParams.valueAt(j); result.appendFormat("%.1f%s", params.batchDelay / 1e6f, result.appendFormat( "%.1f%s", params.batchDelay / 1e6f, j < info.batchParams.size() - 1 ? ", " : ""); } result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f); result.appendFormat( "}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f); result.append("batching_period(ms) = {"); for (size_t j = 0; j < info.batchParams.size(); j++) { BatchParams params = info.batchParams.valueAt(j); result.appendFormat("%.1f%s", params.batchTimeout / 1e6f, result.appendFormat( "%.1f%s", params.batchTimeout / 1e6f, j < info.batchParams.size() - 1 ? ", " : ""); } result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f); result.appendFormat( "}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f); } }); return result.string(); } ssize_t SensorDevice::getSensorList(sensor_t const** list) { if (!mSensorModule) return NO_INIT; ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list); return count; *list = &mSensorList[0]; return mSensorList.size(); } status_t SensorDevice::initCheck() const { return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT; return mSensors != NULL ? NO_ERROR : NO_INIT; } ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { if (!mSensorDevice) return NO_INIT; ssize_t c; do { c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), buffer, count); } while (c == -EINTR); return c; if (mSensors == NULL) return NO_INIT; ssize_t err; mSensors->poll( count, [&](auto result, const auto &events, const auto &dynamicSensorsAdded) { if (result == Result::OK) { convertToSensorEvents(events, dynamicSensorsAdded, buffer); err = (ssize_t)events.size(); } else { err = StatusFromResult(result); } }); return err; } void SensorDevice::autoDisable(void *ident, int handle) { Loading @@ -155,7 +184,8 @@ void SensorDevice::autoDisable(void *ident, int handle) { } status_t SensorDevice::activate(void* ident, int handle, int enabled) { if (!mSensorDevice) return NO_INIT; if (mSensors == NULL) return NO_INIT; status_t err(NO_ERROR); bool actuateHardware = false; Loading Loading @@ -187,13 +217,19 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { } else { ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident)); // If a connected dynamic sensor is deactivated, remove it from the // dictionary. auto it = mConnectedDynamicSensors.find(handle); if (it != mConnectedDynamicSensors.end()) { delete it->second; mConnectedDynamicSensors.erase(it); } if (info.removeBatchParamsForIdent(ident) >= 0) { if (info.numActiveClients() == 0) { // This is the last connection, we need to de-activate the underlying h/w sensor. actuateHardware = true; } else { const int halVersion = getHalDeviceVersion(); if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { // Call batch for this sensor with the previously calculated best effort // batch_rate and timeout. One of the apps has unregistered for sensor // events, and the best effort batch parameters might have changed. Loading @@ -201,11 +237,11 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags, mSensors->batch( handle, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); } } } else { // sensor wasn't enabled for this ident } Loading @@ -218,8 +254,7 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { if (actuateHardware) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled); err = mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled); err = StatusFromResult(mSensors->activate(handle, enabled)); ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle, strerror(-err)); Loading @@ -229,31 +264,21 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) { } } // On older devices which do not support batch, call setDelay(). if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle, info.bestBatchParams.batchDelay); mSensorDevice->setDelay( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, info.bestBatchParams.batchDelay); } return err; } status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs, status_t SensorDevice::batch( void* ident, int handle, int flags, int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs) { if (!mSensorDevice) return NO_INIT; if (mSensors == NULL) return NO_INIT; if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { samplingPeriodNs = MINIMUM_EVENTS_PERIOD; } const int halVersion = getHalDeviceVersion(); if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) { // Batch is not supported on older devices return invalid operation. return INVALID_OPERATION; } ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64, ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs); Loading Loading @@ -282,21 +307,17 @@ status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplin status_t err(NO_ERROR); // If the min period or min timeout has changed since the last batch call, call batch. if (prevBestBatchParams != info.bestBatchParams) { if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags, err = StatusFromResult( mSensors->batch( handle, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); } else { // For older devices which do not support batch, call setDelay() after activate() is // called. Some older devices may not support calling setDelay before activate(), so // call setDelay in SensorDevice::activate() method. } info.bestBatchParams.batchTimeout)); if (err != NO_ERROR) { ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s", mSensorDevice, handle, mSensors.get(), handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout, strerror(-err)); info.removeBatchParamsForIdent(ident); Loading @@ -306,7 +327,7 @@ status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplin } status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) { if (!mSensorDevice) return NO_INIT; if (mSensors == NULL) return NO_INIT; if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { samplingPeriodNs = MINIMUM_EVENTS_PERIOD; } Loading @@ -325,22 +346,20 @@ status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodN BatchParams& params = info.batchParams.editValueAt(index); params.batchDelay = samplingPeriodNs; info.selectBatchParams(); return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, info.bestBatchParams.batchDelay); return StatusFromResult( mSensors->batch(handle, info.bestBatchParams.batchDelay, 0)); } int SensorDevice::getHalDeviceVersion() const { if (!mSensorDevice) return -1; return mSensorDevice->common.version; if (mSensors == NULL) return -1; return SENSORS_DEVICE_API_VERSION_1_4; } status_t SensorDevice::flush(void* ident, int handle) { if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) { return INVALID_OPERATION; } if (isClientDisabled(ident)) return INVALID_OPERATION; ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle); return mSensorDevice->flush(mSensorDevice, handle); return StatusFromResult(mSensors->flush(handle)); } bool SensorDevice::isClientDisabled(void* ident) { Loading @@ -356,7 +375,6 @@ void SensorDevice::enableAllSensors() { Mutex::Autolock _l(mLock); mDisabledClients.clear(); ALOGI("cleared mDisabledClients"); const int halVersion = getHalDeviceVersion(); for (size_t i = 0; i< mActivationCount.size(); ++i) { Info& info = mActivationCount.editValueAt(i); if (info.batchParams.isEmpty()) continue; Loading @@ -364,27 +382,18 @@ void SensorDevice::enableAllSensors() { const int sensor_handle = mActivationCount.keyAt(i); ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ", sensor_handle); status_t err(NO_ERROR); if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) { err = mSensorDevice->batch(mSensorDevice, sensor_handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); status_t err = StatusFromResult( mSensors->batch( sensor_handle, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout)); ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err)); } if (err == NO_ERROR) { err = mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), sensor_handle, 1); err = StatusFromResult( mSensors->activate(sensor_handle, 1 /* enabled */)); ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err)); } if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) { err = mSensorDevice->setDelay( reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), sensor_handle, info.bestBatchParams.batchDelay); ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err)); } } } Loading @@ -397,9 +406,8 @@ void SensorDevice::disableAllSensors() { const int sensor_handle = mActivationCount.keyAt(i); ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ", sensor_handle); mSensorDevice->activate( reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), sensor_handle, 0); mSensors->activate(sensor_handle, 0 /* enabled */); // Add all the connections that were registered for this sensor to the disabled // clients list. for (size_t j = 0; j < info.batchParams.size(); ++j) { Loading @@ -410,7 +418,8 @@ void SensorDevice::disableAllSensors() { } } status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) { status_t SensorDevice::injectSensorData( const sensors_event_t *injected_sensor_event) { ALOGD_IF(DEBUG_CONNECTIONS, "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f", injected_sensor_event->sensor, Loading @@ -418,17 +427,18 @@ status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_e injected_sensor_event->data[1], injected_sensor_event->data[2], injected_sensor_event->data[3], injected_sensor_event->data[4], injected_sensor_event->data[5]); if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) { return INVALID_OPERATION; } return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event); Event ev; convertFromSensorEvent(*injected_sensor_event, &ev); return StatusFromResult(mSensors->injectSensorData(ev)); } status_t SensorDevice::setMode(uint32_t mode) { if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) { return INVALID_OPERATION; } return mSensorModule->set_operation_mode(mode); return StatusFromResult( mSensors->setOperationMode( static_cast<hardware::sensors::V1_0::OperationMode>(mode))); } // --------------------------------------------------------------------------- Loading Loading @@ -491,44 +501,139 @@ void SensorDevice::notifyConnectionDestroyed(void* ident) { } int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) { Mutex::Autolock _l(mLock); if (!isDirectReportSupported()) { return INVALID_OPERATION; SharedMemType type; switch (memory->type) { case SENSOR_DIRECT_MEM_TYPE_ASHMEM: type = SharedMemType::ASHMEM; break; case SENSOR_DIRECT_MEM_TYPE_GRALLOC: type = SharedMemType::GRALLOC; break; default: return BAD_VALUE; } SharedMemFormat format; if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { return BAD_VALUE; } format = SharedMemFormat::SENSORS_EVENT; SharedMemInfo mem = { .type = type, .format = format, .size = static_cast<uint32_t>(memory->size), .memoryHandle = memory->handle, }; int32_t ret; mSensors->registerDirectChannel(mem, [&ret](auto result, auto channelHandle) { if (result == Result::OK) { ret = channelHandle; } else { ret = StatusFromResult(result); } }); return ret; } void SensorDevice::unregisterDirectChannel(int32_t channelHandle) { Mutex::Autolock _l(mLock); int32_t channelHandle = mSensorDevice->register_direct_channel( mSensorDevice, memory, -1 /*channel_handle*/); return channelHandle; mSensors->unregisterDirectChannel(channelHandle); } void SensorDevice::unregisterDirectChannel(int32_t channelHandle) { int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle, const struct sensors_direct_cfg_t *config) { Mutex::Autolock _l(mLock); mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle); RateLevel rate; switch(config->rate_level) { case SENSOR_DIRECT_RATE_STOP: rate = RateLevel::STOP; break; case SENSOR_DIRECT_RATE_NORMAL: rate = RateLevel::NORMAL; break; case SENSOR_DIRECT_RATE_FAST: rate = RateLevel::FAST; break; case SENSOR_DIRECT_RATE_VERY_FAST: rate = RateLevel::VERY_FAST; break; default: return BAD_VALUE; } int32_t ret; mSensors->configDirectReport(sensorHandle, channelHandle, rate, [&ret, rate] (auto result, auto token) { if (rate == RateLevel::STOP) { ret = StatusFromResult(result); } else { if (result == Result::OK) { ret = token; } else { ret = StatusFromResult(result); } } }); int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle, const struct sensors_direct_cfg_t *config) { return ret; } if (!isDirectReportSupported()) { return INVALID_OPERATION; bool SensorDevice::isDirectReportSupported() const { return mIsDirectReportSupported; } Mutex::Autolock _l(mLock); void SensorDevice::convertToSensorEvent( const Event &src, sensors_event_t *dst) { ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent( src, dst); int32_t ret = mSensorDevice->config_direct_report( mSensorDevice, sensorHandle, channelHandle, config); ALOGE_IF(ret < 0, "SensorDevice::configureDirectChannel ret %d", ret); return ret; if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) { const DynamicSensorInfo &dyn = src.u.dynamic; dst->dynamic_sensor_meta.connected = dyn.connected; dst->dynamic_sensor_meta.handle = dyn.sensorHandle; if (dyn.connected) { auto it = mConnectedDynamicSensors.find(dyn.sensorHandle); CHECK(it != mConnectedDynamicSensors.end()); dst->dynamic_sensor_meta.sensor = it->second; memcpy(dst->dynamic_sensor_meta.uuid, dyn.uuid.data(), sizeof(dst->dynamic_sensor_meta.uuid)); } } } bool SensorDevice::isDirectReportSupported() const { bool ret = mSensorDevice->register_direct_channel != nullptr && mSensorDevice->config_direct_report != nullptr; return ret; void SensorDevice::convertToSensorEvents( const hidl_vec<Event> &src, const hidl_vec<SensorInfo> &dynamicSensorsAdded, sensors_event_t *dst) { // Allocate a sensor_t structure for each dynamic sensor added and insert // it into the dictionary of connected dynamic sensors keyed by handle. for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) { const SensorInfo &info = dynamicSensorsAdded[i]; auto it = mConnectedDynamicSensors.find(info.sensorHandle); CHECK(it == mConnectedDynamicSensors.end()); sensor_t *sensor = new sensor_t; convertToSensor(info, sensor); mConnectedDynamicSensors.insert( std::make_pair(sensor->handle, sensor)); } for (size_t i = 0; i < src.size(); ++i) { convertToSensorEvent(src[i], &dst[i]); } } // --------------------------------------------------------------------------- }; // namespace android