Tue, 06 Jan 2015 21:39:09 +0100
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 |