hal/gonk/GonkSensor.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial