/* * Copyright (C) 2010 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. */ #include #include #include #include #include #include #include #include #include #include #include "SensorDevice.h" #include "SensorService.h" 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); ALOGE_IF(err, "couldn't load %s module (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); if (mSensorModule) { err = sensors_open(&mSensorModule->common, &mSensorDevice); ALOGE_IF(err, "couldn't open device for module %s (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); if (mSensorDevice) { sensor_t const* list; ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); mActivationCount.setCapacity(count); Info model; for (size_t i=0 ; iactivate(mSensorDevice, list[i].handle, 0); } } } } void SensorDevice::dump(String8& result, char* buffer, size_t SIZE) { if (!mSensorModule) return; sensor_t const* list; ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); snprintf(buffer, SIZE, "%d h/w sensors:\n", int(count)); result.append(buffer); Mutex::Autolock _l(mLock); for (size_t i=0 ; iget_sensors_list(mSensorModule, list); return count; } status_t SensorDevice::initCheck() const { return mSensorDevice && mSensorModule ? 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(mSensorDevice, buffer, count); } while (c == -EINTR); return c; } status_t SensorDevice::activate(void* ident, int handle, int enabled) { if (!mSensorDevice) return NO_INIT; status_t err(NO_ERROR); bool actuateHardware = false; Info& info( mActivationCount.editValueFor(handle) ); ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d", ident, handle, enabled, info.rates.size()); if (enabled) { Mutex::Autolock _l(mLock); ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld", info.rates.indexOfKey(ident)); if (info.rates.indexOfKey(ident) < 0) { info.rates.add(ident, DEFAULT_EVENTS_PERIOD); if (info.rates.size() == 1) { actuateHardware = true; } } else { // sensor was already activated for this ident } } else { Mutex::Autolock _l(mLock); ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld", info.rates.indexOfKey(ident)); ssize_t idx = info.rates.removeItem(ident); if (idx >= 0) { if (info.rates.size() == 0) { actuateHardware = true; } } else { // sensor wasn't enabled for this ident } } if (actuateHardware) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w"); err = mSensorDevice->activate(mSensorDevice, handle, enabled); ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle, strerror(-err)); } { // scope for the lock Mutex::Autolock _l(mLock); nsecs_t ns = info.selectDelay(); mSensorDevice->setDelay(mSensorDevice, handle, ns); } return err; } status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns) { if (!mSensorDevice) return NO_INIT; Mutex::Autolock _l(mLock); Info& info( mActivationCount.editValueFor(handle) ); status_t err = info.setDelayForIdent(ident, ns); if (err < 0) return err; ns = info.selectDelay(); return mSensorDevice->setDelay(mSensorDevice, handle, ns); } // --------------------------------------------------------------------------- status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns) { ssize_t index = rates.indexOfKey(ident); if (index < 0) { ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)", ident, ns, strerror(-index)); return BAD_INDEX; } rates.editValueAt(index) = ns; return NO_ERROR; } nsecs_t SensorDevice::Info::selectDelay() { nsecs_t ns = rates.valueAt(0); for (size_t i=1 ; i