Home | History | Annotate | Download | only in sensorhal
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      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  */
     16 
     17 #include "hubconnection.h"
     18 #include "eventnums.h"
     19 #include "sensType.h"
     20 
     21 #define LOG_TAG "nanohub"
     22 #include <utils/Log.h>
     23 #include <utils/SystemClock.h>
     24 
     25 #include "file.h"
     26 #include "JSONObject.h"
     27 
     28 #include <errno.h>
     29 #include <unistd.h>
     30 #include <math.h>
     31 #include <inttypes.h>
     32 
     33 #include <cutils/properties.h>
     34 #include <linux/input.h>
     35 #include <linux/uinput.h>
     36 #include <media/stagefright/foundation/ADebug.h>
     37 #include <sched.h>
     38 #include <sys/inotify.h>
     39 
     40 #define APP_ID_GET_VENDOR(appid)       ((appid) >> 24)
     41 #define APP_ID_MAKE(vendor, app)       ((((uint64_t)(vendor)) << 24) | ((app) & 0x00FFFFFF))
     42 #define APP_ID_VENDOR_GOOGLE           0x476f6f676cULL // "Googl"
     43 #define APP_ID_APP_BMI160              2
     44 
     45 #define SENS_TYPE_TO_EVENT(_sensorType) (EVT_NO_FIRST_SENSOR_EVENT + (_sensorType))
     46 
     47 #define NANOHUB_FILE_PATH       "/dev/nanohub"
     48 #define NANOHUB_LOCK_DIR        "/data/system/nanohub_lock"
     49 #define NANOHUB_LOCK_FILE       NANOHUB_LOCK_DIR "/lock"
     50 #define MAG_BIAS_FILE_PATH      "/sys/class/power_supply/battery/compass_compensation"
     51 #define DOUBLE_TOUCH_FILE_PATH  "/sys/android_touch/synaptics_rmi4_dsx/wake_event"
     52 
     53 #define NANOHUB_LOCK_DIR_PERMS  (S_IRUSR | S_IWUSR | S_IXUSR)
     54 
     55 #define SENSOR_RATE_ONCHANGE    0xFFFFFF01UL
     56 #define SENSOR_RATE_ONESHOT     0xFFFFFF02UL
     57 
     58 #define MIN_MAG_SQ              (10.0f * 10.0f)
     59 #define MAX_MAG_SQ              (80.0f * 80.0f)
     60 
     61 #define ACCEL_RAW_KSCALE        (8.0f * 9.81f / 32768.0f)
     62 
     63 #define OS_LOG_EVENT            0x474F4C41  // ascii: ALOG
     64 
     65 #define HUBCONNECTION_SCHED_FIFO_PRIORITY 10
     66 
     67 #ifdef LID_STATE_REPORTING_ENABLED
     68 const char LID_STATE_PROPERTY[] = "sensors.contexthub.lid_state";
     69 const char LID_STATE_UNKNOWN[]  = "unknown";
     70 const char LID_STATE_OPEN[]     = "open";
     71 const char LID_STATE_CLOSED[]   = "closed";
     72 #endif  // LID_STATE_REPORTING_ENABLED
     73 
     74 static const uint32_t delta_time_encoded = 1;
     75 static const uint32_t delta_time_shift_table[2] = {9, 0};
     76 
     77 namespace android {
     78 
     79 // static
     80 Mutex HubConnection::sInstanceLock;
     81 
     82 // static
     83 HubConnection *HubConnection::sInstance = NULL;
     84 
     85 HubConnection *HubConnection::getInstance()
     86 {
     87     Mutex::Autolock autoLock(sInstanceLock);
     88     if (sInstance == NULL) {
     89         sInstance = new HubConnection;
     90     }
     91     return sInstance;
     92 }
     93 
     94 HubConnection::HubConnection()
     95     : Thread(false /* canCallJava */),
     96       mRing(10 *1024),
     97       mActivityEventHandler(NULL),
     98       mStepCounterOffset(0ull),
     99       mLastStepCount(0ull)
    100 {
    101     mMagBias[0] = mMagBias[1] = mMagBias[2] = 0.0f;
    102     mMagAccuracy = SENSOR_STATUS_UNRELIABLE;
    103     mMagAccuracyRestore = SENSOR_STATUS_UNRELIABLE;
    104     mGyroBias[0] = mGyroBias[1] = mGyroBias[2] = 0.0f;
    105     mAccelBias[0] = mAccelBias[1] = mAccelBias[2] = 0.0f;
    106 
    107     memset(&mSensorState, 0x00, sizeof(mSensorState));
    108     mFd = open(NANOHUB_FILE_PATH, O_RDWR);
    109     mPollFds[0].fd = mFd;
    110     mPollFds[0].events = POLLIN;
    111     mPollFds[0].revents = 0;
    112     mNumPollFds = 1;
    113 
    114     initNanohubLock();
    115 
    116 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
    117     mUsbMagBias = 0;
    118     mMagBiasPollIndex = -1;
    119     int magBiasFd = open(MAG_BIAS_FILE_PATH, O_RDONLY);
    120     if (magBiasFd < 0) {
    121         ALOGW("Mag bias file open failed: %s", strerror(errno));
    122     } else {
    123         mPollFds[mNumPollFds].fd = magBiasFd;
    124         mPollFds[mNumPollFds].events = 0;
    125         mPollFds[mNumPollFds].revents = 0;
    126         mMagBiasPollIndex = mNumPollFds;
    127         mNumPollFds++;
    128     }
    129 #endif  // USB_MAG_BIAS_REPORTING_ENABLED
    130 
    131 #ifdef DOUBLE_TOUCH_ENABLED
    132     mDoubleTouchPollIndex = -1;
    133     int doubleTouchFd = open(DOUBLE_TOUCH_FILE_PATH, O_RDONLY);
    134     if (doubleTouchFd < 0) {
    135         ALOGW("Double touch file open failed: %s", strerror(errno));
    136     } else {
    137         mPollFds[mNumPollFds].fd = doubleTouchFd;
    138         mPollFds[mNumPollFds].events = 0;
    139         mPollFds[mNumPollFds].revents = 0;
    140         mDoubleTouchPollIndex = mNumPollFds;
    141         mNumPollFds++;
    142     }
    143 #endif  // DOUBLE_TOUCH_ENABLED
    144 
    145     mSensorState[COMMS_SENSOR_ACCEL].sensorType = SENS_TYPE_ACCEL;
    146     mSensorState[COMMS_SENSOR_GYRO].sensorType = SENS_TYPE_GYRO;
    147     mSensorState[COMMS_SENSOR_GYRO].alt = COMMS_SENSOR_GYRO_UNCALIBRATED;
    148     mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].sensorType = SENS_TYPE_GYRO;
    149     mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].alt = COMMS_SENSOR_GYRO;
    150     mSensorState[COMMS_SENSOR_MAG].sensorType = SENS_TYPE_MAG;
    151     mSensorState[COMMS_SENSOR_MAG].alt = COMMS_SENSOR_MAG_UNCALIBRATED;
    152     mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].sensorType = SENS_TYPE_MAG;
    153     mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].alt = COMMS_SENSOR_MAG;
    154     mSensorState[COMMS_SENSOR_LIGHT].sensorType = SENS_TYPE_ALS;
    155     mSensorState[COMMS_SENSOR_PROXIMITY].sensorType = SENS_TYPE_PROX;
    156     mSensorState[COMMS_SENSOR_PRESSURE].sensorType = SENS_TYPE_BARO;
    157     mSensorState[COMMS_SENSOR_TEMPERATURE].sensorType = SENS_TYPE_TEMP;
    158     mSensorState[COMMS_SENSOR_ORIENTATION].sensorType = SENS_TYPE_ORIENTATION;
    159     mSensorState[COMMS_SENSOR_WINDOW_ORIENTATION].sensorType = SENS_TYPE_WIN_ORIENTATION;
    160     mSensorState[COMMS_SENSOR_WINDOW_ORIENTATION].rate = SENSOR_RATE_ONCHANGE;
    161     mSensorState[COMMS_SENSOR_STEP_DETECTOR].sensorType = SENS_TYPE_STEP_DETECT;
    162     mSensorState[COMMS_SENSOR_STEP_DETECTOR].rate = SENSOR_RATE_ONCHANGE;
    163     mSensorState[COMMS_SENSOR_STEP_COUNTER].sensorType = SENS_TYPE_STEP_COUNT;
    164     mSensorState[COMMS_SENSOR_SIGNIFICANT_MOTION].sensorType = SENS_TYPE_SIG_MOTION;
    165     mSensorState[COMMS_SENSOR_SIGNIFICANT_MOTION].rate = SENSOR_RATE_ONESHOT;
    166     mSensorState[COMMS_SENSOR_GRAVITY].sensorType = SENS_TYPE_GRAVITY;
    167     mSensorState[COMMS_SENSOR_LINEAR_ACCEL].sensorType = SENS_TYPE_LINEAR_ACCEL;
    168     mSensorState[COMMS_SENSOR_ROTATION_VECTOR].sensorType = SENS_TYPE_ROTATION_VECTOR;
    169     mSensorState[COMMS_SENSOR_GEO_MAG].sensorType = SENS_TYPE_GEO_MAG_ROT_VEC;
    170     mSensorState[COMMS_SENSOR_GAME_ROTATION_VECTOR].sensorType = SENS_TYPE_GAME_ROT_VECTOR;
    171     mSensorState[COMMS_SENSOR_HALL].sensorType = SENS_TYPE_HALL;
    172     mSensorState[COMMS_SENSOR_HALL].rate = SENSOR_RATE_ONCHANGE;
    173     mSensorState[COMMS_SENSOR_SYNC].sensorType = SENS_TYPE_VSYNC;
    174     mSensorState[COMMS_SENSOR_SYNC].rate = SENSOR_RATE_ONCHANGE;
    175     mSensorState[COMMS_SENSOR_ACTIVITY].sensorType = SENS_TYPE_ACTIVITY;
    176     mSensorState[COMMS_SENSOR_ACTIVITY].rate = SENSOR_RATE_ONCHANGE;
    177     mSensorState[COMMS_SENSOR_TILT].sensorType = SENS_TYPE_TILT;
    178     mSensorState[COMMS_SENSOR_TILT].rate = SENSOR_RATE_ONCHANGE;
    179     mSensorState[COMMS_SENSOR_GESTURE].sensorType = SENS_TYPE_GESTURE;
    180     mSensorState[COMMS_SENSOR_GESTURE].rate = SENSOR_RATE_ONESHOT;
    181     mSensorState[COMMS_SENSOR_DOUBLE_TWIST].sensorType = SENS_TYPE_DOUBLE_TWIST;
    182     mSensorState[COMMS_SENSOR_DOUBLE_TWIST].rate = SENSOR_RATE_ONCHANGE;
    183     mSensorState[COMMS_SENSOR_DOUBLE_TAP].sensorType = SENS_TYPE_DOUBLE_TAP;
    184     mSensorState[COMMS_SENSOR_DOUBLE_TAP].rate = SENSOR_RATE_ONCHANGE;
    185     mSensorState[COMMS_SENSOR_WRIST_TILT].sensorType = SENS_TYPE_WRIST_TILT;
    186     mSensorState[COMMS_SENSOR_WRIST_TILT].rate = SENSOR_RATE_ONCHANGE;
    187     mSensorState[COMMS_SENSOR_DOUBLE_TOUCH].sensorType = SENS_TYPE_DOUBLE_TOUCH;
    188     mSensorState[COMMS_SENSOR_DOUBLE_TOUCH].rate = SENSOR_RATE_ONESHOT;
    189     mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_START].sensorType = SENS_TYPE_ACTIVITY_IN_VEHICLE_START;
    190     mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_START].rate = SENSOR_RATE_ONCHANGE;
    191     mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_STOP].sensorType = SENS_TYPE_ACTIVITY_IN_VEHICLE_STOP;
    192     mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_STOP].rate = SENSOR_RATE_ONCHANGE;
    193     mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_START].sensorType = SENS_TYPE_ACTIVITY_ON_BICYCLE_START;
    194     mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_START].rate = SENSOR_RATE_ONCHANGE;
    195     mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_STOP].sensorType = SENS_TYPE_ACTIVITY_ON_BICYCLE_STOP;
    196     mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_STOP].rate = SENSOR_RATE_ONCHANGE;
    197     mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_START].sensorType = SENS_TYPE_ACTIVITY_WALKING_START;
    198     mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_START].rate = SENSOR_RATE_ONCHANGE;
    199     mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_STOP].sensorType = SENS_TYPE_ACTIVITY_WALKING_STOP;
    200     mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_STOP].rate = SENSOR_RATE_ONCHANGE;
    201     mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_START].sensorType = SENS_TYPE_ACTIVITY_RUNNING_START;
    202     mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_START].rate = SENSOR_RATE_ONCHANGE;
    203     mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_STOP].sensorType = SENS_TYPE_ACTIVITY_RUNNING_STOP;
    204     mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_STOP].rate = SENSOR_RATE_ONCHANGE;
    205     mSensorState[COMMS_SENSOR_ACTIVITY_STILL_START].sensorType = SENS_TYPE_ACTIVITY_STILL_START;
    206     mSensorState[COMMS_SENSOR_ACTIVITY_STILL_START].rate = SENSOR_RATE_ONCHANGE;
    207     mSensorState[COMMS_SENSOR_ACTIVITY_STILL_STOP].sensorType = SENS_TYPE_ACTIVITY_STILL_STOP;
    208     mSensorState[COMMS_SENSOR_ACTIVITY_STILL_STOP].rate = SENSOR_RATE_ONCHANGE;
    209     mSensorState[COMMS_SENSOR_ACTIVITY_TILTING].sensorType = SENS_TYPE_ACTIVITY_TILTING;
    210     mSensorState[COMMS_SENSOR_ACTIVITY_TILTING].rate = SENSOR_RATE_ONCHANGE;
    211 
    212 #ifdef LID_STATE_REPORTING_ENABLED
    213     initializeUinputNode();
    214 
    215     // set initial lid state
    216     if (property_set(LID_STATE_PROPERTY, LID_STATE_UNKNOWN) < 0) {
    217         ALOGE("could not set lid_state property");
    218     }
    219 
    220     // enable hall sensor for folio
    221     if (mFd >= 0) {
    222         queueActivate(COMMS_SENSOR_HALL, true /* enable */);
    223     }
    224 #endif  // LID_STATE_REPORTING_ENABLED
    225 }
    226 
    227 HubConnection::~HubConnection()
    228 {
    229     close(mFd);
    230 }
    231 
    232 void HubConnection::onFirstRef()
    233 {
    234     run("HubConnection", PRIORITY_URGENT_DISPLAY);
    235     enableSchedFifoMode();
    236 }
    237 
    238 // Set main thread to SCHED_FIFO to lower sensor event latency when system is under load
    239 void HubConnection::enableSchedFifoMode() {
    240     struct sched_param param = {0};
    241     param.sched_priority = HUBCONNECTION_SCHED_FIFO_PRIORITY;
    242     if (sched_setscheduler(getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
    243         ALOGE("Couldn't set SCHED_FIFO for HubConnection thread");
    244     }
    245 }
    246 
    247 status_t HubConnection::initCheck() const
    248 {
    249     return mFd < 0 ? UNKNOWN_ERROR : OK;
    250 }
    251 
    252 status_t HubConnection::getAliveCheck()
    253 {
    254     return OK;
    255 }
    256 
    257 static sp<JSONObject> readSettings(File *file) {
    258     off64_t size = file->seekTo(0, SEEK_END);
    259     file->seekTo(0, SEEK_SET);
    260 
    261     sp<JSONObject> root;
    262 
    263     if (size > 0) {
    264         char *buf = (char *)malloc(size);
    265         CHECK_EQ(file->read(buf, size), (ssize_t)size);
    266         file->seekTo(0, SEEK_SET);
    267 
    268         sp<JSONCompound> in = JSONCompound::Parse(buf, size);
    269         free(buf);
    270         buf = NULL;
    271 
    272         if (in != NULL && in->isObject()) {
    273             root = (JSONObject *)in.get();
    274         }
    275     }
    276 
    277     if (root == NULL) {
    278         root = new JSONObject;
    279     }
    280 
    281     return root;
    282 }
    283 
    284 static bool getCalibrationInt32(
    285         const sp<JSONObject> &settings, const char *key, int32_t *out,
    286         size_t numArgs) {
    287     sp<JSONArray> array;
    288     for (size_t i = 0; i < numArgs; i++) {
    289         out[i] = 0;
    290     }
    291     if (!settings->getArray(key, &array)) {
    292         return false;
    293     } else {
    294         for (size_t i = 0; i < numArgs; i++) {
    295             if (!array->getInt32(i, &out[i])) {
    296                 return false;
    297             }
    298         }
    299     }
    300     return true;
    301 }
    302 
    303 static bool getCalibrationFloat(
    304         const sp<JSONObject> &settings, const char *key, float out[3]) {
    305     sp<JSONArray> array;
    306     for (size_t i = 0; i < 3; i++) {
    307         out[i] = 0.0f;
    308     }
    309     if (!settings->getArray(key, &array)) {
    310         return false;
    311     } else {
    312         for (size_t i = 0; i < 3; i++) {
    313             if (!array->getFloat(i, &out[i])) {
    314                 return false;
    315             }
    316         }
    317     }
    318     return true;
    319 }
    320 
    321 static void loadSensorSettings(sp<JSONObject>* settings,
    322                                sp<JSONObject>* saved_settings) {
    323     File settings_file(CONTEXTHUB_SETTINGS_PATH, "r");
    324     File saved_settings_file(CONTEXTHUB_SAVED_SETTINGS_PATH, "r");
    325 
    326     status_t err;
    327     if ((err = settings_file.initCheck()) != OK) {
    328         ALOGE("settings file open failed: %d (%s)",
    329               err,
    330               strerror(-err));
    331 
    332         *settings = new JSONObject;
    333     } else {
    334         *settings = readSettings(&settings_file);
    335     }
    336 
    337     if ((err = saved_settings_file.initCheck()) != OK) {
    338         ALOGE("saved settings file open failed: %d (%s)",
    339               err,
    340               strerror(-err));
    341         *saved_settings = new JSONObject;
    342     } else {
    343         *saved_settings = readSettings(&saved_settings_file);
    344     }
    345 }
    346 
    347 void HubConnection::saveSensorSettings() const {
    348     File saved_settings_file(CONTEXTHUB_SAVED_SETTINGS_PATH, "w");
    349     sp<JSONObject> settingsObject = new JSONObject;
    350 
    351     status_t err;
    352     if ((err = saved_settings_file.initCheck()) != OK) {
    353         ALOGE("saved settings file open failed %d (%s)",
    354               err,
    355               strerror(-err));
    356         return;
    357     }
    358 
    359     // Build a settings object.
    360     sp<JSONArray> magArray = new JSONArray;
    361 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
    362     magArray->addFloat(mMagBias[0] + mUsbMagBias);
    363 #else
    364     magArray->addFloat(mMagBias[0]);
    365 #endif  // USB_MAG_BIAS_REPORTING_ENABLED
    366     magArray->addFloat(mMagBias[1]);
    367     magArray->addFloat(mMagBias[2]);
    368     settingsObject->setArray("mag", magArray);
    369 
    370     // Add gyro settings
    371     sp<JSONArray> gyroArray = new JSONArray;
    372     gyroArray->addFloat(mGyroBias[0]);
    373     gyroArray->addFloat(mGyroBias[1]);
    374     gyroArray->addFloat(mGyroBias[2]);
    375     settingsObject->setArray("gyro_sw", gyroArray);
    376 
    377     // Add accel settings
    378     sp<JSONArray> accelArray = new JSONArray;
    379     accelArray->addFloat(mAccelBias[0]);
    380     accelArray->addFloat(mAccelBias[1]);
    381     accelArray->addFloat(mAccelBias[2]);
    382     settingsObject->setArray("accel_sw", accelArray);
    383 
    384     // Write the JSON string to disk.
    385     AString serializedSettings = settingsObject->toString();
    386     size_t size = serializedSettings.size();
    387     if ((err = saved_settings_file.write(serializedSettings.c_str(), size)) != (ssize_t)size) {
    388         ALOGE("saved settings file write failed %d (%s)",
    389               err,
    390               strerror(-err));
    391     }
    392 }
    393 
    394 sensors_event_t *HubConnection::initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor)
    395 {
    396     memset(ev, 0x00, sizeof(sensors_event_t));
    397     ev->version = sizeof(sensors_event_t);
    398     ev->timestamp = timestamp;
    399     ev->type = type;
    400     ev->sensor = sensor;
    401 
    402     return ev;
    403 }
    404 
    405 void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, __attribute__((unused)) bool highAccuracy)
    406 {
    407     sensors_event_t nev[1];
    408     int cnt = 0;
    409 
    410     switch (sensor) {
    411     case COMMS_SENSOR_ACTIVITY:
    412         if (mActivityEventHandler != NULL) {
    413             mActivityEventHandler->OnActivityEvent(sample->idata & 0x7,
    414                                                    timestamp);
    415         }
    416         break;
    417     case COMMS_SENSOR_PRESSURE:
    418         initEv(&nev[cnt++], timestamp, type, sensor)->pressure = sample->fdata;
    419         break;
    420     case COMMS_SENSOR_TEMPERATURE:
    421         initEv(&nev[cnt++], timestamp, type, sensor)->temperature = sample->fdata;
    422         break;
    423     case COMMS_SENSOR_PROXIMITY:
    424         initEv(&nev[cnt++], timestamp, type, sensor)->distance = sample->fdata;
    425         break;
    426     case COMMS_SENSOR_LIGHT:
    427         initEv(&nev[cnt++], timestamp, type, sensor)->light = sample->fdata;
    428         break;
    429     case COMMS_SENSOR_STEP_COUNTER:
    430         // We'll stash away the last step count in case we need to reset
    431         // the hub. This last step count would then become the new offset.
    432         mLastStepCount = mStepCounterOffset + sample->idata;
    433         initEv(&nev[cnt++], timestamp, type, sensor)->u64.step_counter = mLastStepCount;
    434         break;
    435     case COMMS_SENSOR_STEP_DETECTOR:
    436     case COMMS_SENSOR_SIGNIFICANT_MOTION:
    437     case COMMS_SENSOR_TILT:
    438     case COMMS_SENSOR_DOUBLE_TWIST:
    439     case COMMS_SENSOR_WRIST_TILT:
    440         initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = 1.0f;
    441         break;
    442     case COMMS_SENSOR_GESTURE:
    443     case COMMS_SENSOR_SYNC:
    444     case COMMS_SENSOR_DOUBLE_TOUCH:
    445         initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = sample->idata;
    446         break;
    447     case COMMS_SENSOR_HALL:
    448 #ifdef LID_STATE_REPORTING_ENABLED
    449         sendFolioEvent(sample->idata);
    450 #endif  // LID_STATE_REPORTING_ENABLED
    451         break;
    452     case COMMS_SENSOR_WINDOW_ORIENTATION:
    453         initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = sample->idata;
    454         break;
    455     default:
    456         break;
    457     }
    458 
    459     if (cnt > 0)
    460         mRing.write(nev, cnt);
    461 }
    462 
    463 void HubConnection::magAccuracyUpdate(float x, float y, float z)
    464 {
    465     float magSq = x * x + y * y + z * z;
    466 
    467     if (magSq < MIN_MAG_SQ || magSq > MAX_MAG_SQ) {
    468         // save last good accuracy (either MEDIUM or HIGH)
    469         if (mMagAccuracy != SENSOR_STATUS_UNRELIABLE)
    470             mMagAccuracyRestore = mMagAccuracy;
    471         mMagAccuracy = SENSOR_STATUS_UNRELIABLE;
    472     } else if (mMagAccuracy == SENSOR_STATUS_UNRELIABLE) {
    473         // restore
    474         mMagAccuracy = mMagAccuracyRestore;
    475     }
    476 }
    477 
    478 void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, __attribute__((unused)) bool highAccuracy)
    479 {
    480     sensors_vec_t *sv;
    481     sensors_event_t nev[2];
    482     int cnt = 0;
    483 
    484     switch (sensor) {
    485     case COMMS_SENSOR_ACCEL:
    486         sv = &initEv(&nev[cnt++], timestamp, type, sensor)->acceleration;
    487         sv->x = sample->ix * ACCEL_RAW_KSCALE;
    488         sv->y = sample->iy * ACCEL_RAW_KSCALE;
    489         sv->z = sample->iz * ACCEL_RAW_KSCALE;
    490         sv->status = SENSOR_STATUS_ACCURACY_HIGH;
    491         break;
    492     default:
    493         break;
    494     }
    495 
    496     if (cnt > 0)
    497         mRing.write(nev, cnt);
    498 }
    499 
    500 void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy)
    501 {
    502     sensors_vec_t *sv;
    503     uncalibrated_event_t *ue;
    504     sensors_event_t *ev;
    505     sensors_event_t nev[2];
    506     static const float heading_accuracy = M_PI / 6.0f;
    507     float w;
    508     int cnt = 0;
    509 
    510     switch (sensor) {
    511     case COMMS_SENSOR_ACCEL:
    512         sv = &initEv(&nev[cnt++], timestamp, type, sensor)->acceleration;
    513         sv->x = sample->x;
    514         sv->y = sample->y;
    515         sv->z = sample->z;
    516         sv->status = SENSOR_STATUS_ACCURACY_HIGH;
    517         break;
    518     case COMMS_SENSOR_GYRO:
    519         if (mSensorState[sensor].enable) {
    520             sv = &initEv(&nev[cnt++], timestamp, type, sensor)->gyro;
    521             sv->x = sample->x;
    522             sv->y = sample->y;
    523             sv->z = sample->z;
    524             sv->status = SENSOR_STATUS_ACCURACY_HIGH;
    525         }
    526 
    527         if (mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].enable) {
    528             ue = &initEv(&nev[cnt++], timestamp,
    529                 SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
    530                 COMMS_SENSOR_GYRO_UNCALIBRATED)->uncalibrated_gyro;
    531             ue->x_uncalib = sample->x + mGyroBias[0];
    532             ue->y_uncalib = sample->y + mGyroBias[1];
    533             ue->z_uncalib = sample->z + mGyroBias[2];
    534             ue->x_bias = mGyroBias[0];
    535             ue->y_bias = mGyroBias[1];
    536             ue->z_bias = mGyroBias[2];
    537         }
    538         break;
    539     case COMMS_SENSOR_ACCEL_BIAS:
    540         mAccelBias[0] = sample->x;
    541         mAccelBias[1] = sample->y;
    542         mAccelBias[2] = sample->z;
    543         saveSensorSettings();
    544         break;
    545     case COMMS_SENSOR_GYRO_BIAS:
    546         mGyroBias[0] = sample->x;
    547         mGyroBias[1] = sample->y;
    548         mGyroBias[2] = sample->z;
    549         saveSensorSettings();
    550         break;
    551     case COMMS_SENSOR_MAG:
    552         magAccuracyUpdate(sample->x, sample->y, sample->z);
    553 
    554         if (mSensorState[sensor].enable) {
    555             sv = &initEv(&nev[cnt++], timestamp, type, sensor)->magnetic;
    556             sv->x = sample->x;
    557             sv->y = sample->y;
    558             sv->z = sample->z;
    559             sv->status = mMagAccuracy;
    560         }
    561 
    562         if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable) {
    563             ue = &initEv(&nev[cnt++], timestamp,
    564                 SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
    565                 COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic;
    566             ue->x_uncalib = sample->x + mMagBias[0];
    567             ue->y_uncalib = sample->y + mMagBias[1];
    568             ue->z_uncalib = sample->z + mMagBias[2];
    569             ue->x_bias = mMagBias[0];
    570             ue->y_bias = mMagBias[1];
    571             ue->z_bias = mMagBias[2];
    572         }
    573         break;
    574     case COMMS_SENSOR_MAG_BIAS:
    575         mMagAccuracy = highAccuracy ? SENSOR_STATUS_ACCURACY_HIGH : SENSOR_STATUS_ACCURACY_MEDIUM;
    576         mMagBias[0] = sample->x;
    577         mMagBias[1] = sample->y;
    578         mMagBias[2] = sample->z;
    579 
    580         saveSensorSettings();
    581         break;
    582     case COMMS_SENSOR_ORIENTATION:
    583     case COMMS_SENSOR_LINEAR_ACCEL:
    584     case COMMS_SENSOR_GRAVITY:
    585         sv = &initEv(&nev[cnt++], timestamp, type, sensor)->orientation;
    586         sv->x = sample->x;
    587         sv->y = sample->y;
    588         sv->z = sample->z;
    589         sv->status = mMagAccuracy;
    590         break;
    591     case COMMS_SENSOR_DOUBLE_TAP:
    592         ev = initEv(&nev[cnt++], timestamp, type, sensor);
    593         ev->data[0] = sample->x;
    594         ev->data[1] = sample->y;
    595         ev->data[2] = sample->z;
    596         break;
    597     case COMMS_SENSOR_ROTATION_VECTOR:
    598         ev = initEv(&nev[cnt++], timestamp, type, sensor);
    599         w = sample->x * sample->x + sample->y * sample->y + sample->z * sample->z;
    600         if (w < 1.0f)
    601             w = sqrt(1.0f - w);
    602         else
    603             w = 0.0f;
    604         ev->data[0] = sample->x;
    605         ev->data[1] = sample->y;
    606         ev->data[2] = sample->z;
    607         ev->data[3] = w;
    608         ev->data[4] = (4 - mMagAccuracy) * heading_accuracy;
    609         break;
    610     case COMMS_SENSOR_GEO_MAG:
    611     case COMMS_SENSOR_GAME_ROTATION_VECTOR:
    612         ev = initEv(&nev[cnt++], timestamp, type, sensor);
    613         w = sample->x * sample->x + sample->y * sample->y + sample->z * sample->z;
    614         if (w < 1.0f)
    615             w = sqrt(1.0f - w);
    616         else
    617             w = 0.0f;
    618         ev->data[0] = sample->x;
    619         ev->data[1] = sample->y;
    620         ev->data[2] = sample->z;
    621         ev->data[3] = w;
    622         break;
    623     default:
    624         break;
    625     }
    626 
    627     if (cnt > 0)
    628         mRing.write(nev, cnt);
    629 }
    630 
    631 void HubConnection::discardInotifyEvent() {
    632     // Read & discard an inotify event. We only use the presence of an event as
    633     // a trigger to perform the file existence check (for simplicity)
    634     if (mInotifyPollIndex >= 0) {
    635         char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
    636         int ret = ::read(mPollFds[mInotifyPollIndex].fd, buf, sizeof(buf));
    637         ALOGD("Discarded %d bytes of inotify data", ret);
    638     }
    639 }
    640 
    641 void HubConnection::waitOnNanohubLock() {
    642     if (mInotifyPollIndex < 0) {
    643         return;
    644     }
    645     struct pollfd *pfd = &mPollFds[mInotifyPollIndex];
    646 
    647     // While the lock file exists, poll on the inotify fd (with timeout)
    648     while (access(NANOHUB_LOCK_FILE, F_OK) == 0) {
    649         ALOGW("Nanohub is locked; blocking read thread");
    650         int ret = poll(pfd, 1, 5000);
    651         if ((ret > 0) && (pfd->revents & POLLIN)) {
    652             discardInotifyEvent();
    653         }
    654     }
    655 }
    656 
    657 void HubConnection::restoreSensorState()
    658 {
    659     Mutex::Autolock autoLock(mLock);
    660 
    661     sendCalibrationOffsets();
    662 
    663     for (int i = 0; i < NUM_COMMS_SENSORS_PLUS_1; i++) {
    664         if (mSensorState[i].sensorType && mSensorState[i].enable) {
    665             struct ConfigCmd cmd;
    666 
    667             initConfigCmd(&cmd, i);
    668 
    669             ALOGI("restoring: sensor=%d, handle=%d, enable=%d, period=%" PRId64 ", latency=%" PRId64,
    670                   cmd.sensorType, i, mSensorState[i].enable, frequency_q10_to_period_ns(mSensorState[i].rate),
    671                   mSensorState[i].latency);
    672 
    673             int ret = TEMP_FAILURE_RETRY(write(mFd, &cmd, sizeof(cmd)));
    674             if (ret != sizeof(cmd)) {
    675                 ALOGE("failed to send config command to restore sensor %d\n", cmd.sensorType);
    676             }
    677 
    678             cmd.cmd = CONFIG_CMD_FLUSH;
    679 
    680             for (int j = 0; j < mSensorState[i].flushCnt; j++) {
    681                 int ret = TEMP_FAILURE_RETRY(write(mFd, &cmd, sizeof(cmd)));
    682                 if (ret != sizeof(cmd)) {
    683                     ALOGE("failed to send flush command to sensor %d\n", cmd.sensorType);
    684                 }
    685             }
    686         }
    687     }
    688 
    689     mStepCounterOffset = mLastStepCount;
    690 }
    691 
    692 void HubConnection::postOsLog(uint8_t *buf, ssize_t len)
    693 {
    694     // if len is less than 6, it's either an invalid or an empty log message.
    695     if (len < 6)
    696         return;
    697 
    698     buf[len] = 0x00;
    699     switch (buf[4]) {
    700     case 'E':
    701         ALOGE("osLog: %s", &buf[5]);
    702         break;
    703     case 'W':
    704         ALOGW("osLog: %s", &buf[5]);
    705         break;
    706     case 'I':
    707         ALOGI("osLog: %s", &buf[5]);
    708         break;
    709     case 'D':
    710         ALOGD("osLog: %s", &buf[5]);
    711         break;
    712     default:
    713         break;
    714     }
    715 }
    716 
    717 ssize_t HubConnection::processBuf(uint8_t *buf, ssize_t len)
    718 {
    719     struct nAxisEvent *data = (struct nAxisEvent *)buf;
    720     uint32_t type, sensor, bias, currSensor;
    721     int i, numSamples;
    722     bool one, rawThree, three;
    723     sensors_event_t ev;
    724     uint64_t timestamp;
    725     ssize_t ret = 0;
    726 
    727     if (len >= 4) {
    728         ret = sizeof(data->evtType);
    729         one = three = rawThree = false;
    730         bias = 0;
    731         switch (data->evtType) {
    732         case OS_LOG_EVENT:
    733             postOsLog(buf, len);
    734             return 0;
    735         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACCEL):
    736             type = SENSOR_TYPE_ACCELEROMETER;
    737             sensor = COMMS_SENSOR_ACCEL;
    738             bias = COMMS_SENSOR_ACCEL_BIAS;
    739             three = true;
    740             break;
    741         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACCEL_RAW):
    742             type = SENSOR_TYPE_ACCELEROMETER;
    743             sensor = COMMS_SENSOR_ACCEL;
    744             rawThree = true;
    745             break;
    746         case SENS_TYPE_TO_EVENT(SENS_TYPE_GYRO):
    747             type = SENSOR_TYPE_GYROSCOPE;
    748             sensor = COMMS_SENSOR_GYRO;
    749             bias = COMMS_SENSOR_GYRO_BIAS;
    750             three = true;
    751             break;
    752         case SENS_TYPE_TO_EVENT(SENS_TYPE_MAG):
    753             type = SENSOR_TYPE_MAGNETIC_FIELD;
    754             sensor = COMMS_SENSOR_MAG;
    755             bias = COMMS_SENSOR_MAG_BIAS;
    756             three = true;
    757             break;
    758         case SENS_TYPE_TO_EVENT(SENS_TYPE_ALS):
    759             type = SENSOR_TYPE_LIGHT;
    760             sensor = COMMS_SENSOR_LIGHT;
    761             one = true;
    762             break;
    763         case SENS_TYPE_TO_EVENT(SENS_TYPE_PROX):
    764             type = SENSOR_TYPE_PROXIMITY;
    765             sensor = COMMS_SENSOR_PROXIMITY;
    766             one = true;
    767             break;
    768         case SENS_TYPE_TO_EVENT(SENS_TYPE_BARO):
    769             type = SENSOR_TYPE_PRESSURE;
    770             sensor = COMMS_SENSOR_PRESSURE;
    771             one = true;
    772             break;
    773         case SENS_TYPE_TO_EVENT(SENS_TYPE_TEMP):
    774             type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
    775             sensor = COMMS_SENSOR_TEMPERATURE;
    776             one = true;
    777             break;
    778         case SENS_TYPE_TO_EVENT(SENS_TYPE_ORIENTATION):
    779             type = SENSOR_TYPE_ORIENTATION;
    780             sensor = COMMS_SENSOR_ORIENTATION;
    781             three = true;
    782             break;
    783         case SENS_TYPE_TO_EVENT(SENS_TYPE_WIN_ORIENTATION):
    784             type = SENSOR_TYPE_DEVICE_ORIENTATION;
    785             sensor = COMMS_SENSOR_WINDOW_ORIENTATION;
    786             one = true;
    787             break;
    788         case SENS_TYPE_TO_EVENT(SENS_TYPE_STEP_DETECT):
    789             type = SENSOR_TYPE_STEP_DETECTOR;
    790             sensor = COMMS_SENSOR_STEP_DETECTOR;
    791             one = true;
    792             break;
    793         case SENS_TYPE_TO_EVENT(SENS_TYPE_STEP_COUNT):
    794             type = SENSOR_TYPE_STEP_COUNTER;
    795             sensor = COMMS_SENSOR_STEP_COUNTER;
    796             one = true;
    797             break;
    798         case SENS_TYPE_TO_EVENT(SENS_TYPE_SIG_MOTION):
    799             type = SENSOR_TYPE_SIGNIFICANT_MOTION;
    800             sensor = COMMS_SENSOR_SIGNIFICANT_MOTION;
    801             one = true;
    802             break;
    803         case SENS_TYPE_TO_EVENT(SENS_TYPE_GRAVITY):
    804             type = SENSOR_TYPE_GRAVITY;
    805             sensor = COMMS_SENSOR_GRAVITY;
    806             three = true;
    807             break;
    808         case SENS_TYPE_TO_EVENT(SENS_TYPE_LINEAR_ACCEL):
    809             type = SENSOR_TYPE_LINEAR_ACCELERATION;
    810             sensor = COMMS_SENSOR_LINEAR_ACCEL;
    811             three = true;
    812             break;
    813         case SENS_TYPE_TO_EVENT(SENS_TYPE_ROTATION_VECTOR):
    814             type = SENSOR_TYPE_ROTATION_VECTOR;
    815             sensor = COMMS_SENSOR_ROTATION_VECTOR;
    816             three = true;
    817             break;
    818         case SENS_TYPE_TO_EVENT(SENS_TYPE_GEO_MAG_ROT_VEC):
    819             type = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
    820             sensor = COMMS_SENSOR_GEO_MAG;
    821             three = true;
    822             break;
    823         case SENS_TYPE_TO_EVENT(SENS_TYPE_GAME_ROT_VECTOR):
    824             type = SENSOR_TYPE_GAME_ROTATION_VECTOR;
    825             sensor = COMMS_SENSOR_GAME_ROTATION_VECTOR;
    826             three = true;
    827             break;
    828         case SENS_TYPE_TO_EVENT(SENS_TYPE_HALL):
    829             type = 0;
    830             sensor = COMMS_SENSOR_HALL;
    831             one = true;
    832             break;
    833         case SENS_TYPE_TO_EVENT(SENS_TYPE_VSYNC):
    834             type = SENSOR_TYPE_SYNC;
    835             sensor = COMMS_SENSOR_SYNC;
    836             one = true;
    837             break;
    838         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY):
    839             type = 0;
    840             sensor = COMMS_SENSOR_ACTIVITY;
    841             one = true;
    842             break;
    843         case SENS_TYPE_TO_EVENT(SENS_TYPE_TILT):
    844             type = SENSOR_TYPE_TILT_DETECTOR;
    845             sensor = COMMS_SENSOR_TILT;
    846             one = true;
    847             break;
    848         case SENS_TYPE_TO_EVENT(SENS_TYPE_GESTURE):
    849             type = SENSOR_TYPE_PICK_UP_GESTURE;
    850             sensor = COMMS_SENSOR_GESTURE;
    851             one = true;
    852             break;
    853         case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TWIST):
    854             type = SENSOR_TYPE_DOUBLE_TWIST;
    855             sensor = COMMS_SENSOR_DOUBLE_TWIST;
    856             one = true;
    857             break;
    858         case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TAP):
    859             type = SENSOR_TYPE_DOUBLE_TAP;
    860             sensor = COMMS_SENSOR_DOUBLE_TAP;
    861             three = true;
    862             break;
    863         case SENS_TYPE_TO_EVENT(SENS_TYPE_WRIST_TILT):
    864             type = SENSOR_TYPE_WRIST_TILT_GESTURE;
    865             sensor = COMMS_SENSOR_WRIST_TILT;
    866             one = true;
    867             break;
    868         case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TOUCH):
    869             type = SENSOR_TYPE_DOUBLE_TOUCH;
    870             sensor = COMMS_SENSOR_DOUBLE_TOUCH;
    871             one = true;
    872             break;
    873         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_IN_VEHICLE_START):
    874             type = 0;
    875             sensor = COMMS_SENSOR_ACTIVITY_IN_VEHICLE_START;
    876             one = true;
    877             break;
    878         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_IN_VEHICLE_STOP):
    879             type = 0;
    880             sensor = COMMS_SENSOR_ACTIVITY_IN_VEHICLE_STOP;
    881             one = true;
    882             break;
    883         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_ON_BICYCLE_START):
    884             type = 0;
    885             sensor = COMMS_SENSOR_ACTIVITY_ON_BICYCLE_START;
    886             one = true;
    887             break;
    888         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_ON_BICYCLE_STOP):
    889             type = 0;
    890             sensor = COMMS_SENSOR_ACTIVITY_ON_BICYCLE_STOP;
    891             one = true;
    892             break;
    893         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_WALKING_START):
    894             type = 0;
    895             sensor = COMMS_SENSOR_ACTIVITY_WALKING_START;
    896             one = true;
    897             break;
    898         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_WALKING_STOP):
    899             type = 0;
    900             sensor = COMMS_SENSOR_ACTIVITY_WALKING_STOP;
    901             one = true;
    902             break;
    903         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_RUNNING_START):
    904             type = 0;
    905             sensor = COMMS_SENSOR_ACTIVITY_RUNNING_START;
    906             one = true;
    907             break;
    908         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_RUNNING_STOP):
    909             type = 0;
    910             sensor = COMMS_SENSOR_ACTIVITY_RUNNING_STOP;
    911             one = true;
    912             break;
    913         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_STILL_START):
    914             type = 0;
    915             sensor = COMMS_SENSOR_ACTIVITY_STILL_START;
    916             one = true;
    917             break;
    918         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_STILL_STOP):
    919             type = 0;
    920             sensor = COMMS_SENSOR_ACTIVITY_STILL_STOP;
    921             one = true;
    922             break;
    923         case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_TILTING):
    924             type = 0;
    925             sensor = COMMS_SENSOR_ACTIVITY_TILTING;
    926             one = true;
    927             break;
    928         case EVT_RESET_REASON:
    929             uint32_t resetReason;
    930             memcpy(&resetReason, data->buffer, sizeof(resetReason));
    931             ALOGI("Observed hub reset: 0x%08" PRIx32, resetReason);
    932             restoreSensorState();
    933             return 0;
    934         default:
    935             return 0;
    936         }
    937     }
    938 
    939     if (len >= 16) {
    940         ret += sizeof(data->referenceTime);
    941         timestamp = data->referenceTime;
    942         numSamples = data->firstSample.numSamples;
    943         for (i=0; i<numSamples; i++) {
    944             if (data->firstSample.biasPresent && data->firstSample.biasSample == i)
    945                 currSensor = bias;
    946             else
    947                 currSensor = sensor;
    948 
    949             if (one) {
    950                 if (i > 0)
    951                     timestamp += ((uint64_t)data->oneSamples[i].deltaTime) << delta_time_shift_table[data->oneSamples[i].deltaTime & delta_time_encoded];
    952                 processSample(timestamp, type, currSensor, &data->oneSamples[i], data->firstSample.highAccuracy);
    953                 ret += sizeof(data->oneSamples[i]);
    954             } else if (rawThree) {
    955                 if (i > 0)
    956                     timestamp += ((uint64_t)data->rawThreeSamples[i].deltaTime) << delta_time_shift_table[data->rawThreeSamples[i].deltaTime & delta_time_encoded];
    957                 processSample(timestamp, type, currSensor, &data->rawThreeSamples[i], data->firstSample.highAccuracy);
    958                 ret += sizeof(data->rawThreeSamples[i]);
    959             } else if (three) {
    960                 if (i > 0)
    961                     timestamp += ((uint64_t)data->threeSamples[i].deltaTime) << delta_time_shift_table[data->threeSamples[i].deltaTime & delta_time_encoded];
    962                 processSample(timestamp, type, currSensor, &data->threeSamples[i], data->firstSample.highAccuracy);
    963                 ret += sizeof(data->threeSamples[i]);
    964             }
    965         }
    966 
    967         if (!numSamples)
    968             ret += sizeof(data->firstSample);
    969 
    970         for (i=0; i<data->firstSample.numFlushes; i++) {
    971             if (sensor == COMMS_SENSOR_ACTIVITY) {
    972                 if (mActivityEventHandler != NULL) {
    973                     mActivityEventHandler->OnFlush();
    974                 }
    975             } else {
    976                 memset(&ev, 0x00, sizeof(sensors_event_t));
    977                 ev.version = META_DATA_VERSION;
    978                 ev.timestamp = 0;
    979                 ev.type = SENSOR_TYPE_META_DATA;
    980                 ev.sensor = 0;
    981                 ev.meta_data.what = META_DATA_FLUSH_COMPLETE;
    982                 if (mSensorState[sensor].alt && mSensorState[mSensorState[sensor].alt].flushCnt > 0) {
    983                     mSensorState[mSensorState[sensor].alt].flushCnt --;
    984                     ev.meta_data.sensor = mSensorState[sensor].alt;
    985                 } else {
    986                     mSensorState[sensor].flushCnt --;
    987                     ev.meta_data.sensor = sensor;
    988                 }
    989 
    990                 mRing.write(&ev, 1);
    991                 ALOGI("flushing %d", ev.meta_data.sensor);
    992             }
    993         }
    994     }
    995 
    996     return ret;
    997 }
    998 
    999 void HubConnection::sendCalibrationOffsets()
   1000 {
   1001     sp<JSONObject> settings;
   1002     sp<JSONObject> saved_settings;
   1003     struct {
   1004         int32_t hw[3];
   1005         float sw[3];
   1006     } gyro, accel;
   1007     int32_t proximity, proximity_array[4];
   1008     float barometer, mag[3], light;
   1009     bool gyro_hw_cal_exists, gyro_sw_cal_exists;
   1010     bool accel_hw_cal_exists, accel_sw_cal_exists;
   1011 
   1012     loadSensorSettings(&settings, &saved_settings);
   1013 
   1014     accel_hw_cal_exists = getCalibrationInt32(settings, "accel", accel.hw, 3);
   1015     accel_sw_cal_exists = getCalibrationFloat(saved_settings, "accel_sw", accel.sw);
   1016     if (accel_hw_cal_exists || accel_sw_cal_exists) {
   1017         // Store SW bias so we can remove bias for uncal data
   1018         mAccelBias[0] = accel.sw[0];
   1019         mAccelBias[1] = accel.sw[1];
   1020         mAccelBias[2] = accel.sw[2];
   1021 
   1022         queueDataInternal(COMMS_SENSOR_ACCEL, &accel, sizeof(accel));
   1023     }
   1024 
   1025     gyro_hw_cal_exists = getCalibrationInt32(settings, "gyro", gyro.hw, 3);
   1026     gyro_sw_cal_exists = getCalibrationFloat(saved_settings, "gyro_sw", gyro.sw);
   1027     if (gyro_hw_cal_exists || gyro_sw_cal_exists) {
   1028         // Store SW bias so we can remove bias for uncal data
   1029         mGyroBias[0] = gyro.sw[0];
   1030         mGyroBias[1] = gyro.sw[1];
   1031         mGyroBias[2] = gyro.sw[2];
   1032 
   1033         queueDataInternal(COMMS_SENSOR_GYRO, &gyro, sizeof(gyro));
   1034     }
   1035 
   1036     if (settings->getFloat("barometer", &barometer))
   1037         queueDataInternal(COMMS_SENSOR_PRESSURE, &barometer, sizeof(barometer));
   1038 
   1039     if (settings->getInt32("proximity", &proximity))
   1040         queueDataInternal(COMMS_SENSOR_PROXIMITY, &proximity, sizeof(proximity));
   1041 
   1042     if (getCalibrationInt32(settings, "proximity", proximity_array, 4))
   1043         queueDataInternal(COMMS_SENSOR_PROXIMITY, proximity_array, sizeof(proximity_array));
   1044 
   1045     if (settings->getFloat("light", &light))
   1046         queueDataInternal(COMMS_SENSOR_LIGHT, &light, sizeof(light));
   1047 
   1048     if (getCalibrationFloat(saved_settings, "mag", mag)) {
   1049         // Store SW bias so we can remove bias for uncal data
   1050         mMagBias[0] = mag[0];
   1051         mMagBias[1] = mag[1];
   1052         mMagBias[2] = mag[2];
   1053 
   1054         queueDataInternal(COMMS_SENSOR_MAG, mag, sizeof(mag));
   1055     }
   1056 }
   1057 
   1058 bool HubConnection::threadLoop() {
   1059     ALOGI("threadLoop: starting");
   1060 
   1061     if (mFd < 0) {
   1062         ALOGE("threadLoop: exiting prematurely: nanohub is unavailable");
   1063         return false;
   1064     }
   1065     waitOnNanohubLock();
   1066 
   1067     sendCalibrationOffsets();
   1068 
   1069     while (!Thread::exitPending()) {
   1070         ssize_t ret;
   1071 
   1072         do {
   1073             ret = poll(mPollFds, mNumPollFds, -1);
   1074         } while (ret < 0 && errno == EINTR);
   1075 
   1076         if (mInotifyPollIndex >= 0 && mPollFds[mInotifyPollIndex].revents & POLLIN) {
   1077             discardInotifyEvent();
   1078             waitOnNanohubLock();
   1079         }
   1080 
   1081 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
   1082         if (mMagBiasPollIndex >= 0 && mPollFds[mMagBiasPollIndex].revents & POLLERR) {
   1083             // Read from mag bias file
   1084             char buf[16];
   1085             lseek(mPollFds[mMagBiasPollIndex].fd, 0, SEEK_SET);
   1086             ::read(mPollFds[mMagBiasPollIndex].fd, buf, 16);
   1087             float bias = atof(buf);
   1088             mUsbMagBias = bias;
   1089             queueUsbMagBias();
   1090         }
   1091 #endif // USB_MAG_BIAS_REPORTING_ENABLED
   1092 
   1093 #ifdef DOUBLE_TOUCH_ENABLED
   1094         if (mDoubleTouchPollIndex >= 0 && mPollFds[mDoubleTouchPollIndex].revents & POLLERR) {
   1095             // Read from double touch file
   1096             char buf[16];
   1097             lseek(mPollFds[mDoubleTouchPollIndex].fd, 0, SEEK_SET);
   1098             ::read(mPollFds[mDoubleTouchPollIndex].fd, buf, 16);
   1099             sensors_event_t gestureEvent;
   1100             initEv(&gestureEvent, elapsedRealtimeNano(), SENSOR_TYPE_PICK_UP_GESTURE, COMMS_SENSOR_GESTURE)->data[0] = 8;
   1101             mRing.write(&gestureEvent, 1);
   1102         }
   1103 #endif // DOUBLE_TOUCH_ENABLED
   1104 
   1105         if (mPollFds[0].revents & POLLIN) {
   1106             uint8_t recv[256];
   1107             ssize_t len = ::read(mFd, recv, sizeof(recv));
   1108 
   1109             for (ssize_t offset = 0; offset < len;) {
   1110                 ret = processBuf(recv + offset, len - offset);
   1111 
   1112                 if (ret > 0)
   1113                     offset += ret;
   1114                 else
   1115                     break;
   1116             }
   1117         }
   1118     }
   1119 
   1120     return false;
   1121 }
   1122 
   1123 ssize_t HubConnection::read(sensors_event_t *ev, size_t size) {
   1124     return mRing.read(ev, size);
   1125 }
   1126 
   1127 void HubConnection::setActivityCallback(ActivityEventHandler *eventHandler)
   1128 {
   1129     Mutex::Autolock autoLock(mLock);
   1130     mActivityEventHandler = eventHandler;
   1131 }
   1132 
   1133 void HubConnection::initConfigCmd(struct ConfigCmd *cmd, int handle)
   1134 {
   1135     uint8_t alt = mSensorState[handle].alt;
   1136 
   1137     memset(cmd, 0x00, sizeof(*cmd));
   1138 
   1139     cmd->evtType = EVT_NO_SENSOR_CONFIG_EVENT;
   1140     cmd->sensorType = mSensorState[handle].sensorType;
   1141 
   1142     if (alt && mSensorState[alt].enable && mSensorState[handle].enable) {
   1143         cmd->cmd = CONFIG_CMD_ENABLE;
   1144         if (mSensorState[alt].rate > mSensorState[handle].rate)
   1145             cmd->rate = mSensorState[alt].rate;
   1146         else
   1147             cmd->rate = mSensorState[handle].rate;
   1148         if (mSensorState[alt].latency < mSensorState[handle].latency)
   1149             cmd->latency = mSensorState[alt].latency;
   1150         else
   1151             cmd->latency = mSensorState[handle].latency;
   1152     } else if (alt && mSensorState[alt].enable) {
   1153         cmd->cmd = mSensorState[alt].enable ? CONFIG_CMD_ENABLE : CONFIG_CMD_DISABLE;
   1154         cmd->rate = mSensorState[alt].rate;
   1155         cmd->latency = mSensorState[alt].latency;
   1156     } else { /* !alt || !mSensorState[alt].enable */
   1157         cmd->cmd = mSensorState[handle].enable ? CONFIG_CMD_ENABLE : CONFIG_CMD_DISABLE;
   1158         cmd->rate = mSensorState[handle].rate;
   1159         cmd->latency = mSensorState[handle].latency;
   1160     }
   1161 }
   1162 
   1163 void HubConnection::queueActivate(int handle, bool enable)
   1164 {
   1165     struct ConfigCmd cmd;
   1166     int ret;
   1167 
   1168     Mutex::Autolock autoLock(mLock);
   1169 
   1170     if (mSensorState[handle].sensorType) {
   1171         mSensorState[handle].enable = enable;
   1172 
   1173         initConfigCmd(&cmd, handle);
   1174 
   1175         ret = TEMP_FAILURE_RETRY(write(mFd, &cmd, sizeof(cmd)));
   1176         if (ret == sizeof(cmd))
   1177             ALOGI("queueActivate: sensor=%d, handle=%d, enable=%d",
   1178                     cmd.sensorType, handle, enable);
   1179         else
   1180             ALOGE("queueActivate: failed to send command: sensor=%d, handle=%d, enable=%d",
   1181                     cmd.sensorType, handle, enable);
   1182     } else {
   1183         ALOGI("queueActivate: unhandled handle=%d, enable=%d", handle, enable);
   1184     }
   1185 }
   1186 
   1187 void HubConnection::queueSetDelay(int handle, nsecs_t sampling_period_ns)
   1188 {
   1189     struct ConfigCmd cmd;
   1190     int ret;
   1191 
   1192     Mutex::Autolock autoLock(mLock);
   1193 
   1194     if (mSensorState[handle].sensorType) {
   1195         if (sampling_period_ns > 0 &&
   1196                 mSensorState[handle].rate != SENSOR_RATE_ONCHANGE &&
   1197                 mSensorState[handle].rate != SENSOR_RATE_ONESHOT) {
   1198             mSensorState[handle].rate = period_ns_to_frequency_q10(sampling_period_ns);
   1199         }
   1200 
   1201         initConfigCmd(&cmd, handle);
   1202 
   1203         ret = TEMP_FAILURE_RETRY(write(mFd, &cmd, sizeof(cmd)));
   1204         if (ret == sizeof(cmd))
   1205             ALOGI("queueSetDelay: sensor=%d, handle=%d, period=%" PRId64,
   1206                     cmd.sensorType, handle, sampling_period_ns);
   1207         else
   1208             ALOGE("queueSetDelay: failed to send command: sensor=%d, handle=%d, period=%" PRId64,
   1209                     cmd.sensorType, handle, sampling_period_ns);
   1210     } else {
   1211         ALOGI("queueSetDelay: unhandled handle=%d, period=%" PRId64, handle, sampling_period_ns);
   1212     }
   1213 }
   1214 
   1215 void HubConnection::queueBatch(
   1216         int handle,
   1217         nsecs_t sampling_period_ns,
   1218         nsecs_t max_report_latency_ns)
   1219 {
   1220     struct ConfigCmd cmd;
   1221     int ret;
   1222 
   1223     Mutex::Autolock autoLock(mLock);
   1224 
   1225     if (mSensorState[handle].sensorType) {
   1226         if (sampling_period_ns > 0 &&
   1227                 mSensorState[handle].rate != SENSOR_RATE_ONCHANGE &&
   1228                 mSensorState[handle].rate != SENSOR_RATE_ONESHOT) {
   1229             mSensorState[handle].rate = period_ns_to_frequency_q10(sampling_period_ns);
   1230         }
   1231         mSensorState[handle].latency = max_report_latency_ns;
   1232 
   1233         initConfigCmd(&cmd, handle);
   1234 
   1235         ret = TEMP_FAILURE_RETRY(write(mFd, &cmd, sizeof(cmd)));
   1236         if (ret == sizeof(cmd))
   1237             ALOGI("queueBatch: sensor=%d, handle=%d, period=%" PRId64 ", latency=%" PRId64,
   1238                     cmd.sensorType, handle, sampling_period_ns, max_report_latency_ns);
   1239         else
   1240             ALOGE("queueBatch: failed to send command: sensor=%d, handle=%d, period=%" PRId64 ", latency=%" PRId64,
   1241                     cmd.sensorType, handle, sampling_period_ns, max_report_latency_ns);
   1242     } else {
   1243         ALOGI("queueBatch: unhandled handle=%d, period=%" PRId64 ", latency=%" PRId64,
   1244                 handle, sampling_period_ns, max_report_latency_ns);
   1245     }
   1246 }
   1247 
   1248 void HubConnection::queueFlush(int handle)
   1249 {
   1250     struct ConfigCmd cmd;
   1251     int ret;
   1252 
   1253     Mutex::Autolock autoLock(mLock);
   1254 
   1255     if (mSensorState[handle].sensorType) {
   1256         mSensorState[handle].flushCnt++;
   1257 
   1258         initConfigCmd(&cmd, handle);
   1259         cmd.cmd = CONFIG_CMD_FLUSH;
   1260 
   1261         ret = TEMP_FAILURE_RETRY(write(mFd, &cmd, sizeof(cmd)));
   1262         if (ret == sizeof(cmd))
   1263             ALOGI("queueFlush: sensor=%d, handle=%d",
   1264                     cmd.sensorType, handle);
   1265         else
   1266             ALOGE("queueFlush: failed to send command: sensor=%d, handle=%d",
   1267                     cmd.sensorType, handle);
   1268     } else {
   1269         ALOGI("queueFlush: unhandled handle=%d", handle);
   1270     }
   1271 }
   1272 
   1273 void HubConnection::queueDataInternal(int handle, void *data, size_t length)
   1274 {
   1275     struct ConfigCmd *cmd = (struct ConfigCmd *)malloc(sizeof(struct ConfigCmd) + length);
   1276     size_t ret;
   1277 
   1278     if (cmd && mSensorState[handle].sensorType) {
   1279         initConfigCmd(cmd, handle);
   1280         memcpy(cmd->data, data, length);
   1281         cmd->cmd = CONFIG_CMD_CFG_DATA;
   1282 
   1283         ret = TEMP_FAILURE_RETRY(write(mFd, cmd, sizeof(*cmd) + length));
   1284         if (ret == sizeof(*cmd) + length)
   1285             ALOGI("queueData: sensor=%d, length=%zu",
   1286                     cmd->sensorType, length);
   1287         else
   1288             ALOGE("queueData: failed to send command: sensor=%d, length=%zu",
   1289                     cmd->sensorType, length);
   1290         free(cmd);
   1291     } else {
   1292         ALOGI("queueData: unhandled handle=%d", handle);
   1293     }
   1294 }
   1295 
   1296 void HubConnection::queueData(int handle, void *data, size_t length)
   1297 {
   1298     Mutex::Autolock autoLock(mLock);
   1299     queueDataInternal(handle, data, length);
   1300 }
   1301 
   1302 void HubConnection::initNanohubLock() {
   1303     // Create the lock directory (if it doesn't already exist)
   1304     if (mkdir(NANOHUB_LOCK_DIR, NANOHUB_LOCK_DIR_PERMS) < 0 && errno != EEXIST) {
   1305         ALOGE("Couldn't create Nanohub lock directory: %s", strerror(errno));
   1306         return;
   1307     }
   1308 
   1309     mInotifyPollIndex = -1;
   1310     int inotifyFd = inotify_init1(IN_NONBLOCK);
   1311     if (inotifyFd < 0) {
   1312         ALOGE("Couldn't initialize inotify: %s", strerror(errno));
   1313     } else if (inotify_add_watch(inotifyFd, NANOHUB_LOCK_DIR, IN_CREATE | IN_DELETE) < 0) {
   1314         ALOGE("Couldn't add inotify watch: %s", strerror(errno));
   1315         close(inotifyFd);
   1316     } else {
   1317         mPollFds[mNumPollFds].fd = inotifyFd;
   1318         mPollFds[mNumPollFds].events = POLLIN;
   1319         mPollFds[mNumPollFds].revents = 0;
   1320         mInotifyPollIndex = mNumPollFds;
   1321         mNumPollFds++;
   1322     }
   1323 }
   1324 
   1325 #ifdef USB_MAG_BIAS_REPORTING_ENABLED
   1326 void HubConnection::queueUsbMagBias()
   1327 {
   1328     struct MsgCmd *cmd = (struct MsgCmd *)malloc(sizeof(struct MsgCmd) + sizeof(float));
   1329     size_t ret;
   1330 
   1331     if (cmd) {
   1332         cmd->evtType = EVT_APP_FROM_HOST;
   1333         cmd->msg.appId = APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, APP_ID_APP_BMI160);
   1334         cmd->msg.dataLen = sizeof(float);
   1335         memcpy((float *)(cmd+1), &mUsbMagBias, sizeof(float));
   1336 
   1337         ret = TEMP_FAILURE_RETRY(write(mFd, cmd, sizeof(*cmd) + sizeof(float)));
   1338         if (ret == sizeof(*cmd) + sizeof(float))
   1339             ALOGI("queueUsbMagBias: bias=%f\n", mUsbMagBias);
   1340         else
   1341             ALOGE("queueUsbMagBias: failed to send command: bias=%f\n", mUsbMagBias);
   1342         free(cmd);
   1343     }
   1344 }
   1345 #endif  // USB_MAG_BIAS_REPORTING_ENABLED
   1346 
   1347 #ifdef LID_STATE_REPORTING_ENABLED
   1348 status_t HubConnection::initializeUinputNode()
   1349 {
   1350     int ret = 0;
   1351 
   1352     // Open uinput dev node
   1353     mUinputFd = TEMP_FAILURE_RETRY(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
   1354     if (mUinputFd < 0) {
   1355         ALOGE("could not open uinput node: %s", strerror(errno));
   1356         return UNKNOWN_ERROR;
   1357     }
   1358 
   1359     // Enable SW_LID events
   1360     ret  = TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_EVBIT, EV_SW));
   1361     ret |= TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_EVBIT, EV_SYN));
   1362     ret |= TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_SWBIT, SW_LID));
   1363     if (ret < 0) {
   1364         ALOGE("could not send ioctl to uinput node: %s", strerror(errno));
   1365         return UNKNOWN_ERROR;
   1366     }
   1367 
   1368     // Create uinput node for SW_LID
   1369     struct uinput_user_dev uidev;
   1370     memset(&uidev, 0, sizeof(uidev));
   1371     snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-folio");
   1372     uidev.id.bustype = BUS_SPI;
   1373     uidev.id.vendor  = 0;
   1374     uidev.id.product = 0;
   1375     uidev.id.version = 0;
   1376 
   1377     ret = TEMP_FAILURE_RETRY(write(mUinputFd, &uidev, sizeof(uidev)));
   1378     if (ret < 0) {
   1379         ALOGE("write to uinput node failed: %s", strerror(errno));
   1380         return UNKNOWN_ERROR;
   1381     }
   1382 
   1383     ret = TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_DEV_CREATE));
   1384     if (ret < 0) {
   1385         ALOGE("could not send ioctl to uinput node: %s", strerror(errno));
   1386         return UNKNOWN_ERROR;
   1387     }
   1388 
   1389     return OK;
   1390 }
   1391 
   1392 void HubConnection::sendFolioEvent(int32_t data) {
   1393     ssize_t ret = 0;
   1394     struct input_event ev;
   1395 
   1396     memset(&ev, 0, sizeof(ev));
   1397 
   1398     ev.type = EV_SW;
   1399     ev.code = SW_LID;
   1400     ev.value =  data;
   1401     ret = TEMP_FAILURE_RETRY(write(mUinputFd, &ev, sizeof(ev)));
   1402     if (ret < 0) {
   1403         ALOGE("write to uinput node failed: %s", strerror(errno));
   1404         return;
   1405     }
   1406 
   1407     // Force flush with EV_SYN event
   1408     ev.type = EV_SYN;
   1409     ev.code = SYN_REPORT;
   1410     ev.value =  0;
   1411     ret = TEMP_FAILURE_RETRY(write(mUinputFd, &ev, sizeof(ev)));
   1412     if (ret < 0) {
   1413         ALOGE("write to uinput node failed: %s", strerror(errno));
   1414         return;
   1415     }
   1416 
   1417     // Set lid state property
   1418     if (property_set(LID_STATE_PROPERTY,
   1419                      (data ? LID_STATE_CLOSED : LID_STATE_OPEN)) < 0) {
   1420         ALOGE("could not set lid_state property");
   1421     }
   1422 }
   1423 #endif  // LID_STATE_REPORTING_ENABLED
   1424 
   1425 } // namespace android
   1426