hal/cocoa/CocoaSensor.mm

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.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 #include "Hal.h"
     5 #include "nsITimer.h"
     6 #include "smslib.h"
     7 #include "nsComponentManagerUtils.h"
     9 #include <mach/mach.h>
    10 #include <cmath>
    11 #import <IOKit/IOKitLib.h>
    13 #define MEAN_GRAVITY 9.80665
    14 #define DEFAULT_SENSOR_POLL 100
    15 using namespace mozilla::hal;
    16 namespace mozilla {
    17 namespace hal_impl {
    18 static nsITimer* sUpdateTimer = nullptr;
    19 static bool sActiveSensors[NUM_SENSOR_TYPE];
    20 static io_connect_t sDataPort = IO_OBJECT_NULL;
    21 static uint64_t sLastMean = -1;
    22 static float
    23 LMUvalueToLux(uint64_t aValue)
    24 {
    25   //Conversion formula from regression. See Bug 793728.
    26   // -3*(10^-27)*x^4 + 2.6*(10^-19)*x^3 + -3.4*(10^-12)*x^2 + 3.9*(10^-5)*x - 0.19
    27   long double powerC4 = 1/pow((long double)10,27);
    28   long double powerC3 = 1/pow((long double)10,19);
    29   long double powerC2 = 1/pow((long double)10,12);
    30   long double powerC1 = 1/pow((long double)10,5);
    32   long double term4 = -3.0 * powerC4 * pow(aValue,4);
    33   long double term3 =  2.6 * powerC3 * pow(aValue,3);
    34   long double term2 = -3.4 * powerC2 * pow(aValue,2);
    35   long double term1 =  3.9 * powerC1 * aValue;
    37   float lux = ceil(static_cast<float>(term4 + term3 + term2 + term1 - 0.19));
    38   return lux > 0 ? lux : 0;
    39 }
    40 void
    41 UpdateHandler(nsITimer *aTimer, void *aClosure)
    42 {
    43   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
    44     if (!sActiveSensors[i]) {
    45       continue;
    46     }
    47     SensorType sensor = static_cast<SensorType>(i);
    48     InfallibleTArray<float> values;
    49     if (sensor == SENSOR_ACCELERATION) {
    50       sms_acceleration accel;
    51       smsGetData(&accel);
    53       values.AppendElement(accel.x * MEAN_GRAVITY);
    54       values.AppendElement(accel.y * MEAN_GRAVITY);
    55       values.AppendElement(accel.z * MEAN_GRAVITY);
    56     } else if (sensor == SENSOR_LIGHT && sDataPort != IO_OBJECT_NULL) {
    57       kern_return_t kr;
    58       uint32_t outputs = 2;
    59       uint64_t lightLMU[outputs];
    61       kr = IOConnectCallMethod(sDataPort, 0, nil, 0, nil, 0, lightLMU, &outputs, nil, 0);
    62       if (kr == KERN_SUCCESS) {
    63         uint64_t mean = (lightLMU[0] + lightLMU[1]) / 2;
    64         if (mean == sLastMean) {
    65           continue;
    66         }
    67         sLastMean = mean;
    68         values.AppendElement(LMUvalueToLux(mean));
    69       } else if (kr == kIOReturnBusy) {
    70         continue;
    71       }
    72     }
    74     hal::SensorData sdata(sensor,
    75                           PR_Now(),
    76                           values,
    77                           hal::SENSOR_ACCURACY_UNKNOWN);
    78     hal::NotifySensorChange(sdata);
    79   }
    80 }
    81 void
    82 EnableSensorNotifications(SensorType aSensor)
    83 {
    84   if (aSensor == SENSOR_ACCELERATION) {
    85     int result = smsStartup(nil, nil);
    87     if (result != SMS_SUCCESS) {
    88       return;
    89     }
    91     if (!smsLoadCalibration()) {
    92       return;
    93     }
    94   } else if (aSensor == SENSOR_LIGHT) {
    95     io_service_t serviceObject;
    96     serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault,
    97                                                 IOServiceMatching("AppleLMUController"));
    98     if (!serviceObject) {
    99       return;
   100     }
   101     kern_return_t kr;
   102     kr = IOServiceOpen(serviceObject, mach_task_self(), 0, &sDataPort);
   103     IOObjectRelease(serviceObject);
   104     if (kr != KERN_SUCCESS) {
   105       return;
   106     }
   107   } else {
   108     NS_WARNING("EnableSensorNotifications called on an unknown sensor type");
   109     return;
   110   }
   111   sActiveSensors[aSensor] = true;
   113   if (!sUpdateTimer) {
   114     CallCreateInstance("@mozilla.org/timer;1", &sUpdateTimer);
   115     if (sUpdateTimer) {
   116         sUpdateTimer->InitWithFuncCallback(UpdateHandler,
   117                                            nullptr,
   118                                            DEFAULT_SENSOR_POLL,
   119                                            nsITimer::TYPE_REPEATING_SLACK);
   120     }
   121   }
   122 }
   123 void
   124 DisableSensorNotifications(SensorType aSensor)
   125 {
   126   if (!sActiveSensors[aSensor] || (aSensor != SENSOR_ACCELERATION && aSensor != SENSOR_LIGHT)) {
   127     return;
   128   }
   130   sActiveSensors[aSensor] = false;
   132   if (aSensor == SENSOR_ACCELERATION) {
   133     smsShutdown();
   134   } else if (aSensor == SENSOR_LIGHT) {
   135     IOServiceClose(sDataPort);
   136   }
   137   // If all sensors are disabled, cancel the update timer.
   138   if (sUpdateTimer) {
   139     for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
   140       if (sActiveSensors[i]) {
   141         return;
   142       }
   143     }
   144     sUpdateTimer->Cancel();
   145     NS_RELEASE(sUpdateTimer);
   146   }
   147 }
   148 } // hal_impl
   149 } // mozilla

mercurial