1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdint.h> 18 #include <math.h> 19 #include <sys/types.h> 20 21 #include <utils/Atomic.h> 22 #include <utils/Errors.h> 23 #include <utils/Singleton.h> 24 25 #include <binder/BinderService.h> 26 #include <binder/Parcel.h> 27 #include <binder/IServiceManager.h> 28 29 #include <hardware/sensors.h> 30 31 #include "SensorDevice.h" 32 #include "SensorService.h" 33 34 namespace android { 35 // --------------------------------------------------------------------------- 36 37 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice) 38 39 SensorDevice::SensorDevice() 40 : mSensorDevice(0), 41 mSensorModule(0) 42 { 43 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, 44 (hw_module_t const**)&mSensorModule); 45 46 ALOGE_IF(err, "couldn't load %s module (%s)", 47 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 48 49 if (mSensorModule) { 50 err = sensors_open(&mSensorModule->common, &mSensorDevice); 51 52 ALOGE_IF(err, "couldn't open device for module %s (%s)", 53 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 54 55 if (mSensorDevice) { 56 sensor_t const* list; 57 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); 58 mActivationCount.setCapacity(count); 59 Info model; 60 for (size_t i=0 ; i<size_t(count) ; i++) { 61 mActivationCount.add(list[i].handle, model); 62 mSensorDevice->activate(mSensorDevice, list[i].handle, 0); 63 } 64 } 65 } 66 } 67 68 void SensorDevice::dump(String8& result, char* buffer, size_t SIZE) 69 { 70 if (!mSensorModule) return; 71 sensor_t const* list; 72 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); 73 74 snprintf(buffer, SIZE, "%d h/w sensors:\n", int(count)); 75 result.append(buffer); 76 77 Mutex::Autolock _l(mLock); 78 for (size_t i=0 ; i<size_t(count) ; i++) { 79 const Info& info = mActivationCount.valueFor(list[i].handle); 80 snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d, rates(ms)={ ", 81 list[i].handle, 82 info.rates.size()); 83 result.append(buffer); 84 for (size_t j=0 ; j<info.rates.size() ; j++) { 85 snprintf(buffer, SIZE, "%4.1f%s", 86 info.rates.valueAt(j) / 1e6f, 87 j<info.rates.size()-1 ? ", " : ""); 88 result.append(buffer); 89 } 90 snprintf(buffer, SIZE, " }, selected=%4.1f ms\n", info.delay / 1e6f); 91 result.append(buffer); 92 } 93 } 94 95 ssize_t SensorDevice::getSensorList(sensor_t const** list) { 96 if (!mSensorModule) return NO_INIT; 97 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list); 98 return count; 99 } 100 101 status_t SensorDevice::initCheck() const { 102 return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT; 103 } 104 105 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { 106 if (!mSensorDevice) return NO_INIT; 107 ssize_t c; 108 do { 109 c = mSensorDevice->poll(mSensorDevice, buffer, count); 110 } while (c == -EINTR); 111 return c; 112 } 113 114 void SensorDevice::autoDisable(void *ident, int handle) { 115 Info& info( mActivationCount.editValueFor(handle) ); 116 Mutex::Autolock _l(mLock); 117 info.rates.removeItem(ident); 118 } 119 120 status_t SensorDevice::activate(void* ident, int handle, int enabled) 121 { 122 if (!mSensorDevice) return NO_INIT; 123 status_t err(NO_ERROR); 124 bool actuateHardware = false; 125 126 Info& info( mActivationCount.editValueFor(handle) ); 127 128 129 ALOGD_IF(DEBUG_CONNECTIONS, 130 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d", 131 ident, handle, enabled, info.rates.size()); 132 133 if (enabled) { 134 Mutex::Autolock _l(mLock); 135 ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld", 136 info.rates.indexOfKey(ident)); 137 138 if (info.rates.indexOfKey(ident) < 0) { 139 info.rates.add(ident, DEFAULT_EVENTS_PERIOD); 140 if (info.rates.size() == 1) { 141 actuateHardware = true; 142 } 143 } else { 144 // sensor was already activated for this ident 145 } 146 } else { 147 Mutex::Autolock _l(mLock); 148 ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld", 149 info.rates.indexOfKey(ident)); 150 151 ssize_t idx = info.rates.removeItem(ident); 152 if (idx >= 0) { 153 if (info.rates.size() == 0) { 154 actuateHardware = true; 155 } 156 } else { 157 // sensor wasn't enabled for this ident 158 } 159 } 160 161 if (actuateHardware) { 162 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w"); 163 164 err = mSensorDevice->activate(mSensorDevice, handle, enabled); 165 ALOGE_IF(err, "Error %s sensor %d (%s)", 166 enabled ? "activating" : "disabling", 167 handle, strerror(-err)); 168 169 if (err != NO_ERROR) { 170 // clean-up on failure 171 if (enabled) { 172 // failure when enabling the sensor 173 Mutex::Autolock _l(mLock); 174 info.rates.removeItem(ident); 175 } 176 } 177 } 178 179 { // scope for the lock 180 Mutex::Autolock _l(mLock); 181 nsecs_t ns = info.selectDelay(); 182 mSensorDevice->setDelay(mSensorDevice, handle, ns); 183 } 184 185 return err; 186 } 187 188 status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns) 189 { 190 if (!mSensorDevice) return NO_INIT; 191 Mutex::Autolock _l(mLock); 192 Info& info( mActivationCount.editValueFor(handle) ); 193 status_t err = info.setDelayForIdent(ident, ns); 194 if (err < 0) return err; 195 ns = info.selectDelay(); 196 return mSensorDevice->setDelay(mSensorDevice, handle, ns); 197 } 198 199 int SensorDevice::getHalDeviceVersion() const { 200 if (!mSensorDevice) return -1; 201 202 return mSensorDevice->common.version; 203 } 204 205 // --------------------------------------------------------------------------- 206 207 status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns) 208 { 209 ssize_t index = rates.indexOfKey(ident); 210 if (index < 0) { 211 ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)", 212 ident, ns, strerror(-index)); 213 return BAD_INDEX; 214 } 215 rates.editValueAt(index) = ns; 216 return NO_ERROR; 217 } 218 219 nsecs_t SensorDevice::Info::selectDelay() 220 { 221 nsecs_t ns = rates.valueAt(0); 222 for (size_t i=1 ; i<rates.size() ; i++) { 223 nsecs_t cur = rates.valueAt(i); 224 if (cur < ns) { 225 ns = cur; 226 } 227 } 228 delay = ns; 229 return ns; 230 } 231 232 // --------------------------------------------------------------------------- 233 }; // namespace android 234 235