1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/hal/gonk/GonkSensor.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,307 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* Copyright 2012 Mozilla Foundation and Mozilla contributors 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +#include <pthread.h> 1.21 +#include <stdio.h> 1.22 + 1.23 +#include "mozilla/DebugOnly.h" 1.24 + 1.25 +#include "base/basictypes.h" 1.26 +#include "base/thread.h" 1.27 + 1.28 +#include "Hal.h" 1.29 +#include "HalSensor.h" 1.30 +#include "hardware/sensors.h" 1.31 +#include "nsThreadUtils.h" 1.32 + 1.33 +#undef LOG 1.34 + 1.35 +#include <android/log.h> 1.36 + 1.37 +using namespace mozilla::hal; 1.38 + 1.39 +#define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "GonkSensor" , ## args) 1.40 +#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "GonkSensor" , ## args) 1.41 + 1.42 +namespace mozilla { 1.43 + 1.44 +// The value from SensorDevice.h (Android) 1.45 +#define DEFAULT_DEVICE_POLL_RATE 200000000 /*200ms*/ 1.46 +// ProcessOrientation.cpp needs smaller poll rate to detect delay between 1.47 +// different orientation angles 1.48 +#define ACCELEROMETER_POLL_RATE 66667000 /*66.667ms*/ 1.49 + 1.50 +double radToDeg(double a) { 1.51 + return a * (180.0 / M_PI); 1.52 +} 1.53 + 1.54 +static SensorType 1.55 +HardwareSensorToHalSensor(int type) 1.56 +{ 1.57 + switch(type) { 1.58 + case SENSOR_TYPE_ORIENTATION: 1.59 + return SENSOR_ORIENTATION; 1.60 + case SENSOR_TYPE_ACCELEROMETER: 1.61 + return SENSOR_ACCELERATION; 1.62 + case SENSOR_TYPE_PROXIMITY: 1.63 + return SENSOR_PROXIMITY; 1.64 + case SENSOR_TYPE_LIGHT: 1.65 + return SENSOR_LIGHT; 1.66 + case SENSOR_TYPE_GYROSCOPE: 1.67 + return SENSOR_GYROSCOPE; 1.68 + case SENSOR_TYPE_LINEAR_ACCELERATION: 1.69 + return SENSOR_LINEAR_ACCELERATION; 1.70 + default: 1.71 + return SENSOR_UNKNOWN; 1.72 + } 1.73 +} 1.74 + 1.75 +static SensorAccuracyType 1.76 +HardwareStatusToHalAccuracy(int status) { 1.77 + return static_cast<SensorAccuracyType>(status); 1.78 +} 1.79 + 1.80 +static int 1.81 +HalSensorToHardwareSensor(SensorType type) 1.82 +{ 1.83 + switch(type) { 1.84 + case SENSOR_ORIENTATION: 1.85 + return SENSOR_TYPE_ORIENTATION; 1.86 + case SENSOR_ACCELERATION: 1.87 + return SENSOR_TYPE_ACCELEROMETER; 1.88 + case SENSOR_PROXIMITY: 1.89 + return SENSOR_TYPE_PROXIMITY; 1.90 + case SENSOR_LIGHT: 1.91 + return SENSOR_TYPE_LIGHT; 1.92 + case SENSOR_GYROSCOPE: 1.93 + return SENSOR_TYPE_GYROSCOPE; 1.94 + case SENSOR_LINEAR_ACCELERATION: 1.95 + return SENSOR_TYPE_LINEAR_ACCELERATION; 1.96 + default: 1.97 + return -1; 1.98 + } 1.99 +} 1.100 + 1.101 +static int 1.102 +SensorseventStatus(const sensors_event_t& data) 1.103 +{ 1.104 + int type = data.type; 1.105 + switch(type) { 1.106 + case SENSOR_ORIENTATION: 1.107 + return data.orientation.status; 1.108 + case SENSOR_LINEAR_ACCELERATION: 1.109 + case SENSOR_ACCELERATION: 1.110 + return data.acceleration.status; 1.111 + case SENSOR_GYROSCOPE: 1.112 + return data.gyro.status; 1.113 + } 1.114 + 1.115 + return SENSOR_STATUS_UNRELIABLE; 1.116 +} 1.117 + 1.118 +class SensorRunnable : public nsRunnable 1.119 +{ 1.120 +public: 1.121 + SensorRunnable(const sensors_event_t& data, const sensor_t* sensors, ssize_t size) 1.122 + { 1.123 + mSensorData.sensor() = HardwareSensorToHalSensor(data.type); 1.124 + mSensorData.accuracy() = HardwareStatusToHalAccuracy(SensorseventStatus(data)); 1.125 + mSensorData.timestamp() = data.timestamp; 1.126 + if (mSensorData.sensor() == SENSOR_GYROSCOPE) { 1.127 + // libhardware returns gyro as rad. convert. 1.128 + mSensorValues.AppendElement(radToDeg(data.data[0])); 1.129 + mSensorValues.AppendElement(radToDeg(data.data[1])); 1.130 + mSensorValues.AppendElement(radToDeg(data.data[2])); 1.131 + } else if (mSensorData.sensor() == SENSOR_PROXIMITY) { 1.132 + mSensorValues.AppendElement(data.data[0]); 1.133 + mSensorValues.AppendElement(0); 1.134 + 1.135 + // Determine the maxRange for this sensor. 1.136 + for (ssize_t i = 0; i < size; i++) { 1.137 + if (sensors[i].type == SENSOR_TYPE_PROXIMITY) { 1.138 + mSensorValues.AppendElement(sensors[i].maxRange); 1.139 + } 1.140 + } 1.141 + } else if (mSensorData.sensor() == SENSOR_LIGHT) { 1.142 + mSensorValues.AppendElement(data.data[0]); 1.143 + } else { 1.144 + mSensorValues.AppendElement(data.data[0]); 1.145 + mSensorValues.AppendElement(data.data[1]); 1.146 + mSensorValues.AppendElement(data.data[2]); 1.147 + } 1.148 + mSensorData.values() = mSensorValues; 1.149 + } 1.150 + 1.151 + ~SensorRunnable() {} 1.152 + 1.153 + NS_IMETHOD Run() 1.154 + { 1.155 + NotifySensorChange(mSensorData); 1.156 + return NS_OK; 1.157 + } 1.158 + 1.159 +private: 1.160 + SensorData mSensorData; 1.161 + InfallibleTArray<float> mSensorValues; 1.162 +}; 1.163 + 1.164 +namespace hal_impl { 1.165 + 1.166 +static DebugOnly<int> sSensorRefCount[NUM_SENSOR_TYPE]; 1.167 +static base::Thread* sPollingThread; 1.168 +static sensors_poll_device_t* sSensorDevice; 1.169 +static sensors_module_t* sSensorModule; 1.170 + 1.171 +static void 1.172 +PollSensors() 1.173 +{ 1.174 + const size_t numEventMax = 16; 1.175 + sensors_event_t buffer[numEventMax]; 1.176 + const sensor_t* sensors; 1.177 + int size = sSensorModule->get_sensors_list(sSensorModule, &sensors); 1.178 + 1.179 + do { 1.180 + // didn't check sSensorDevice because already be done on creating pollingThread. 1.181 + int n = sSensorDevice->poll(sSensorDevice, buffer, numEventMax); 1.182 + if (n < 0) { 1.183 + LOGE("Error polling for sensor data (err=%d)", n); 1.184 + break; 1.185 + } 1.186 + 1.187 + for (int i = 0; i < n; ++i) { 1.188 + // FIXME: bug 802004, add proper support for the magnetic field sensor. 1.189 + if (buffer[i].type == SENSOR_TYPE_MAGNETIC_FIELD) 1.190 + continue; 1.191 + 1.192 + // Bug 938035, transfer HAL data for orientation sensor to meet w3c spec 1.193 + // ex: HAL report alpha=90 means East but alpha=90 means West in w3c spec 1.194 + if (buffer[i].type == SENSOR_TYPE_ORIENTATION) { 1.195 + buffer[i].orientation.azimuth = 360 - buffer[i].orientation.azimuth; 1.196 + buffer[i].orientation.pitch = -buffer[i].orientation.pitch; 1.197 + buffer[i].orientation.roll = -buffer[i].orientation.roll; 1.198 + } 1.199 + 1.200 + if (HardwareSensorToHalSensor(buffer[i].type) == SENSOR_UNKNOWN) { 1.201 + // Emulator is broken and gives us events without types set 1.202 + int index; 1.203 + for (index = 0; index < size; index++) { 1.204 + if (sensors[index].handle == buffer[i].sensor) { 1.205 + break; 1.206 + } 1.207 + } 1.208 + if (index < size && 1.209 + HardwareSensorToHalSensor(sensors[index].type) != SENSOR_UNKNOWN) { 1.210 + buffer[i].type = sensors[index].type; 1.211 + } else { 1.212 + LOGW("Could not determine sensor type of event"); 1.213 + continue; 1.214 + } 1.215 + } 1.216 + 1.217 + NS_DispatchToMainThread(new SensorRunnable(buffer[i], sensors, size)); 1.218 + } 1.219 + } while (true); 1.220 +} 1.221 + 1.222 +static void 1.223 +SwitchSensor(bool aActivate, sensor_t aSensor, pthread_t aThreadId) 1.224 +{ 1.225 + int index = HardwareSensorToHalSensor(aSensor.type); 1.226 + 1.227 + MOZ_ASSERT(sSensorRefCount[index] || aActivate); 1.228 + 1.229 + sSensorDevice->activate(sSensorDevice, aSensor.handle, aActivate); 1.230 + 1.231 + if (aActivate) { 1.232 + if (aSensor.type == SENSOR_TYPE_ACCELEROMETER) { 1.233 + sSensorDevice->setDelay(sSensorDevice, aSensor.handle, 1.234 + ACCELEROMETER_POLL_RATE); 1.235 + } else { 1.236 + sSensorDevice->setDelay(sSensorDevice, aSensor.handle, 1.237 + DEFAULT_DEVICE_POLL_RATE); 1.238 + } 1.239 + } 1.240 + 1.241 + if (aActivate) { 1.242 + sSensorRefCount[index]++; 1.243 + } else { 1.244 + sSensorRefCount[index]--; 1.245 + } 1.246 +} 1.247 + 1.248 +static void 1.249 +SetSensorState(SensorType aSensor, bool activate) 1.250 +{ 1.251 + int type = HalSensorToHardwareSensor(aSensor); 1.252 + const sensor_t* sensors = nullptr; 1.253 + 1.254 + int size = sSensorModule->get_sensors_list(sSensorModule, &sensors); 1.255 + for (ssize_t i = 0; i < size; i++) { 1.256 + if (sensors[i].type == type) { 1.257 + SwitchSensor(activate, sensors[i], pthread_self()); 1.258 + break; 1.259 + } 1.260 + } 1.261 +} 1.262 + 1.263 +void 1.264 +EnableSensorNotifications(SensorType aSensor) 1.265 +{ 1.266 + if (!sSensorModule) { 1.267 + hw_get_module(SENSORS_HARDWARE_MODULE_ID, 1.268 + (hw_module_t const**)&sSensorModule); 1.269 + if (!sSensorModule) { 1.270 + LOGE("Can't get sensor HAL module\n"); 1.271 + return; 1.272 + } 1.273 + 1.274 + sensors_open(&sSensorModule->common, &sSensorDevice); 1.275 + if (!sSensorDevice) { 1.276 + sSensorModule = nullptr; 1.277 + LOGE("Can't get sensor poll device from module \n"); 1.278 + return; 1.279 + } 1.280 + 1.281 + sensor_t const* sensors; 1.282 + int count = sSensorModule->get_sensors_list(sSensorModule, &sensors); 1.283 + for (size_t i=0 ; i<size_t(count) ; i++) { 1.284 + sSensorDevice->activate(sSensorDevice, sensors[i].handle, 0); 1.285 + } 1.286 + } 1.287 + 1.288 + if (!sPollingThread) { 1.289 + sPollingThread = new base::Thread("GonkSensors"); 1.290 + MOZ_ASSERT(sPollingThread); 1.291 + // sPollingThread never terminates because poll may never return 1.292 + sPollingThread->Start(); 1.293 + sPollingThread->message_loop()->PostTask(FROM_HERE, 1.294 + NewRunnableFunction(PollSensors)); 1.295 + } 1.296 + 1.297 + SetSensorState(aSensor, true); 1.298 +} 1.299 + 1.300 +void 1.301 +DisableSensorNotifications(SensorType aSensor) 1.302 +{ 1.303 + if (!sSensorModule) { 1.304 + return; 1.305 + } 1.306 + SetSensorState(aSensor, false); 1.307 +} 1.308 + 1.309 +} // hal_impl 1.310 +} // mozilla