hal/gonk/GonkSensor.cpp

changeset 0
6474c204b198
     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

mercurial