hal/gonk/GonkSensor.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* Copyright 2012 Mozilla Foundation and Mozilla contributors
     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  */
    17 #include <pthread.h>
    18 #include <stdio.h>
    20 #include "mozilla/DebugOnly.h"
    22 #include "base/basictypes.h"
    23 #include "base/thread.h"
    25 #include "Hal.h"
    26 #include "HalSensor.h"
    27 #include "hardware/sensors.h"
    28 #include "nsThreadUtils.h"
    30 #undef LOG
    32 #include <android/log.h>
    34 using namespace mozilla::hal;
    36 #define LOGE(args...)  __android_log_print(ANDROID_LOG_ERROR, "GonkSensor" , ## args)
    37 #define LOGW(args...)  __android_log_print(ANDROID_LOG_WARN, "GonkSensor" , ## args)
    39 namespace mozilla {
    41 // The value from SensorDevice.h (Android)
    42 #define DEFAULT_DEVICE_POLL_RATE 200000000 /*200ms*/
    43 // ProcessOrientation.cpp needs smaller poll rate to detect delay between
    44 // different orientation angles
    45 #define ACCELEROMETER_POLL_RATE 66667000 /*66.667ms*/
    47 double radToDeg(double a) {
    48   return a * (180.0 / M_PI);
    49 }
    51 static SensorType
    52 HardwareSensorToHalSensor(int type)
    53 {
    54   switch(type) {
    55     case SENSOR_TYPE_ORIENTATION:
    56       return SENSOR_ORIENTATION;
    57     case SENSOR_TYPE_ACCELEROMETER:
    58       return SENSOR_ACCELERATION;
    59     case SENSOR_TYPE_PROXIMITY:
    60       return SENSOR_PROXIMITY;
    61     case SENSOR_TYPE_LIGHT:
    62       return SENSOR_LIGHT;
    63     case SENSOR_TYPE_GYROSCOPE:
    64       return SENSOR_GYROSCOPE;
    65     case SENSOR_TYPE_LINEAR_ACCELERATION:
    66       return SENSOR_LINEAR_ACCELERATION;
    67     default:
    68       return SENSOR_UNKNOWN;
    69   }
    70 }
    72 static SensorAccuracyType
    73 HardwareStatusToHalAccuracy(int status) {
    74   return static_cast<SensorAccuracyType>(status);
    75 }
    77 static int
    78 HalSensorToHardwareSensor(SensorType type)
    79 {
    80   switch(type) {
    81     case SENSOR_ORIENTATION:
    82       return SENSOR_TYPE_ORIENTATION;
    83     case SENSOR_ACCELERATION:
    84       return SENSOR_TYPE_ACCELEROMETER;
    85     case SENSOR_PROXIMITY:
    86       return SENSOR_TYPE_PROXIMITY;
    87     case SENSOR_LIGHT:
    88       return SENSOR_TYPE_LIGHT;
    89     case SENSOR_GYROSCOPE:
    90       return SENSOR_TYPE_GYROSCOPE;
    91     case SENSOR_LINEAR_ACCELERATION:
    92       return SENSOR_TYPE_LINEAR_ACCELERATION;
    93     default:
    94       return -1;
    95   }
    96 }
    98 static int
    99 SensorseventStatus(const sensors_event_t& data)
   100 {
   101   int type = data.type;
   102   switch(type) {
   103     case SENSOR_ORIENTATION:
   104       return data.orientation.status;
   105     case SENSOR_LINEAR_ACCELERATION:
   106     case SENSOR_ACCELERATION:
   107       return data.acceleration.status;
   108     case SENSOR_GYROSCOPE:
   109       return data.gyro.status;
   110   }
   112   return SENSOR_STATUS_UNRELIABLE;
   113 }
   115 class SensorRunnable : public nsRunnable
   116 {
   117 public:
   118   SensorRunnable(const sensors_event_t& data, const sensor_t* sensors, ssize_t size)
   119   {
   120     mSensorData.sensor() = HardwareSensorToHalSensor(data.type);
   121     mSensorData.accuracy() = HardwareStatusToHalAccuracy(SensorseventStatus(data));
   122     mSensorData.timestamp() = data.timestamp;
   123     if (mSensorData.sensor() == SENSOR_GYROSCOPE) {
   124       // libhardware returns gyro as rad.  convert.
   125       mSensorValues.AppendElement(radToDeg(data.data[0]));
   126       mSensorValues.AppendElement(radToDeg(data.data[1]));
   127       mSensorValues.AppendElement(radToDeg(data.data[2]));
   128     } else if (mSensorData.sensor() == SENSOR_PROXIMITY) {
   129       mSensorValues.AppendElement(data.data[0]);
   130       mSensorValues.AppendElement(0);
   132       // Determine the maxRange for this sensor.
   133       for (ssize_t i = 0; i < size; i++) {
   134         if (sensors[i].type == SENSOR_TYPE_PROXIMITY) {
   135           mSensorValues.AppendElement(sensors[i].maxRange);
   136         }
   137       }
   138     } else if (mSensorData.sensor() == SENSOR_LIGHT) {
   139       mSensorValues.AppendElement(data.data[0]);
   140     } else {
   141       mSensorValues.AppendElement(data.data[0]);
   142       mSensorValues.AppendElement(data.data[1]);
   143       mSensorValues.AppendElement(data.data[2]);
   144     }
   145     mSensorData.values() = mSensorValues;
   146   }
   148   ~SensorRunnable() {}
   150   NS_IMETHOD Run()
   151   {
   152     NotifySensorChange(mSensorData);
   153     return NS_OK;
   154   }
   156 private:
   157   SensorData mSensorData;
   158   InfallibleTArray<float> mSensorValues;
   159 };
   161 namespace hal_impl {
   163 static DebugOnly<int> sSensorRefCount[NUM_SENSOR_TYPE];
   164 static base::Thread* sPollingThread;
   165 static sensors_poll_device_t* sSensorDevice;
   166 static sensors_module_t* sSensorModule;
   168 static void
   169 PollSensors()
   170 {
   171   const size_t numEventMax = 16;
   172   sensors_event_t buffer[numEventMax];
   173   const sensor_t* sensors;
   174   int size = sSensorModule->get_sensors_list(sSensorModule, &sensors);
   176   do {
   177     // didn't check sSensorDevice because already be done on creating pollingThread.
   178     int n = sSensorDevice->poll(sSensorDevice, buffer, numEventMax);
   179     if (n < 0) {
   180       LOGE("Error polling for sensor data (err=%d)", n);
   181       break;
   182     }
   184     for (int i = 0; i < n; ++i) {
   185       // FIXME: bug 802004, add proper support for the magnetic field sensor.
   186       if (buffer[i].type == SENSOR_TYPE_MAGNETIC_FIELD)
   187         continue;
   189       // Bug 938035, transfer HAL data for orientation sensor to meet w3c spec
   190       // ex: HAL report alpha=90 means East but alpha=90 means West in w3c spec
   191       if (buffer[i].type == SENSOR_TYPE_ORIENTATION) {
   192         buffer[i].orientation.azimuth = 360 - buffer[i].orientation.azimuth;
   193         buffer[i].orientation.pitch = -buffer[i].orientation.pitch;
   194         buffer[i].orientation.roll = -buffer[i].orientation.roll;
   195       }
   197       if (HardwareSensorToHalSensor(buffer[i].type) == SENSOR_UNKNOWN) {
   198         // Emulator is broken and gives us events without types set
   199         int index;
   200         for (index = 0; index < size; index++) {
   201           if (sensors[index].handle == buffer[i].sensor) {
   202             break;
   203           }
   204         }
   205         if (index < size &&
   206             HardwareSensorToHalSensor(sensors[index].type) != SENSOR_UNKNOWN) {
   207           buffer[i].type = sensors[index].type;
   208         } else {
   209           LOGW("Could not determine sensor type of event");
   210           continue;
   211         }
   212       }
   214       NS_DispatchToMainThread(new SensorRunnable(buffer[i], sensors, size));
   215     }
   216   } while (true);
   217 }
   219 static void
   220 SwitchSensor(bool aActivate, sensor_t aSensor, pthread_t aThreadId)
   221 {
   222   int index = HardwareSensorToHalSensor(aSensor.type);
   224   MOZ_ASSERT(sSensorRefCount[index] || aActivate);
   226   sSensorDevice->activate(sSensorDevice, aSensor.handle, aActivate);
   228   if (aActivate) {
   229     if (aSensor.type == SENSOR_TYPE_ACCELEROMETER) {
   230       sSensorDevice->setDelay(sSensorDevice, aSensor.handle,
   231                    ACCELEROMETER_POLL_RATE);
   232     } else {
   233       sSensorDevice->setDelay(sSensorDevice, aSensor.handle,
   234                    DEFAULT_DEVICE_POLL_RATE);
   235     }
   236   }
   238   if (aActivate) {
   239     sSensorRefCount[index]++;
   240   } else {
   241     sSensorRefCount[index]--;
   242   }
   243 }
   245 static void
   246 SetSensorState(SensorType aSensor, bool activate)
   247 {
   248   int type = HalSensorToHardwareSensor(aSensor);
   249   const sensor_t* sensors = nullptr;
   251   int size = sSensorModule->get_sensors_list(sSensorModule, &sensors);
   252   for (ssize_t i = 0; i < size; i++) {
   253     if (sensors[i].type == type) {
   254       SwitchSensor(activate, sensors[i], pthread_self());
   255       break;
   256     }
   257   }
   258 }
   260 void
   261 EnableSensorNotifications(SensorType aSensor)
   262 {
   263   if (!sSensorModule) {
   264     hw_get_module(SENSORS_HARDWARE_MODULE_ID,
   265                        (hw_module_t const**)&sSensorModule);
   266     if (!sSensorModule) {
   267       LOGE("Can't get sensor HAL module\n");
   268       return;
   269     }
   271     sensors_open(&sSensorModule->common, &sSensorDevice);
   272     if (!sSensorDevice) {
   273       sSensorModule = nullptr;
   274       LOGE("Can't get sensor poll device from module \n");
   275       return;
   276     }
   278     sensor_t const* sensors;
   279     int count = sSensorModule->get_sensors_list(sSensorModule, &sensors);
   280     for (size_t i=0 ; i<size_t(count) ; i++) {
   281       sSensorDevice->activate(sSensorDevice, sensors[i].handle, 0);
   282     }
   283   }
   285   if (!sPollingThread) {
   286     sPollingThread = new base::Thread("GonkSensors");
   287     MOZ_ASSERT(sPollingThread);
   288     // sPollingThread never terminates because poll may never return
   289     sPollingThread->Start();
   290     sPollingThread->message_loop()->PostTask(FROM_HERE,
   291                                      NewRunnableFunction(PollSensors));
   292   }
   294   SetSensorState(aSensor, true);
   295 }
   297 void
   298 DisableSensorNotifications(SensorType aSensor)
   299 {
   300   if (!sSensorModule) {
   301     return;
   302   }
   303   SetSensorState(aSensor, false);
   304 }
   306 } // hal_impl
   307 } // mozilla

mercurial