/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "nanohub"

#include "hubconnection.h"

#include "file.h"
#include "JSONObject.h"

#include <errno.h>
#include <unistd.h>
#include <math.h>
#include <inttypes.h>
#include <sched.h>
#include <sys/inotify.h>

#include <linux/input.h>
#include <linux/uinput.h>

#include <cutils/ashmem.h>
#include <cutils/properties.h>
#include <hardware_legacy/power.h>
#include <media/stagefright/foundation/ADebug.h>

#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>

#define APP_ID_GET_VENDOR(appid)       ((appid) >> 24)
#define APP_ID_MAKE(vendor, app)       ((((uint64_t)(vendor)) << 24) | ((app) & 0x00FFFFFF))
#define APP_ID_VENDOR_GOOGLE           0x476f6f676cULL // "Googl"
#define APP_ID_APP_BMI160              2
#define APP_ID_APP_WRIST_TILT_DETECT   0x1005
#define APP_ID_APP_GAZE_DETECT         0x1009
#define APP_ID_APP_UNGAZE_DETECT       0x100a

#define SENS_TYPE_TO_EVENT(_sensorType) (EVT_NO_FIRST_SENSOR_EVENT + (_sensorType))

#define NANOHUB_FILE_PATH       "/dev/nanohub"
#define NANOHUB_LOCK_DIR        "/data/vendor/sensor/nanohub_lock"
#define NANOHUB_LOCK_FILE       NANOHUB_LOCK_DIR "/lock"
#define MAG_BIAS_FILE_PATH      "/sys/class/power_supply/battery/compass_compensation"
#define DOUBLE_TOUCH_FILE_PATH  "/sys/android_touch/synaptics_rmi4_dsx/wake_event"

#define NANOHUB_LOCK_DIR_PERMS  (S_IRUSR | S_IWUSR | S_IXUSR)

#define SENSOR_RATE_ONCHANGE    0xFFFFFF01UL
#define SENSOR_RATE_ONESHOT     0xFFFFFF02UL

#define MIN_MAG_SQ              (10.0f * 10.0f)
#define MAX_MAG_SQ              (80.0f * 80.0f)

#define OS_LOG_EVENT            0x474F4C41  // ascii: ALOG

#define MAX_RETRY_CNT           5

#ifdef LID_STATE_REPORTING_ENABLED
const char LID_STATE_PROPERTY[] = "sensors.contexthub.lid_state";
const char LID_STATE_UNKNOWN[]  = "unknown";
const char LID_STATE_OPEN[]     = "open";
const char LID_STATE_CLOSED[]   = "closed";
#endif  // LID_STATE_REPORTING_ENABLED

constexpr int HUBCONNECTION_SCHED_FIFO_PRIORITY = 3;

static const uint32_t delta_time_encoded = 1;
static const uint32_t delta_time_shift_table[2] = {9, 0};

namespace android {

// static
Mutex HubConnection::sInstanceLock;

// static
HubConnection *HubConnection::sInstance = NULL;

HubConnection *HubConnection::getInstance()
{
    Mutex::Autolock autoLock(sInstanceLock);
    if (sInstance == NULL) {
        sInstance = new HubConnection;
    }
    return sInstance;
}

static bool isWakeEvent(int32_t sensor)
{
    switch (sensor) {
    case COMMS_SENSOR_DOUBLE_TOUCH:
    case COMMS_SENSOR_DOUBLE_TWIST:
    case COMMS_SENSOR_GESTURE:
    case COMMS_SENSOR_PROXIMITY:
    case COMMS_SENSOR_SIGNIFICANT_MOTION:
    case COMMS_SENSOR_TILT:
        return true;
    default:
        return false;
    }
}

HubConnection::HubConnection()
    : Thread(false /* canCallJava */),
      mRing(10 *1024),
      mScaleAccel(1.0f),
      mScaleMag(1.0f),
      mStepCounterOffset(0ull),
      mLastStepCount(0ull)
{
    mMagBias[0] = mMagBias[1] = mMagBias[2] = 0.0f;
    mMagAccuracy = SENSOR_STATUS_UNRELIABLE;
    mMagAccuracyRestore = SENSOR_STATUS_UNRELIABLE;
    mGyroBias[0] = mGyroBias[1] = mGyroBias[2] = 0.0f;
    mAccelBias[0] = mAccelBias[1] = mAccelBias[2] = 0.0f;
    mAccelEnabledBias[0] = mAccelEnabledBias[1] = mAccelEnabledBias[2] = 0.0f;
    mAccelEnabledBiasStored = true;
    memset(&mGyroOtcData, 0, sizeof(mGyroOtcData));

    mLefty.accel = false;
    mLefty.gyro = false;
    mLefty.hub = false;

    memset(&mSensorState, 0x00, sizeof(mSensorState));
    mFd = open(NANOHUB_FILE_PATH, O_RDWR);
    mPollFds[0].fd = mFd;
    mPollFds[0].events = POLLIN;
    mPollFds[0].revents = 0;
    mNumPollFds = 1;

    mWakelockHeld = false;
    mWakeEventCount = 0;
    mWriteFailures = 0;

    initNanohubLock();

#ifdef USB_MAG_BIAS_REPORTING_ENABLED
    mUsbMagBias = 0;
    mMagBiasPollIndex = -1;
    int magBiasFd = open(MAG_BIAS_FILE_PATH, O_RDONLY);
    if (magBiasFd < 0) {
        ALOGW("Mag bias file open failed: %s", strerror(errno));
    } else {
        mPollFds[mNumPollFds].fd = magBiasFd;
        mPollFds[mNumPollFds].events = 0;
        mPollFds[mNumPollFds].revents = 0;
        mMagBiasPollIndex = mNumPollFds;
        mNumPollFds++;
    }
#endif  // USB_MAG_BIAS_REPORTING_ENABLED

#ifdef DOUBLE_TOUCH_ENABLED
    mDoubleTouchPollIndex = -1;
    int doubleTouchFd = open(DOUBLE_TOUCH_FILE_PATH, O_RDONLY);
    if (doubleTouchFd < 0) {
        ALOGW("Double touch file open failed: %s", strerror(errno));
    } else {
        mPollFds[mNumPollFds].fd = doubleTouchFd;
        mPollFds[mNumPollFds].events = 0;
        mPollFds[mNumPollFds].revents = 0;
        mDoubleTouchPollIndex = mNumPollFds;
        mNumPollFds++;
    }
#endif  // DOUBLE_TOUCH_ENABLED

    mSensorState[COMMS_SENSOR_ACCEL].sensorType = SENS_TYPE_ACCEL;
    mSensorState[COMMS_SENSOR_ACCEL].alt[0] = COMMS_SENSOR_ACCEL_UNCALIBRATED;
    mSensorState[COMMS_SENSOR_ACCEL].alt[1] = COMMS_SENSOR_ACCEL_WRIST_AWARE;
    mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].sensorType = SENS_TYPE_ACCEL;
    mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].primary = COMMS_SENSOR_ACCEL;
    mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].alt[0] = COMMS_SENSOR_ACCEL;
    mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].alt[1] = COMMS_SENSOR_ACCEL_WRIST_AWARE;
    mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].sensorType = SENS_TYPE_ACCEL;
    mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].primary = COMMS_SENSOR_ACCEL;
    mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].alt[0] = COMMS_SENSOR_ACCEL;
    mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].alt[1] = COMMS_SENSOR_ACCEL_UNCALIBRATED;
    mSensorState[COMMS_SENSOR_GYRO].sensorType = SENS_TYPE_GYRO;
    mSensorState[COMMS_SENSOR_GYRO].alt[0] = COMMS_SENSOR_GYRO_UNCALIBRATED;
    mSensorState[COMMS_SENSOR_GYRO].alt[1] = COMMS_SENSOR_GYRO_WRIST_AWARE;
    mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].sensorType = SENS_TYPE_GYRO;
    mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].primary = COMMS_SENSOR_GYRO;
    mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].alt[0] = COMMS_SENSOR_GYRO;
    mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].alt[1] = COMMS_SENSOR_GYRO_WRIST_AWARE;
    mSensorState[COMMS_SENSOR_GYRO_WRIST_AWARE].sensorType = SENS_TYPE_GYRO;
    mSensorState[COMMS_SENSOR_GYRO_WRIST_AWARE].primary = COMMS_SENSOR_GYRO;
    mSensorState[COMMS_SENSOR_GYRO_WRIST_AWARE].alt[0] = COMMS_SENSOR_GYRO;
    mSensorState[COMMS_SENSOR_GYRO_WRIST_AWARE].alt[1] = COMMS_SENSOR_GYRO_UNCALIBRATED;
    mSensorState[COMMS_SENSOR_MAG].sensorType = SENS_TYPE_MAG;
    mSensorState[COMMS_SENSOR_MAG].alt[0] = COMMS_SENSOR_MAG_UNCALIBRATED;
    mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].sensorType = SENS_TYPE_MAG;
    mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].primary = COMMS_SENSOR_MAG;
    mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].alt[0] = COMMS_SENSOR_MAG;
    mSensorState[COMMS_SENSOR_LIGHT].sensorType = SENS_TYPE_ALS;
    mSensorState[COMMS_SENSOR_PROXIMITY].sensorType = SENS_TYPE_PROX;
    mSensorState[COMMS_SENSOR_PRESSURE].sensorType = SENS_TYPE_BARO;
    mSensorState[COMMS_SENSOR_TEMPERATURE].sensorType = SENS_TYPE_TEMP;
    mSensorState[COMMS_SENSOR_AMBIENT_TEMPERATURE].sensorType = SENS_TYPE_AMBIENT_TEMP;
    mSensorState[COMMS_SENSOR_ORIENTATION].sensorType = SENS_TYPE_ORIENTATION;
    mSensorState[COMMS_SENSOR_WINDOW_ORIENTATION].sensorType = SENS_TYPE_WIN_ORIENTATION;
    mSensorState[COMMS_SENSOR_WINDOW_ORIENTATION].rate = SENSOR_RATE_ONCHANGE;
    mSensorState[COMMS_SENSOR_STEP_DETECTOR].sensorType = SENS_TYPE_STEP_DETECT;
    mSensorState[COMMS_SENSOR_STEP_DETECTOR].rate = SENSOR_RATE_ONCHANGE;
    mSensorState[COMMS_SENSOR_STEP_COUNTER].sensorType = SENS_TYPE_STEP_COUNT;
    mSensorState[COMMS_SENSOR_SIGNIFICANT_MOTION].sensorType = SENS_TYPE_SIG_MOTION;
    mSensorState[COMMS_SENSOR_SIGNIFICANT_MOTION].rate = SENSOR_RATE_ONESHOT;
    mSensorState[COMMS_SENSOR_GRAVITY].sensorType = SENS_TYPE_GRAVITY;
    mSensorState[COMMS_SENSOR_LINEAR_ACCEL].sensorType = SENS_TYPE_LINEAR_ACCEL;
    mSensorState[COMMS_SENSOR_ROTATION_VECTOR].sensorType = SENS_TYPE_ROTATION_VECTOR;
    mSensorState[COMMS_SENSOR_GEO_MAG].sensorType = SENS_TYPE_GEO_MAG_ROT_VEC;
    mSensorState[COMMS_SENSOR_GAME_ROTATION_VECTOR].sensorType = SENS_TYPE_GAME_ROT_VECTOR;
    mSensorState[COMMS_SENSOR_HALL].sensorType = SENS_TYPE_HALL;
    mSensorState[COMMS_SENSOR_HALL].rate = SENSOR_RATE_ONCHANGE;
    mSensorState[COMMS_SENSOR_SYNC].sensorType = SENS_TYPE_VSYNC;
    mSensorState[COMMS_SENSOR_SYNC].rate = SENSOR_RATE_ONCHANGE;
    mSensorState[COMMS_SENSOR_TILT].sensorType = SENS_TYPE_TILT;
    mSensorState[COMMS_SENSOR_TILT].rate = SENSOR_RATE_ONCHANGE;
    mSensorState[COMMS_SENSOR_GESTURE].sensorType = SENS_TYPE_GESTURE;
    mSensorState[COMMS_SENSOR_GESTURE].rate = SENSOR_RATE_ONESHOT;
    mSensorState[COMMS_SENSOR_DOUBLE_TWIST].sensorType = SENS_TYPE_DOUBLE_TWIST;
    mSensorState[COMMS_SENSOR_DOUBLE_TWIST].rate = SENSOR_RATE_ONCHANGE;
    mSensorState[COMMS_SENSOR_DOUBLE_TAP].sensorType = SENS_TYPE_DOUBLE_TAP;
    mSensorState[COMMS_SENSOR_DOUBLE_TAP].rate = SENSOR_RATE_ONCHANGE;
    mSensorState[COMMS_SENSOR_WRIST_TILT].sensorType = SENS_TYPE_WRIST_TILT;
    mSensorState[COMMS_SENSOR_DOUBLE_TOUCH].sensorType = SENS_TYPE_DOUBLE_TOUCH;
    mSensorState[COMMS_SENSOR_DOUBLE_TOUCH].rate = SENSOR_RATE_ONESHOT;
    mSensorState[COMMS_SENSOR_GAZE].sensorType = SENS_TYPE_GAZE;
    mSensorState[COMMS_SENSOR_GAZE].rate = SENSOR_RATE_ONESHOT;
    mSensorState[COMMS_SENSOR_UNGAZE].sensorType = SENS_TYPE_UNGAZE;
    mSensorState[COMMS_SENSOR_UNGAZE].rate = SENSOR_RATE_ONESHOT;
    mSensorState[COMMS_SENSOR_HUMIDITY].sensorType = SENS_TYPE_HUMIDITY;

#ifdef LID_STATE_REPORTING_ENABLED
    initializeUinputNode();

    // set initial lid state
    if (property_set(LID_STATE_PROPERTY, LID_STATE_UNKNOWN) < 0) {
        ALOGW("could not set lid_state property");
    }

    // enable hall sensor for folio
    if (mFd >= 0) {
        queueActivate(COMMS_SENSOR_HALL, true /* enable */);
    }
#endif  // LID_STATE_REPORTING_ENABLED

#ifdef DIRECT_REPORT_ENABLED
    mDirectChannelHandle = 1;
    mSensorToChannel.emplace(COMMS_SENSOR_ACCEL,
                             std::unordered_map<int32_t, DirectChannelTimingInfo>());
    mSensorToChannel.emplace(COMMS_SENSOR_GYRO,
                             std::unordered_map<int32_t, DirectChannelTimingInfo>());
    mSensorToChannel.emplace(COMMS_SENSOR_MAG,
                             std::unordered_map<int32_t, DirectChannelTimingInfo>());
    mSensorToChannel.emplace(COMMS_SENSOR_ACCEL_UNCALIBRATED,
                             std::unordered_map<int32_t, DirectChannelTimingInfo>());
    mSensorToChannel.emplace(COMMS_SENSOR_GYRO_UNCALIBRATED,
                             std::unordered_map<int32_t, DirectChannelTimingInfo>());
    mSensorToChannel.emplace(COMMS_SENSOR_MAG_UNCALIBRATED,
                             std::unordered_map<int32_t, DirectChannelTimingInfo>());
#endif // DIRECT_REPORT_ENABLED
}

HubConnection::~HubConnection()
{
    close(mFd);
}

void HubConnection::onFirstRef()
{
    run("HubConnection", PRIORITY_URGENT_DISPLAY);
    enableSchedFifoMode();
}

// Set main thread to SCHED_FIFO to lower sensor event latency when system is under load
void HubConnection::enableSchedFifoMode() {
    struct sched_param param = {0};
    param.sched_priority = HUBCONNECTION_SCHED_FIFO_PRIORITY;
    if (sched_setscheduler(getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
        ALOGW("Couldn't set SCHED_FIFO for HubConnection thread");
    }
}

status_t HubConnection::initCheck() const
{
    return mFd < 0 ? UNKNOWN_ERROR : OK;
}

status_t HubConnection::getAliveCheck()
{
    return OK;
}

static sp<JSONObject> readSettings(File *file) {
    off64_t size = file->seekTo(0, SEEK_END);
    file->seekTo(0, SEEK_SET);

    sp<JSONObject> root;

    if (size > 0) {
        char *buf = (char *)malloc(size);
        CHECK_EQ(file->read(buf, size), (ssize_t)size);
        file->seekTo(0, SEEK_SET);

        sp<JSONCompound> in = JSONCompound::Parse(buf, size);
        free(buf);
        buf = NULL;

        if (in != NULL && in->isObject()) {
            root = (JSONObject *)in.get();
        }
    }

    if (root == NULL) {
        root = new JSONObject;
    }

    return root;
}

static bool getCalibrationInt32(
        const sp<JSONObject> &settings, const char *key, int32_t *out,
        size_t numArgs) {
    sp<JSONArray> array;
    for (size_t i = 0; i < numArgs; i++) {
        out[i] = 0;
    }
    if (!settings->getArray(key, &array)) {
        return false;
    } else {
        for (size_t i = 0; i < numArgs; i++) {
            if (!array->getInt32(i, &out[i])) {
                return false;
            }
        }
    }
    return true;
}

static bool getCalibrationFloat(
        const sp<JSONObject> &settings, const char *key, float out[3]) {
    sp<JSONArray> array;
    for (size_t i = 0; i < 3; i++) {
        out[i] = 0.0f;
    }
    if (!settings->getArray(key, &array)) {
        return false;
    } else {
        for (size_t i = 0; i < 3; i++) {
            if (!array->getFloat(i, &out[i])) {
                return false;
            }
        }
    }
    return true;
}

static std::vector<int32_t> getInt32Setting(const sp<JSONObject> &settings, const char *key) {
    std::vector<int32_t> ret;

    sp<JSONArray> array;
    if (settings->getArray(key, &array)) {
        ret.resize(array->size());
        for (size_t i = 0; i < array->size(); ++i) {
            array->getInt32(i, &ret[i]);
        }
    }
    return ret;
}

static std::vector<float> getFloatSetting(const sp<JSONObject> &settings, const char *key) {
    std::vector<float> ret;

    sp<JSONArray> array;
    if (settings->getArray(key, &array)) {
        ret.resize(array->size());
        for (size_t i = 0; i < array->size(); ++i) {
            array->getFloat(i, &ret[i]);
        }
    }
    return ret;
}

static void loadSensorSettings(sp<JSONObject>* settings,
                               sp<JSONObject>* saved_settings) {
    File settings_file(CONTEXTHUB_SETTINGS_PATH, "r");
    File saved_settings_file(CONTEXTHUB_SAVED_SETTINGS_PATH, "r");

    status_t err;
    if ((err = settings_file.initCheck()) != OK) {
        ALOGW("settings file open failed: %d (%s)",
              err,
              strerror(-err));

        *settings = new JSONObject;
    } else {
        *settings = readSettings(&settings_file);
    }

    if ((err = saved_settings_file.initCheck()) != OK) {
        ALOGW("saved settings file open failed: %d (%s)",
              err,
              strerror(-err));
        *saved_settings = new JSONObject;
    } else {
        *saved_settings = readSettings(&saved_settings_file);
    }
}

void HubConnection::saveSensorSettings() const {
    File saved_settings_file(CONTEXTHUB_SAVED_SETTINGS_PATH, "w");
    sp<JSONObject> settingsObject = new JSONObject;

    status_t err;
    if ((err = saved_settings_file.initCheck()) != OK) {
        ALOGW("saved settings file open failed %d (%s)",
              err,
              strerror(-err));
        return;
    }

    // Build a settings object.
    sp<JSONArray> magArray = new JSONArray;
#ifdef USB_MAG_BIAS_REPORTING_ENABLED
    magArray->addFloat(mMagBias[0] + mUsbMagBias);
#else
    magArray->addFloat(mMagBias[0]);
#endif  // USB_MAG_BIAS_REPORTING_ENABLED
    magArray->addFloat(mMagBias[1]);
    magArray->addFloat(mMagBias[2]);
    settingsObject->setArray(MAG_BIAS_TAG, magArray);

    // Add gyro settings
    sp<JSONArray> gyroArray = new JSONArray;
    gyroArray->addFloat(mGyroBias[0]);
    gyroArray->addFloat(mGyroBias[1]);
    gyroArray->addFloat(mGyroBias[2]);
    settingsObject->setArray(GYRO_SW_BIAS_TAG, gyroArray);

    // Add accel settings
    sp<JSONArray> accelArray = new JSONArray;
    accelArray->addFloat(mAccelBias[0]);
    accelArray->addFloat(mAccelBias[1]);
    accelArray->addFloat(mAccelBias[2]);
    settingsObject->setArray(ACCEL_SW_BIAS_TAG, accelArray);

    // Add overtemp calibration values for gyro
    sp<JSONArray> gyroOtcDataArray = new JSONArray;
    const float *f;
    size_t i;
    for (f = reinterpret_cast<const float *>(&mGyroOtcData), i = 0;
            i < sizeof(mGyroOtcData)/sizeof(float); ++i, ++f) {
        gyroOtcDataArray->addFloat(*f);
    }
    settingsObject->setArray(GYRO_OTC_DATA_TAG, gyroOtcDataArray);

    // Write the JSON string to disk.
    AString serializedSettings = settingsObject->toString();
    size_t size = serializedSettings.size();
    if ((err = saved_settings_file.write(serializedSettings.c_str(), size)) != (ssize_t)size) {
        ALOGW("saved settings file write failed %d (%s)",
              err,
              strerror(-err));
    }
}

ssize_t HubConnection::sendCmd(const void *buf, size_t count)
{
    ssize_t ret;
    int retryCnt = 0;

    do {
        ret = TEMP_FAILURE_RETRY(::write(mFd, buf, count));
    } while (ret == 0 && retryCnt++ < MAX_RETRY_CNT);

    if (retryCnt > 0)
        ALOGW("sendCmd: retry: count=%zu, ret=%zd, retryCnt=%d",
              count, ret, retryCnt);
    else if (ret < 0 || static_cast<size_t>(ret) != count)
        ALOGW("sendCmd: failed: count=%zu, ret=%zd, errno=%d",
              count, ret, errno);

    return ret;
}

void HubConnection::setLeftyMode(bool enable) {
    struct MsgCmd *cmd;
    size_t ret;

    Mutex::Autolock autoLock(mLock);

    if (enable == mLefty.hub) return;

    cmd = (struct MsgCmd *)malloc(sizeof(struct MsgCmd) + sizeof(bool));

    if (cmd) {
        cmd->evtType = EVT_APP_FROM_HOST;
        cmd->msg.appId = APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, APP_ID_APP_GAZE_DETECT);
        cmd->msg.dataLen = sizeof(bool);
        memcpy((bool *)(cmd+1), &enable, sizeof(bool));

        ret = sendCmd(cmd, sizeof(*cmd) + sizeof(bool));
        if (ret == sizeof(*cmd) + sizeof(bool))
            ALOGV("setLeftyMode: lefty (gaze) = %s\n",
                  (enable ? "true" : "false"));
        else
            ALOGE("setLeftyMode: failed to send command lefty (gaze) = %s\n",
                  (enable ? "true" : "false"));

        cmd->msg.appId = APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, APP_ID_APP_UNGAZE_DETECT);

        ret = sendCmd(cmd, sizeof(*cmd) + sizeof(bool));
        if (ret == sizeof(*cmd) + sizeof(bool))
            ALOGV("setLeftyMode: lefty (ungaze) = %s\n",
                  (enable ? "true" : "false"));
        else
            ALOGE("setLeftyMode: failed to send command lefty (ungaze) = %s\n",
                  (enable ? "true" : "false"));

        cmd->msg.appId = APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, APP_ID_APP_WRIST_TILT_DETECT);

        ret = sendCmd(cmd, sizeof(*cmd) + sizeof(bool));
        if (ret == sizeof(*cmd) + sizeof(bool))
            ALOGV("setLeftyMode: lefty (tilt) = %s\n",
                  (enable ? "true" : "false"));
        else
            ALOGE("setLeftyMode: failed to send command lefty (tilt) = %s\n",
                  (enable ? "true" : "false"));

        free(cmd);
    } else {
        ALOGE("setLeftyMode: failed to allocate command\n");
        return;
    }

    queueFlushInternal(COMMS_SENSOR_ACCEL_WRIST_AWARE, true);
    queueFlushInternal(COMMS_SENSOR_GYRO_WRIST_AWARE, true);

    mLefty.hub = enable;
}

sensors_event_t *HubConnection::initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor)
{
    memset(ev, 0x00, sizeof(sensors_event_t));
    ev->version = sizeof(sensors_event_t);
    ev->timestamp = timestamp;
    ev->type = type;
    ev->sensor = sensor;

    return ev;
}

ssize_t HubConnection::decrementIfWakeEventLocked(int32_t sensor)
{
    if (isWakeEvent(sensor)) {
        if (mWakeEventCount > 0)
            mWakeEventCount--;
        else
            ALOGW("%s: sensor=%d, unexpected count=%d, no-op",
                  __FUNCTION__, sensor, mWakeEventCount);
    }

    return mWakeEventCount;
}

void HubConnection::protectIfWakeEventLocked(int32_t sensor)
{
    if (isWakeEvent(sensor)) {
        if (mWakelockHeld == false) {
            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKELOCK_NAME);
            mWakelockHeld = true;
        }
        mWakeEventCount++;
    }
}

void HubConnection::releaseWakeLockIfAppropriate()
{
    Mutex::Autolock autoLock(mLock);

    if (mWakelockHeld && (mWakeEventCount == 0)) {
        mWakelockHeld = false;
        release_wake_lock(WAKELOCK_NAME);
    }
}

void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, __attribute__((unused)) bool highAccuracy)
{
    sensors_event_t nev[1];
    int cnt = 0;

    switch (sensor) {
    case COMMS_SENSOR_PRESSURE:
        initEv(&nev[cnt++], timestamp, type, sensor)->pressure = sample->fdata;
        break;
    case COMMS_SENSOR_HUMIDITY:
        initEv(&nev[cnt++], timestamp, type, sensor)->relative_humidity = sample->fdata;
        break;
    case COMMS_SENSOR_TEMPERATURE:
        initEv(&nev[cnt++], timestamp, type, sensor)->temperature = sample->fdata;
        break;
    case COMMS_SENSOR_AMBIENT_TEMPERATURE:
        initEv(&nev[cnt++], timestamp, type, sensor)->temperature = sample->fdata;
        break;
    case COMMS_SENSOR_PROXIMITY:
        initEv(&nev[cnt++], timestamp, type, sensor)->distance = sample->fdata;
        break;
    case COMMS_SENSOR_LIGHT:
        initEv(&nev[cnt++], timestamp, type, sensor)->light = sample->fdata;
        break;
    case COMMS_SENSOR_STEP_COUNTER:
        // We'll stash away the last step count in case we need to reset
        // the hub. This last step count would then become the new offset.
        mLastStepCount = mStepCounterOffset + sample->idata;
        initEv(&nev[cnt++], timestamp, type, sensor)->u64.step_counter = mLastStepCount;
        break;
    case COMMS_SENSOR_STEP_DETECTOR:
    case COMMS_SENSOR_SIGNIFICANT_MOTION:
    case COMMS_SENSOR_TILT:
    case COMMS_SENSOR_DOUBLE_TWIST:
    case COMMS_SENSOR_WRIST_TILT:
        initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = 1.0f;
        break;
    case COMMS_SENSOR_GAZE:
    case COMMS_SENSOR_UNGAZE:
    case COMMS_SENSOR_GESTURE:
    case COMMS_SENSOR_SYNC:
    case COMMS_SENSOR_DOUBLE_TOUCH:
        initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = sample->idata;
        break;
    case COMMS_SENSOR_HALL:
#ifdef LID_STATE_REPORTING_ENABLED
        sendFolioEvent(sample->idata);
#endif  // LID_STATE_REPORTING_ENABLED
        break;
    case COMMS_SENSOR_WINDOW_ORIENTATION:
        initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = sample->idata;
        break;
    default:
        break;
    }

    if (cnt > 0)
        write(nev, cnt);
}

uint8_t HubConnection::magAccuracyUpdate(sensors_vec_t *sv)
{
    float magSq = sv->x * sv->x + sv->y * sv->y + sv->z * sv->z;

    if (magSq < MIN_MAG_SQ || magSq > MAX_MAG_SQ) {
        // save last good accuracy (either MEDIUM or HIGH)
        if (mMagAccuracy != SENSOR_STATUS_UNRELIABLE)
            mMagAccuracyRestore = mMagAccuracy;
        mMagAccuracy = SENSOR_STATUS_UNRELIABLE;
    } else if (mMagAccuracy == SENSOR_STATUS_UNRELIABLE) {
        // restore
        mMagAccuracy = mMagAccuracyRestore;
    }

    return mMagAccuracy;
}

void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, __attribute__((unused)) bool highAccuracy)
{
    sensors_vec_t *sv;
    uncalibrated_event_t *ue;
    sensors_event_t nev[3];
    int cnt = 0;

    switch (sensor) {
    case COMMS_SENSOR_ACCEL:
        sv = &initEv(&nev[cnt], timestamp, type, sensor)->acceleration;
        sv->x = sample->ix * mScaleAccel;
        sv->y = sample->iy * mScaleAccel;
        sv->z = sample->iz * mScaleAccel;
        sv->status = SENSOR_STATUS_ACCURACY_HIGH;

        sendDirectReportEvent(&nev[cnt], 1);
        if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) {
            if (!mAccelEnabledBiasStored) {
                // accel is enabled, but no enabled bias. Store latest bias and use
                // for accel and uncalibrated accel due to:
                // https://source.android.com/devices/sensors/sensor-types.html
                // "The bias and scale calibration must only be updated while the sensor is deactivated,
                // so as to avoid causing jumps in values during streaming."
                mAccelEnabledBiasStored = true;
                mAccelEnabledBias[0] = mAccelBias[0];
                mAccelEnabledBias[1] = mAccelBias[1];
                mAccelEnabledBias[2] = mAccelBias[2];
            }
            // samples arrive using latest bias
            // adjust for enabled bias being different from lastest bias
            sv->x += mAccelBias[0] - mAccelEnabledBias[0];
            sv->y += mAccelBias[1] - mAccelEnabledBias[1];
            sv->z += mAccelBias[2] - mAccelEnabledBias[2];
            ++cnt;
        }

        ue = &initEv(&nev[cnt], timestamp,
            SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED,
            COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer;
        ue->x_uncalib = sample->ix * mScaleAccel + mAccelBias[0];
        ue->y_uncalib = sample->iy * mScaleAccel + mAccelBias[1];
        ue->z_uncalib = sample->iz * mScaleAccel + mAccelBias[2];
        if (!mAccelEnabledBiasStored) {
            // No enabled bias (which means accel is disabled). Use latest bias.
            ue->x_bias = mAccelBias[0];
            ue->y_bias = mAccelBias[1];
            ue->z_bias = mAccelBias[2];
        } else {
            // enabled bias is valid, so use it
            ue->x_bias = mAccelEnabledBias[0];
            ue->y_bias = mAccelEnabledBias[1];
            ue->z_bias = mAccelEnabledBias[2];
        }

        sendDirectReportEvent(&nev[cnt], 1);
        if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_UNCALIBRATED, timestamp)) {
            ++cnt;
        }

        if (mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_WRIST_AWARE, timestamp)) {
            sv = &initEv(&nev[cnt++], timestamp,
                SENSOR_TYPE_ACCELEROMETER_WRIST_AWARE,
                COMMS_SENSOR_ACCEL_WRIST_AWARE)->acceleration;
            sv->x = sample->ix * mScaleAccel;
            sv->y = (mLefty.accel ? -sample->iy : sample->iy) * mScaleAccel;
            sv->z = sample->iz * mScaleAccel;
            sv->status = SENSOR_STATUS_ACCURACY_HIGH;
        }
        break;
    case COMMS_SENSOR_MAG:
        sv = &initEv(&nev[cnt], timestamp, type, sensor)->magnetic;
        sv->x = sample->ix * mScaleMag;
        sv->y = sample->iy * mScaleMag;
        sv->z = sample->iz * mScaleMag;
        sv->status = magAccuracyUpdate(sv);

        sendDirectReportEvent(&nev[cnt], 1);
        if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) {
            ++cnt;
        }

        ue = &initEv(&nev[cnt], timestamp,
            SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
            COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic;
        ue->x_uncalib = sample->ix * mScaleMag + mMagBias[0];
        ue->y_uncalib = sample->iy * mScaleMag + mMagBias[1];
        ue->z_uncalib = sample->iz * mScaleMag + mMagBias[2];
        ue->x_bias = mMagBias[0];
        ue->y_bias = mMagBias[1];
        ue->z_bias = mMagBias[2];

        sendDirectReportEvent(&nev[cnt], 1);
        if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_MAG_UNCALIBRATED, timestamp)) {
            ++cnt;
        }
        break;
    default:
        break;
    }

    if (cnt > 0)
        write(nev, cnt);
}

void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy)
{
    sensors_vec_t *sv;
    uncalibrated_event_t *ue;
    sensors_event_t *ev;
    sensors_event_t nev[3];
    static const float heading_accuracy = M_PI / 6.0f;
    float w;
    int cnt = 0;

    switch (sensor) {
    case COMMS_SENSOR_ACCEL:
        sv = &initEv(&nev[cnt], timestamp, type, sensor)->acceleration;
        sv->x = sample->x;
        sv->y = sample->y;
        sv->z = sample->z;
        sv->status = SENSOR_STATUS_ACCURACY_HIGH;

        sendDirectReportEvent(&nev[cnt], 1);
        if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) {
            ++cnt;
        }

        ue = &initEv(&nev[cnt], timestamp,
            SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED,
            COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer;
        ue->x_uncalib = sample->x + mAccelBias[0];
        ue->y_uncalib = sample->y + mAccelBias[1];
        ue->z_uncalib = sample->z + mAccelBias[2];
        ue->x_bias = mAccelBias[0];
        ue->y_bias = mAccelBias[1];
        ue->z_bias = mAccelBias[2];

        sendDirectReportEvent(&nev[cnt], 1);
        if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_UNCALIBRATED, timestamp)) {
            ++cnt;
        }

        if (mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_WRIST_AWARE, timestamp)) {
            sv = &initEv(&nev[cnt], timestamp,
                SENSOR_TYPE_ACCELEROMETER_WRIST_AWARE,
                COMMS_SENSOR_ACCEL_WRIST_AWARE)->acceleration;
            sv->x = sample->x;
            sv->y = (mLefty.accel ? -sample->y : sample->y);
            sv->z = sample->z;
            sv->status = SENSOR_STATUS_ACCURACY_HIGH;
            ++cnt;
        }
        break;
    case COMMS_SENSOR_GYRO:
        sv = &initEv(&nev[cnt], timestamp, type, sensor)->gyro;
        sv->x = sample->x;
        sv->y = sample->y;
        sv->z = sample->z;
        sv->status = SENSOR_STATUS_ACCURACY_HIGH;

        sendDirectReportEvent(&nev[cnt], 1);
        if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) {
            ++cnt;
        }

        ue = &initEv(&nev[cnt], timestamp,
            SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
            COMMS_SENSOR_GYRO_UNCALIBRATED)->uncalibrated_gyro;
        ue->x_uncalib = sample->x + mGyroBias[0];
        ue->y_uncalib = sample->y + mGyroBias[1];
        ue->z_uncalib = sample->z + mGyroBias[2];
        ue->x_bias = mGyroBias[0];
        ue->y_bias = mGyroBias[1];
        ue->z_bias = mGyroBias[2];
        sendDirectReportEvent(&nev[cnt], 1);

        if (mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_GYRO_UNCALIBRATED, timestamp)) {
            ++cnt;
        }

        if (mSensorState[COMMS_SENSOR_GYRO_WRIST_AWARE].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_GYRO_WRIST_AWARE, timestamp)) {
            sv = &initEv(&nev[cnt], timestamp,
                SENSOR_TYPE_GYROSCOPE_WRIST_AWARE,
                COMMS_SENSOR_GYRO_WRIST_AWARE)->gyro;
            sv->x = (mLefty.gyro ? -sample->x : sample->x);
            sv->y = sample->y;
            sv->z = (mLefty.gyro ? -sample->z : sample->z);
            sv->status = SENSOR_STATUS_ACCURACY_HIGH;
            ++cnt;
        }
        break;
    case COMMS_SENSOR_ACCEL_BIAS:
        mAccelBias[0] = sample->x;
        mAccelBias[1] = sample->y;
        mAccelBias[2] = sample->z;
        saveSensorSettings();
        break;
    case COMMS_SENSOR_GYRO_BIAS:
        mGyroBias[0] = sample->x;
        mGyroBias[1] = sample->y;
        mGyroBias[2] = sample->z;
        saveSensorSettings();
        break;
    case COMMS_SENSOR_MAG:
        sv = &initEv(&nev[cnt], timestamp, type, sensor)->magnetic;
        sv->x = sample->x;
        sv->y = sample->y;
        sv->z = sample->z;
        sv->status = magAccuracyUpdate(sv);
        sendDirectReportEvent(&nev[cnt], 1);

        if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) {
            ++cnt;
        }

        ue = &initEv(&nev[cnt], timestamp,
            SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
            COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic;
        ue->x_uncalib = sample->x + mMagBias[0];
        ue->y_uncalib = sample->y + mMagBias[1];
        ue->z_uncalib = sample->z + mMagBias[2];
        ue->x_bias = mMagBias[0];
        ue->y_bias = mMagBias[1];
        ue->z_bias = mMagBias[2];
        sendDirectReportEvent(&nev[cnt], 1);

        if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable
                && isSampleIntervalSatisfied(COMMS_SENSOR_MAG_UNCALIBRATED, timestamp)) {
            ++cnt;
        }
        break;
    case COMMS_SENSOR_MAG_BIAS:
        mMagAccuracy = highAccuracy ? SENSOR_STATUS_ACCURACY_HIGH : SENSOR_STATUS_ACCURACY_MEDIUM;
        mMagBias[0] = sample->x;
        mMagBias[1] = sample->y;
        mMagBias[2] = sample->z;

        saveSensorSettings();
        break;
    case COMMS_SENSOR_ORIENTATION:
    case COMMS_SENSOR_LINEAR_ACCEL:
    case COMMS_SENSOR_GRAVITY:
        sv = &initEv(&nev[cnt++], timestamp, type, sensor)->orientation;
        sv->x = sample->x;
        sv->y = sample->y;
        sv->z = sample->z;
        sv->status = mMagAccuracy;
        break;
    case COMMS_SENSOR_DOUBLE_TAP:
        ev = initEv(&nev[cnt++], timestamp, type, sensor);
        ev->data[0] = sample->x;
        ev->data[1] = sample->y;
        ev->data[2] = sample->z;
        break;
    case COMMS_SENSOR_ROTATION_VECTOR:
        ev = initEv(&nev[cnt++], timestamp, type, sensor);
        w = sample->x * sample->x + sample->y * sample->y + sample->z * sample->z;
        if (w < 1.0f)
            w = sqrt(1.0f - w);
        else
            w = 0.0f;
        ev->data[0] = sample->x;
        ev->data[1] = sample->y;
        ev->data[2] = sample->z;
        ev->data[3] = w;
        ev->data[4] = (4 - mMagAccuracy) * heading_accuracy;
        break;
    case COMMS_SENSOR_GEO_MAG:
    case COMMS_SENSOR_GAME_ROTATION_VECTOR:
        ev = initEv(&nev[cnt++], timestamp, type, sensor);
        w = sample->x * sample->x + sample->y * sample->y + sample->z * sample->z;
        if (w < 1.0f)
            w = sqrt(1.0f - w);
        else
            w = 0.0f;
        ev->data[0] = sample->x;
        ev->data[1] = sample->y;
        ev->data[2] = sample->z;
        ev->data[3] = w;
        break;
    default:
        break;
    }

    if (cnt > 0)
        write(nev, cnt);
}

void HubConnection::discardInotifyEvent() {
    // Read & discard an inotify event. We only use the presence of an event as
    // a trigger to perform the file existence check (for simplicity)
    if (mInotifyPollIndex >= 0) {
        char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
        int ret = ::read(mPollFds[mInotifyPollIndex].fd, buf, sizeof(buf));
        ALOGV("Discarded %d bytes of inotify data", ret);
    }
}

void HubConnection::waitOnNanohubLock() {
    if (mInotifyPollIndex < 0) {
        return;
    }
    struct pollfd *pfd = &mPollFds[mInotifyPollIndex];

    // While the lock file exists, poll on the inotify fd (with timeout)
    while (access(NANOHUB_LOCK_FILE, F_OK) == 0) {
        ALOGW("Nanohub is locked; blocking read thread");
        int ret = poll(pfd, 1, 5000);
        if ((ret > 0) && (pfd->revents & POLLIN)) {
            discardInotifyEvent();
        }
    }
}

void HubConnection::restoreSensorState()
{
    Mutex::Autolock autoLock(mLock);

    sendCalibrationOffsets();

    for (int i = 0; i < NUM_COMMS_SENSORS_PLUS_1; i++) {
        if (mSensorState[i].sensorType && mSensorState[i].enable) {
            struct ConfigCmd cmd;

            initConfigCmd(&cmd, i);

            ALOGV("restoring: sensor=%d, handle=%d, enable=%d, period=%" PRId64 ", latency=%" PRId64,
                  cmd.sensorType, i, mSensorState[i].enable, frequency_q10_to_period_ns(mSensorState[i].rate),
                  mSensorState[i].latency);

            int ret = sendCmd(&cmd, sizeof(cmd));
            if (ret != sizeof(cmd)) {
                ALOGW("failed to send config command to restore sensor %d\n", cmd.sensorType);
            }

            cmd.cmd = CONFIG_CMD_FLUSH;

            for (auto iter = mFlushesPending[i].cbegin(); iter != mFlushesPending[i].cend(); ++iter) {
                for (int j = 0; j < iter->count; j++) {
                    int ret = sendCmd(&cmd, sizeof(cmd));
                    if (ret != sizeof(cmd)) {
                        ALOGW("failed to send flush command to sensor %d\n", cmd.sensorType);
                    }
                }
            }
        }
    }

    mStepCounterOffset = mLastStepCount;
}

void HubConnection::postOsLog(uint8_t *buf, ssize_t len)
{
    // if len is less than 6, it's either an invalid or an empty log message.
    if (len < 6)
        return;

    buf[len] = 0x00;
    switch (buf[4]) {
    case 'E':
        ALOGE("osLog: %s", &buf[5]);
        break;
    case 'W':
        ALOGW("osLog: %s", &buf[5]);
        break;
    case 'I':
        ALOGI("osLog: %s", &buf[5]);
        break;
    case 'D':
        ALOGD("osLog: %s", &buf[5]);
        break;
    case 'V':
        ALOGV("osLog: %s", &buf[5]);
        break;
    default:
        break;
    }
}

void HubConnection::processAppData(uint8_t *buf, ssize_t len) {
    if (len < static_cast<ssize_t>(sizeof(AppToSensorHalDataBuffer)))
        return;

    AppToSensorHalDataPayload *data =
            &(reinterpret_cast<AppToSensorHalDataBuffer *>(buf)->payload);
    if (data->size + sizeof(AppToSensorHalDataBuffer) != len) {
        ALOGW("Received corrupted data update packet, len %zd, size %u", len, data->size);
        return;
    }

    switch (data->type & APP_TO_SENSOR_HAL_TYPE_MASK) {
    case HALINTF_TYPE_GYRO_OTC_DATA:
        if (data->size != sizeof(GyroOtcData)) {
            ALOGW("Corrupted HALINTF_TYPE_GYRO_OTC_DATA with size %u", data->size);
            return;
        }
        mGyroOtcData = data->gyroOtcData[0];
        saveSensorSettings();
        break;
    default:
        ALOGW("Unknown app to hal data type 0x%04x", data->type);
        break;
    }
}

ssize_t HubConnection::processBuf(uint8_t *buf, size_t len)
{
    struct nAxisEvent *data = (struct nAxisEvent *)buf;
    uint32_t type, sensor, bias, currSensor;
    int i, numSamples;
    bool one, rawThree, three;
    sensors_event_t ev;
    uint64_t timestamp;
    ssize_t ret = 0;
    uint32_t primary;

    if (len >= sizeof(data->evtType)) {
        ret = sizeof(data->evtType);
        one = three = rawThree = false;
        bias = 0;
        switch (data->evtType) {
        case OS_LOG_EVENT:
            postOsLog(buf, len);
            return 0;
        case EVT_APP_TO_SENSOR_HAL_DATA:
            processAppData(buf, len);
            return 0;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_ACCEL):
            type = SENSOR_TYPE_ACCELEROMETER;
            sensor = COMMS_SENSOR_ACCEL;
            bias = COMMS_SENSOR_ACCEL_BIAS;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_ACCEL_RAW):
            type = SENSOR_TYPE_ACCELEROMETER;
            sensor = COMMS_SENSOR_ACCEL;
            rawThree = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_GYRO):
            type = SENSOR_TYPE_GYROSCOPE;
            sensor = COMMS_SENSOR_GYRO;
            bias = COMMS_SENSOR_GYRO_BIAS;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_MAG):
            type = SENSOR_TYPE_MAGNETIC_FIELD;
            sensor = COMMS_SENSOR_MAG;
            bias = COMMS_SENSOR_MAG_BIAS;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_MAG_RAW):
            type = SENSOR_TYPE_MAGNETIC_FIELD;
            sensor = COMMS_SENSOR_MAG;
            rawThree = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_ALS):
            type = SENSOR_TYPE_LIGHT;
            sensor = COMMS_SENSOR_LIGHT;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_PROX):
            type = SENSOR_TYPE_PROXIMITY;
            sensor = COMMS_SENSOR_PROXIMITY;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_BARO):
            type = SENSOR_TYPE_PRESSURE;
            sensor = COMMS_SENSOR_PRESSURE;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_HUMIDITY):
            type = SENSOR_TYPE_RELATIVE_HUMIDITY;
            sensor = COMMS_SENSOR_HUMIDITY;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_TEMP):
            // nanohub only has one temperature sensor type, which is mapped to
            // internal temp because we currently don't have ambient temp
            type = SENSOR_TYPE_INTERNAL_TEMPERATURE;
            sensor = COMMS_SENSOR_TEMPERATURE;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_AMBIENT_TEMP):
            type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
            sensor = COMMS_SENSOR_AMBIENT_TEMPERATURE;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_ORIENTATION):
            type = SENSOR_TYPE_ORIENTATION;
            sensor = COMMS_SENSOR_ORIENTATION;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_WIN_ORIENTATION):
            type = SENSOR_TYPE_DEVICE_ORIENTATION;
            sensor = COMMS_SENSOR_WINDOW_ORIENTATION;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_STEP_DETECT):
            type = SENSOR_TYPE_STEP_DETECTOR;
            sensor = COMMS_SENSOR_STEP_DETECTOR;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_STEP_COUNT):
            type = SENSOR_TYPE_STEP_COUNTER;
            sensor = COMMS_SENSOR_STEP_COUNTER;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_SIG_MOTION):
            type = SENSOR_TYPE_SIGNIFICANT_MOTION;
            sensor = COMMS_SENSOR_SIGNIFICANT_MOTION;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_GRAVITY):
            type = SENSOR_TYPE_GRAVITY;
            sensor = COMMS_SENSOR_GRAVITY;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_LINEAR_ACCEL):
            type = SENSOR_TYPE_LINEAR_ACCELERATION;
            sensor = COMMS_SENSOR_LINEAR_ACCEL;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_ROTATION_VECTOR):
            type = SENSOR_TYPE_ROTATION_VECTOR;
            sensor = COMMS_SENSOR_ROTATION_VECTOR;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_GEO_MAG_ROT_VEC):
            type = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
            sensor = COMMS_SENSOR_GEO_MAG;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_GAME_ROT_VECTOR):
            type = SENSOR_TYPE_GAME_ROTATION_VECTOR;
            sensor = COMMS_SENSOR_GAME_ROTATION_VECTOR;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_HALL):
            type = 0;
            sensor = COMMS_SENSOR_HALL;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_VSYNC):
            type = SENSOR_TYPE_SYNC;
            sensor = COMMS_SENSOR_SYNC;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_TILT):
            type = SENSOR_TYPE_TILT_DETECTOR;
            sensor = COMMS_SENSOR_TILT;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_GESTURE):
            type = SENSOR_TYPE_PICK_UP_GESTURE;
            sensor = COMMS_SENSOR_GESTURE;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TWIST):
            type = SENSOR_TYPE_DOUBLE_TWIST;
            sensor = COMMS_SENSOR_DOUBLE_TWIST;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TAP):
            type = SENSOR_TYPE_DOUBLE_TAP;
            sensor = COMMS_SENSOR_DOUBLE_TAP;
            three = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_WRIST_TILT):
            type = SENSOR_TYPE_WRIST_TILT_GESTURE;
            sensor = COMMS_SENSOR_WRIST_TILT;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TOUCH):
            type = SENSOR_TYPE_DOUBLE_TOUCH;
            sensor = COMMS_SENSOR_DOUBLE_TOUCH;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_GAZE):
            type = SENSOR_TYPE_GAZE;
            sensor = COMMS_SENSOR_GAZE;
            one = true;
            break;
        case SENS_TYPE_TO_EVENT(SENS_TYPE_UNGAZE):
            type = SENSOR_TYPE_UNGAZE;
            sensor = COMMS_SENSOR_UNGAZE;
            one = true;
            break;
        case EVT_RESET_REASON:
            uint32_t resetReason;
            memcpy(&resetReason, data->buffer, sizeof(resetReason));
            ALOGI("Observed hub reset: 0x%08" PRIx32, resetReason);
            restoreSensorState();
            return 0;
        default:
            ALOGW("unknown evtType: 0x%08x len: %zu\n", data->evtType, len);
            return -1;
        }
    } else {
        ALOGW("too little data: len=%zu\n", len);
        return -1;
    }

    if (len >= sizeof(data->evtType) + sizeof(data->referenceTime) + sizeof(data->firstSample)) {
        ret += sizeof(data->referenceTime);
        timestamp = data->referenceTime;
        numSamples = data->firstSample.numSamples;
        for (i=0; i<numSamples; i++) {
            if (data->firstSample.biasPresent && data->firstSample.biasSample == i)
                currSensor = bias;
            else
                currSensor = sensor;

            if (one) {
                if (ret + sizeof(data->oneSamples[i]) > len) {
                    ALOGW("sensor %d (one): ret=%zd, numSamples=%d, i=%d\n", currSensor, ret, numSamples, i);
                    return -1;
                }
                if (i > 0)
                    timestamp += ((uint64_t)data->oneSamples[i].deltaTime) << delta_time_shift_table[data->oneSamples[i].deltaTime & delta_time_encoded];
                processSample(timestamp, type, currSensor, &data->oneSamples[i], data->firstSample.highAccuracy);
                ret += sizeof(data->oneSamples[i]);
            } else if (rawThree) {
                if (ret + sizeof(data->rawThreeSamples[i]) > len) {
                    ALOGW("sensor %d (rawThree): ret=%zd, numSamples=%d, i=%d\n", currSensor, ret, numSamples, i);
                    return -1;
                }
                if (i > 0)
                    timestamp += ((uint64_t)data->rawThreeSamples[i].deltaTime) << delta_time_shift_table[data->rawThreeSamples[i].deltaTime & delta_time_encoded];
                processSample(timestamp, type, currSensor, &data->rawThreeSamples[i], data->firstSample.highAccuracy);
                ret += sizeof(data->rawThreeSamples[i]);
            } else if (three) {
                if (ret + sizeof(data->threeSamples[i]) > len) {
                    ALOGW("sensor %d (three): ret=%zd, numSamples=%d, i=%d\n", currSensor, ret, numSamples, i);
                    return -1;
                }
                if (i > 0)
                    timestamp += ((uint64_t)data->threeSamples[i].deltaTime) << delta_time_shift_table[data->threeSamples[i].deltaTime & delta_time_encoded];
                processSample(timestamp, type, currSensor, &data->threeSamples[i], data->firstSample.highAccuracy);
                ret += sizeof(data->threeSamples[i]);
            } else {
                ALOGW("sensor %d (unknown): cannot processSample\n", currSensor);
                return -1;
            }
        }

        if (!numSamples)
            ret += sizeof(data->firstSample);

        // If no primary sensor type is specified,
        // then 'sensor' is the primary sensor type.
        primary = mSensorState[sensor].primary;
        primary = (primary ? primary : sensor);

        for (i=0; i<data->firstSample.numFlushes; i++) {
            bool internal = false;

            {
                Mutex::Autolock autoLock(mLock);
                struct Flush& flush = mFlushesPending[primary].front();
                memset(&ev, 0x00, sizeof(sensors_event_t));
                ev.version = META_DATA_VERSION;
                ev.timestamp = 0;
                ev.type = SENSOR_TYPE_META_DATA;
                ev.sensor = 0;
                ev.meta_data.what = META_DATA_FLUSH_COMPLETE;
                ev.meta_data.sensor = flush.handle;

                if (flush.internal) {
                    internal = true;
                    if (flush.handle == COMMS_SENSOR_ACCEL_WRIST_AWARE)
                        mLefty.accel = !mLefty.accel;
                    else if (flush.handle == COMMS_SENSOR_GYRO_WRIST_AWARE)
                        mLefty.gyro = !mLefty.gyro;
                }

                if (--flush.count == 0)
                    mFlushesPending[primary].pop_front();
            }

            if (!internal)
                write(&ev, 1);

            ALOGV("flushing %d", ev.meta_data.sensor);
        }
    } else {
        ALOGW("too little data for sensor %d: len=%zu\n", sensor, len);
        return -1;
    }

    return ret;
}

void HubConnection::sendCalibrationOffsets()
{
    sp<JSONObject> settings;
    sp<JSONObject> saved_settings;
    struct {
        int32_t hw[3];
        float sw[3];
    } accel;

    int32_t proximity, proximity_array[4];
    float barometer, humidity, light;
    bool accel_hw_cal_exists, accel_sw_cal_exists;

    loadSensorSettings(&settings, &saved_settings);

    accel_hw_cal_exists = getCalibrationInt32(settings, ACCEL_BIAS_TAG, accel.hw, 3);
    accel_sw_cal_exists = getCalibrationFloat(saved_settings, ACCEL_SW_BIAS_TAG, accel.sw);
    if (accel_hw_cal_exists || accel_sw_cal_exists) {
        // Store SW bias so we can remove bias for uncal data
        mAccelBias[0] = accel.sw[0];
        mAccelBias[1] = accel.sw[1];
        mAccelBias[2] = accel.sw[2];

        queueDataInternal(COMMS_SENSOR_ACCEL, &accel, sizeof(accel));
    }

    ALOGV("Use new configuration format");
    std::vector<int32_t> hardwareGyroBias = getInt32Setting(settings, GYRO_BIAS_TAG);
    std::vector<float> softwareGyroBias = getFloatSetting(saved_settings, GYRO_SW_BIAS_TAG);
    if (hardwareGyroBias.size() == 3 || softwareGyroBias.size() == 3) {
        struct {
            AppToSensorHalDataPayload header;
            GyroCalBias data;
        } packet = {
            .header = {
                .size = sizeof(GyroCalBias),
                .type = HALINTF_TYPE_GYRO_CAL_BIAS }
        };
        if (hardwareGyroBias.size() == 3) {
            std::copy(hardwareGyroBias.begin(), hardwareGyroBias.end(),
                      packet.data.hardwareBias);
        }
        if (softwareGyroBias.size() == 3) {
            // Store SW bias so we can remove bias for uncal data
            std::copy(softwareGyroBias.begin(), softwareGyroBias.end(),
                      mGyroBias);

            std::copy(softwareGyroBias.begin(), softwareGyroBias.end(),
                      packet.data.softwareBias);
        }
        // send packet to hub
        queueDataInternal(COMMS_SENSOR_GYRO, &packet, sizeof(packet));
    }

    // over temp cal
    std::vector<float> gyroOtcData = getFloatSetting(saved_settings, GYRO_OTC_DATA_TAG);
    if (gyroOtcData.size() == sizeof(GyroOtcData) / sizeof(float)) {
        std::copy(gyroOtcData.begin(), gyroOtcData.end(),
                  reinterpret_cast<float*>(&mGyroOtcData));
        struct {
            AppToSensorHalDataPayload header;
            GyroOtcData data;
        } packet = {
            .header = {
                .size = sizeof(GyroOtcData),
                .type = HALINTF_TYPE_GYRO_OTC_DATA },
            .data = mGyroOtcData
        };

        // send it to hub
        queueDataInternal(COMMS_SENSOR_GYRO, &packet, sizeof(packet));
    } else {
        ALOGW("Illegal otc_gyro data size = %zu", gyroOtcData.size());
    }

    std::vector<float> magBiasData = getFloatSetting(saved_settings, MAG_BIAS_TAG);
    if (magBiasData.size() == 3) {
        // Store SW bias so we can remove bias for uncal data
        std::copy(magBiasData.begin(), magBiasData.end(), mMagBias);

        struct {
            AppToSensorHalDataPayload header;
            MagCalBias mag;
        } packet = {
            .header = {
                .size = sizeof(MagCalBias),
                .type = HALINTF_TYPE_MAG_CAL_BIAS }
        };
        std::copy(magBiasData.begin(), magBiasData.end(), packet.mag.bias);
        queueDataInternal(COMMS_SENSOR_MAG, &packet, sizeof(packet));
    }

    if (settings->getFloat("barometer", &barometer))
        queueDataInternal(COMMS_SENSOR_PRESSURE, &barometer, sizeof(barometer));

    if (settings->getFloat("humidity", &humidity))
        queueDataInternal(COMMS_SENSOR_HUMIDITY, &humidity, sizeof(humidity));

    if (settings->getInt32("proximity", &proximity))
        queueDataInternal(COMMS_SENSOR_PROXIMITY, &proximity, sizeof(proximity));

    if (getCalibrationInt32(settings, "proximity", proximity_array, 4))
        queueDataInternal(COMMS_SENSOR_PROXIMITY, proximity_array, sizeof(proximity_array));

    if (settings->getFloat("light", &light))
        queueDataInternal(COMMS_SENSOR_LIGHT, &light, sizeof(light));
}

bool HubConnection::threadLoop() {
    ALOGV("threadLoop: starting");

    if (mFd < 0) {
        ALOGW("threadLoop: exiting prematurely: nanohub is unavailable");
        return false;
    }
    waitOnNanohubLock();

    sendCalibrationOffsets();

    while (!Thread::exitPending()) {
        ssize_t ret;

        do {
            ret = poll(mPollFds, mNumPollFds, -1);
        } while (ret < 0 && errno == EINTR);

        if (mInotifyPollIndex >= 0 && mPollFds[mInotifyPollIndex].revents & POLLIN) {
            discardInotifyEvent();
            waitOnNanohubLock();
        }

#ifdef USB_MAG_BIAS_REPORTING_ENABLED
        if (mMagBiasPollIndex >= 0 && mPollFds[mMagBiasPollIndex].revents & POLLERR) {
            // Read from mag bias file
            char buf[16];
            lseek(mPollFds[mMagBiasPollIndex].fd, 0, SEEK_SET);
            ::read(mPollFds[mMagBiasPollIndex].fd, buf, 16);
            float bias = atof(buf);
            mUsbMagBias = bias;
            queueUsbMagBias();
        }
#endif // USB_MAG_BIAS_REPORTING_ENABLED

#ifdef DOUBLE_TOUCH_ENABLED
        if (mDoubleTouchPollIndex >= 0 && mPollFds[mDoubleTouchPollIndex].revents & POLLERR) {
            // Read from double touch file
            char buf[16];
            lseek(mPollFds[mDoubleTouchPollIndex].fd, 0, SEEK_SET);
            ::read(mPollFds[mDoubleTouchPollIndex].fd, buf, 16);
            sensors_event_t gestureEvent;
            initEv(&gestureEvent, elapsedRealtimeNano(), SENSOR_TYPE_PICK_UP_GESTURE, COMMS_SENSOR_GESTURE)->data[0] = 8;
            write(&gestureEvent, 1);
        }
#endif // DOUBLE_TOUCH_ENABLED

        if (mPollFds[0].revents & POLLIN) {
            uint8_t recv[256];
            ssize_t len = ::read(mFd, recv, sizeof(recv));

            if (len >= 0) {
                for (ssize_t offset = 0; offset < len;) {
                    ret = processBuf(recv + offset, len - offset);

                    if (ret > 0)
                        offset += ret;
                    else
                        break;
                }
            } else {
                ALOGW("read -1: errno=%d\n", errno);
            }
        }
    }

    return false;
}

void HubConnection::initConfigCmd(struct ConfigCmd *cmd, int handle)
{
    memset(cmd, 0x00, sizeof(*cmd));

    cmd->evtType = EVT_NO_SENSOR_CONFIG_EVENT;
    cmd->sensorType = mSensorState[handle].sensorType;

    if (mSensorState[handle].enable) {
        cmd->cmd = CONFIG_CMD_ENABLE;
        cmd->rate = mSensorState[handle].rate;
        cmd->latency = mSensorState[handle].latency;
    } else {
        cmd->cmd = CONFIG_CMD_DISABLE;
        // set rate and latency to values that will always be overwritten by the
        // first enabled alt sensor
        cmd->rate = UINT32_C(0);
        cmd->latency = UINT64_MAX;
    }

    for (int i=0; i<MAX_ALTERNATES; ++i) {
        uint8_t alt = mSensorState[handle].alt[i];

        if (alt == COMMS_SENSOR_INVALID) continue;
        if (!mSensorState[alt].enable) continue;

        cmd->cmd = CONFIG_CMD_ENABLE;

        if (mSensorState[alt].rate > cmd->rate) {
            cmd->rate = mSensorState[alt].rate;
        }
        if (mSensorState[alt].latency < cmd->latency) {
            cmd->latency = mSensorState[alt].latency;
        }
    }

    // will be a nop if direct report mode is not enabled
    mergeDirectReportRequest(cmd, handle);
}

void HubConnection::queueActivate(int handle, bool enable)
{
    struct ConfigCmd cmd;
    int ret;

    Mutex::Autolock autoLock(mLock);

    if (isValidHandle(handle)) {
        // disabling accel, so no longer need to use the bias from when
        // accel was first enabled
        if (handle == COMMS_SENSOR_ACCEL && !enable)
            mAccelEnabledBiasStored = false;

        mSensorState[handle].enable = enable;

        initConfigCmd(&cmd, handle);

        ret = sendCmd(&cmd, sizeof(cmd));
        if (ret == sizeof(cmd)) {
            updateSampleRate(handle, enable ? CONFIG_CMD_ENABLE : CONFIG_CMD_DISABLE);
            ALOGV("queueActivate: sensor=%d, handle=%d, enable=%d",
                    cmd.sensorType, handle, enable);
        }
        else
            ALOGW("queueActivate: failed to send command: sensor=%d, handle=%d, enable=%d",
                    cmd.sensorType, handle, enable);
    } else {
        ALOGV("queueActivate: unhandled handle=%d, enable=%d", handle, enable);
    }
}

void HubConnection::queueSetDelay(int handle, nsecs_t sampling_period_ns)
{
    struct ConfigCmd cmd;
    int ret;

    Mutex::Autolock autoLock(mLock);

    if (isValidHandle(handle)) {
        if (sampling_period_ns > 0 &&
                mSensorState[handle].rate != SENSOR_RATE_ONCHANGE &&
                mSensorState[handle].rate != SENSOR_RATE_ONESHOT) {
            mSensorState[handle].rate = period_ns_to_frequency_q10(sampling_period_ns);
        }

        initConfigCmd(&cmd, handle);

        ret = sendCmd(&cmd, sizeof(cmd));
        if (ret == sizeof(cmd))
            ALOGV("queueSetDelay: sensor=%d, handle=%d, period=%" PRId64,
                    cmd.sensorType, handle, sampling_period_ns);
        else
            ALOGW("queueSetDelay: failed to send command: sensor=%d, handle=%d, period=%" PRId64,
                    cmd.sensorType, handle, sampling_period_ns);
    } else {
        ALOGV("queueSetDelay: unhandled handle=%d, period=%" PRId64, handle, sampling_period_ns);
    }
}

void HubConnection::queueBatch(
        int handle,
        nsecs_t sampling_period_ns,
        nsecs_t max_report_latency_ns)
{
    struct ConfigCmd cmd;
    int ret;

    Mutex::Autolock autoLock(mLock);

    if (isValidHandle(handle)) {
        if (sampling_period_ns > 0 &&
                mSensorState[handle].rate != SENSOR_RATE_ONCHANGE &&
                mSensorState[handle].rate != SENSOR_RATE_ONESHOT) {
            mSensorState[handle].rate = period_ns_to_frequency_q10(sampling_period_ns);
        }
        mSensorState[handle].latency = max_report_latency_ns;

        initConfigCmd(&cmd, handle);

        ret = sendCmd(&cmd, sizeof(cmd));
        if (ret == sizeof(cmd)) {
            updateSampleRate(handle, CONFIG_CMD_ENABLE); // batch uses CONFIG_CMD_ENABLE command
            ALOGV("queueBatch: sensor=%d, handle=%d, period=%" PRId64 ", latency=%" PRId64,
                    cmd.sensorType, handle, sampling_period_ns, max_report_latency_ns);
        } else {
            ALOGW("queueBatch: failed to send command: sensor=%d, handle=%d, period=%" PRId64 ", latency=%" PRId64,
                    cmd.sensorType, handle, sampling_period_ns, max_report_latency_ns);
        }
    } else {
        ALOGV("queueBatch: unhandled handle=%d, period=%" PRId64 ", latency=%" PRId64,
                handle, sampling_period_ns, max_report_latency_ns);
    }
}

void HubConnection::queueFlush(int handle)
{
    Mutex::Autolock autoLock(mLock);
    queueFlushInternal(handle, false);
}

void HubConnection::queueFlushInternal(int handle, bool internal)
{
    struct ConfigCmd cmd;
    uint32_t primary;
    int ret;

    if (isValidHandle(handle)) {
        // If no primary sensor type is specified,
        // then 'handle' is the primary sensor type.
        primary = mSensorState[handle].primary;
        primary = (primary ? primary : handle);

        std::list<Flush>& flushList = mFlushesPending[primary];

        if (!flushList.empty() &&
            flushList.back().internal == internal &&
            flushList.back().handle == handle) {
            ++flushList.back().count;
        } else {
            flushList.push_back((struct Flush){handle, 1, internal});
        }

        initConfigCmd(&cmd, handle);
        cmd.cmd = CONFIG_CMD_FLUSH;

        ret = sendCmd(&cmd, sizeof(cmd));
        if (ret == sizeof(cmd)) {
            ALOGV("queueFlush: sensor=%d, handle=%d",
                    cmd.sensorType, handle);
        } else {
            ALOGW("queueFlush: failed to send command: sensor=%d, handle=%d"
                  " with error %s", cmd.sensorType, handle, strerror(errno));
        }
    } else {
        ALOGV("queueFlush: unhandled handle=%d", handle);
    }
}

void HubConnection::queueDataInternal(int handle, void *data, size_t length)
{
    struct ConfigCmd *cmd = (struct ConfigCmd *)malloc(sizeof(struct ConfigCmd) + length);
    size_t ret;

    if (cmd && isValidHandle(handle)) {
        initConfigCmd(cmd, handle);
        memcpy(cmd->data, data, length);
        cmd->cmd = CONFIG_CMD_CFG_DATA;

        ret = sendCmd(cmd, sizeof(*cmd) + length);
        if (ret == sizeof(*cmd) + length)
            ALOGV("queueData: sensor=%d, length=%zu",
                    cmd->sensorType, length);
        else
            ALOGW("queueData: failed to send command: sensor=%d, length=%zu",
                    cmd->sensorType, length);
    } else {
        ALOGV("queueData: unhandled handle=%d", handle);
    }
    free(cmd);
}

void HubConnection::queueData(int handle, void *data, size_t length)
{
    Mutex::Autolock autoLock(mLock);
    queueDataInternal(handle, data, length);
}

void HubConnection::setOperationParameter(const additional_info_event_t &info) {
    switch (info.type) {
        case AINFO_LOCAL_GEOMAGNETIC_FIELD: {
            ALOGV("local geomag field update: strength %fuT, dec %fdeg, inc %fdeg",
                  static_cast<double>(info.data_float[0]),
                  info.data_float[1] * 180 / M_PI,
                  info.data_float[2] * 180 / M_PI);

            struct {
                AppToSensorHalDataPayload header;
                MagLocalField magLocalField;
            } packet = {
                .header = {
                    .size = sizeof(MagLocalField),
                    .type = HALINTF_TYPE_MAG_LOCAL_FIELD },
                .magLocalField = {
                    .strength = info.data_float[0],
                    .declination = info.data_float[1],
                    .inclination = info.data_float[2]}
            };
            queueDataInternal(COMMS_SENSOR_MAG, &packet, sizeof(packet));
            break;
        }
        default:
            break;
    }
}

void HubConnection::initNanohubLock() {
    // Create the lock directory (if it doesn't already exist)
    if (mkdir(NANOHUB_LOCK_DIR, NANOHUB_LOCK_DIR_PERMS) < 0 && errno != EEXIST) {
        ALOGW("Couldn't create Nanohub lock directory: %s", strerror(errno));
        return;
    }

    mInotifyPollIndex = -1;
    int inotifyFd = inotify_init1(IN_NONBLOCK);
    if (inotifyFd < 0) {
        ALOGW("Couldn't initialize inotify: %s", strerror(errno));
    } else if (inotify_add_watch(inotifyFd, NANOHUB_LOCK_DIR, IN_CREATE | IN_DELETE) < 0) {
        ALOGW("Couldn't add inotify watch: %s", strerror(errno));
        close(inotifyFd);
    } else {
        mPollFds[mNumPollFds].fd = inotifyFd;
        mPollFds[mNumPollFds].events = POLLIN;
        mPollFds[mNumPollFds].revents = 0;
        mInotifyPollIndex = mNumPollFds;
        mNumPollFds++;
    }
}

ssize_t HubConnection::read(sensors_event_t *ev, size_t size) {
    ssize_t n = mRing.read(ev, size);

    Mutex::Autolock autoLock(mLock);

    // We log the first failure in write, so only log 2+ errors
    if (mWriteFailures > 1) {
        ALOGW("%s: mRing.write failed %d times",
              __FUNCTION__, mWriteFailures);
        mWriteFailures = 0;
    }

    for (ssize_t i = 0; i < n; i++)
        decrementIfWakeEventLocked(ev[i].sensor);

    return n;
}


ssize_t HubConnection::write(const sensors_event_t *ev, size_t n) {
    ssize_t ret = 0;

    Mutex::Autolock autoLock(mLock);

    for (size_t i=0; i<n; i++) {
        if (mRing.write(&ev[i], 1) == 1) {
            ret++;
            // If event is a wake event, protect it with a wakelock
            protectIfWakeEventLocked(ev[i].sensor);
        } else {
            if (mWriteFailures++ == 0)
                ALOGW("%s: mRing.write failed @ %zu/%zu",
                      __FUNCTION__, i, n);
            break;
        }
    }

    return ret;
}

#ifdef USB_MAG_BIAS_REPORTING_ENABLED
void HubConnection::queueUsbMagBias()
{
    struct MsgCmd *cmd = (struct MsgCmd *)malloc(sizeof(struct MsgCmd) + sizeof(float));
    size_t ret;

    if (cmd) {
        cmd->evtType = EVT_APP_FROM_HOST;
        cmd->msg.appId = APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, APP_ID_APP_BMI160);
        cmd->msg.dataLen = sizeof(float);
        memcpy((float *)(cmd+1), &mUsbMagBias, sizeof(float));

        ret = sendCmd(cmd, sizeof(*cmd) + sizeof(float));
        if (ret == sizeof(*cmd) + sizeof(float))
            ALOGV("queueUsbMagBias: bias=%f\n", mUsbMagBias);
        else
            ALOGW("queueUsbMagBias: failed to send command: bias=%f\n", mUsbMagBias);
        free(cmd);
    }
}
#endif  // USB_MAG_BIAS_REPORTING_ENABLED

#ifdef LID_STATE_REPORTING_ENABLED
status_t HubConnection::initializeUinputNode()
{
    int ret = 0;

    // Open uinput dev node
    mUinputFd = TEMP_FAILURE_RETRY(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
    if (mUinputFd < 0) {
        ALOGW("could not open uinput node: %s", strerror(errno));
        return UNKNOWN_ERROR;
    }

    // Enable SW_LID events
    ret  = TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_EVBIT, EV_SW));
    ret |= TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_EVBIT, EV_SYN));
    ret |= TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_SWBIT, SW_LID));
    if (ret < 0) {
        ALOGW("could not send ioctl to uinput node: %s", strerror(errno));
        return UNKNOWN_ERROR;
    }

    // Create uinput node for SW_LID
    struct uinput_user_dev uidev;
    memset(&uidev, 0, sizeof(uidev));
    snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-folio");
    uidev.id.bustype = BUS_SPI;
    uidev.id.vendor  = 0;
    uidev.id.product = 0;
    uidev.id.version = 0;

    ret = TEMP_FAILURE_RETRY(::write(mUinputFd, &uidev, sizeof(uidev)));
    if (ret < 0) {
        ALOGW("write to uinput node failed: %s", strerror(errno));
        return UNKNOWN_ERROR;
    }

    ret = TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_DEV_CREATE));
    if (ret < 0) {
        ALOGW("could not send ioctl to uinput node: %s", strerror(errno));
        return UNKNOWN_ERROR;
    }

    return OK;
}

void HubConnection::sendFolioEvent(int32_t data) {
    ssize_t ret = 0;
    struct input_event ev;

    memset(&ev, 0, sizeof(ev));

    ev.type = EV_SW;
    ev.code = SW_LID;
    ev.value =  data;
    ret = TEMP_FAILURE_RETRY(::write(mUinputFd, &ev, sizeof(ev)));
    if (ret < 0) {
        ALOGW("write to uinput node failed: %s", strerror(errno));
        return;
    }

    // Force flush with EV_SYN event
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value =  0;
    ret = TEMP_FAILURE_RETRY(::write(mUinputFd, &ev, sizeof(ev)));
    if (ret < 0) {
        ALOGW("write to uinput node failed: %s", strerror(errno));
        return;
    }

    // Set lid state property
    if (property_set(LID_STATE_PROPERTY,
                     (data ? LID_STATE_CLOSED : LID_STATE_OPEN)) < 0) {
        ALOGW("could not set lid_state property");
    }
}
#endif  // LID_STATE_REPORTING_ENABLED

#ifdef DIRECT_REPORT_ENABLED
void HubConnection::sendDirectReportEvent(const sensors_event_t *nev, size_t n) {
    // short circuit to avoid lock operation
    if (n == 0) {
        return;
    }

    // no intention to block sensor delivery thread. when lock is needed ignore
    // the event (this only happens when the channel is reconfiured, so it's ok
    if (mDirectChannelLock.tryLock() == NO_ERROR) {
        while (n--) {
            auto i = mSensorToChannel.find(nev->sensor);
            if (i != mSensorToChannel.end()) {
                for (auto &j : i->second) {
                    if ((uint64_t)nev->timestamp > j.second.lastTimestamp
                            && intervalLargeEnough(
                                nev->timestamp - j.second.lastTimestamp,
                                rateLevelToDeviceSamplingPeriodNs(
                                        nev->sensor, j.second.rateLevel))) {
                        mDirectChannel[j.first]->write(nev);
                        j.second.lastTimestamp = nev->timestamp;
                    }
                }
            }
            ++nev;
        }
        mDirectChannelLock.unlock();
    }
}

void HubConnection::mergeDirectReportRequest(struct ConfigCmd *cmd, int handle) {
    int maxRateLevel = SENSOR_DIRECT_RATE_STOP;

    auto j = mSensorToChannel.find(handle);
    if (j != mSensorToChannel.end()) {
        for (auto &i : j->second) {
            maxRateLevel = std::max(i.second.rateLevel, maxRateLevel);
        }
    }
    for (auto handle : mSensorState[handle].alt) {
        auto j = mSensorToChannel.find(handle);
        if (j != mSensorToChannel.end()) {
            for (auto &i : j->second) {
                maxRateLevel = std::max(i.second.rateLevel, maxRateLevel);
            }
        }
    }

    uint64_t period = rateLevelToDeviceSamplingPeriodNs(handle, maxRateLevel);
    if (period != INT64_MAX) {
        rate_q10_t rate;
        rate = period_ns_to_frequency_q10(period);

        cmd->rate = (rate > cmd->rate || cmd->cmd == CONFIG_CMD_DISABLE) ? rate : cmd->rate;
        cmd->latency = 0;
        cmd->cmd = CONFIG_CMD_ENABLE;
    }
}

int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *mem) {
    std::unique_ptr<DirectChannelBase> ch;
    int ret = NO_MEMORY;

    Mutex::Autolock autoLock(mDirectChannelLock);
    for (const auto& c : mDirectChannel) {
        if (c.second->memoryMatches(mem)) {
            // cannot reusing same memory
            return BAD_VALUE;
        }
    }
    switch(mem->type) {
        case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
            ch = std::make_unique<AshmemDirectChannel>(mem);
            break;
        case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
            ch = std::make_unique<GrallocDirectChannel>(mem);
            break;
        default:
            ret = INVALID_OPERATION;
    }

    if (ch) {
        if (ch->isValid()) {
            ret = mDirectChannelHandle++;
            mDirectChannel.insert(std::make_pair(ret, std::move(ch)));
        } else {
            ret = ch->getError();
            ALOGW("Direct channel object(type:%d) has error %d upon init", mem->type, ret);
        }
    }

    return ret;
}

int HubConnection::removeDirectChannel(int channel_handle) {
    // make sure no active sensor in this channel
    std::vector<int32_t> activeSensorList;
    stopAllDirectReportOnChannel(channel_handle, &activeSensorList);

    // sensor service is responsible for stop all sensors before remove direct
    // channel. Thus, this is an error.
    if (!activeSensorList.empty()) {
        std::stringstream ss;
        std::copy(activeSensorList.begin(), activeSensorList.end(),
                std::ostream_iterator<int32_t>(ss, ","));
        ALOGW("Removing channel %d when sensors (%s) are not stopped.",
                channel_handle, ss.str().c_str());
    }

    // remove the channel record
    Mutex::Autolock autoLock(mDirectChannelLock);
    mDirectChannel.erase(channel_handle);
    return NO_ERROR;
}

int HubConnection::stopAllDirectReportOnChannel(
        int channel_handle, std::vector<int32_t> *activeSensorList) {
    Mutex::Autolock autoLock(mDirectChannelLock);
    if (mDirectChannel.find(channel_handle) == mDirectChannel.end()) {
        return BAD_VALUE;
    }

    std::vector<int32_t> sensorToStop;
    for (auto &it : mSensorToChannel) {
        auto j = it.second.find(channel_handle);
        if (j != it.second.end()) {
            it.second.erase(j);
            if (it.second.empty()) {
                sensorToStop.push_back(it.first);
            }
        }
    }

    if (activeSensorList != nullptr) {
        *activeSensorList = sensorToStop;
    }

    // re-evaluate and send config for all sensor that need to be stopped
    bool ret = true;
    for (auto sensor_handle : sensorToStop) {
        Mutex::Autolock autoLock2(mLock);
        struct ConfigCmd cmd;
        initConfigCmd(&cmd, sensor_handle);

        int result = sendCmd(&cmd, sizeof(cmd));
        ret = ret && (result == sizeof(cmd));
    }
    return ret ? NO_ERROR : BAD_VALUE;
}

int HubConnection::configDirectReport(int sensor_handle, int channel_handle, int rate_level) {
    if (sensor_handle == -1 && rate_level == SENSOR_DIRECT_RATE_STOP) {
        return stopAllDirectReportOnChannel(channel_handle, nullptr);
    }

    if (!isValidHandle(sensor_handle)) {
        return BAD_VALUE;
    }

    // clamp to fast
    if (rate_level > SENSOR_DIRECT_RATE_FAST) {
        rate_level = SENSOR_DIRECT_RATE_FAST;
    }

    // manage direct channel data structure
    Mutex::Autolock autoLock(mDirectChannelLock);
    auto i = mDirectChannel.find(channel_handle);
    if (i == mDirectChannel.end()) {
        return BAD_VALUE;
    }

    auto j = mSensorToChannel.find(sensor_handle);
    if (j == mSensorToChannel.end()) {
        return BAD_VALUE;
    }

    j->second.erase(channel_handle);
    if (rate_level != SENSOR_DIRECT_RATE_STOP) {
        j->second.insert(std::make_pair(channel_handle, (DirectChannelTimingInfo){0, rate_level}));
    }

    Mutex::Autolock autoLock2(mLock);
    struct ConfigCmd cmd;
    initConfigCmd(&cmd, sensor_handle);

    int ret = sendCmd(&cmd, sizeof(cmd));

    if (rate_level == SENSOR_DIRECT_RATE_STOP) {
        ret = NO_ERROR;
    } else {
        ret = (ret == sizeof(cmd)) ? sensor_handle : BAD_VALUE;
    }
    return ret;
}

bool HubConnection::isDirectReportSupported() const {
    return true;
}

void HubConnection::updateSampleRate(int handle, int reason) {
    bool affected = mSensorToChannel.find(handle) != mSensorToChannel.end();
    for (size_t i = 0; i < MAX_ALTERNATES && !affected; ++i) {
        if (mSensorState[handle].alt[i] != COMMS_SENSOR_INVALID) {
            affected |=
                    mSensorToChannel.find(mSensorState[handle].alt[i]) != mSensorToChannel.end();
        }
    }
    if (!affected) {
        return;
    }

    switch (reason) {
        case CONFIG_CMD_ENABLE: {
            constexpr uint64_t PERIOD_800HZ = 1250000;
            uint64_t period_multiplier =
                    (frequency_q10_to_period_ns(mSensorState[handle].rate) + PERIOD_800HZ / 2)
                        / PERIOD_800HZ;
            uint64_t desiredTSample = PERIOD_800HZ;
            while (period_multiplier /= 2) {
                desiredTSample *= 2;
            }
            mSensorState[handle].desiredTSample = desiredTSample;
            ALOGV("DesiredTSample for handle 0x%x set to %" PRIu64, handle, desiredTSample);
            break;
        }
        case CONFIG_CMD_DISABLE:
            mSensorState[handle].desiredTSample = INT64_MAX;
            ALOGV("DesiredTSample 0x%x set to disable", handle);
            break;
        default:
            ALOGW("%s: unexpected reason = %d, no-op", __FUNCTION__, reason);
            break;
    }
}

bool HubConnection::isSampleIntervalSatisfied(int handle, uint64_t timestamp) {
    if (mSensorToChannel.find(handle) == mSensorToChannel.end()) {
        return true;
    }

    if (mSensorState[handle].lastTimestamp >= timestamp
            || mSensorState[handle].desiredTSample == INT64_MAX) {
        return false;
    } else if (intervalLargeEnough(timestamp - mSensorState[handle].lastTimestamp,
                                   mSensorState[handle].desiredTSample)) {
        mSensorState[handle].lastTimestamp = timestamp;
        return true;
    } else {
        return false;
    }
}

uint64_t HubConnection::rateLevelToDeviceSamplingPeriodNs(int handle, int rateLevel) const {
    if (mSensorToChannel.find(handle) == mSensorToChannel.end()) {
        return INT64_MAX;
    }

    switch (rateLevel) {
        case SENSOR_DIRECT_RATE_VERY_FAST:
            [[fallthrough]]; // No sensor support VERY_FAST, fall through
        case SENSOR_DIRECT_RATE_FAST:
            if (handle != COMMS_SENSOR_MAG && handle != COMMS_SENSOR_MAG_UNCALIBRATED) {
                return 2500*1000; // 400Hz
            }
            [[fallthrough]];
        case SENSOR_DIRECT_RATE_NORMAL:
            return 20*1000*1000; // 50 Hz
        default:
            return INT64_MAX;
    }
}
#else // DIRECT_REPORT_ENABLED
// nop functions if feature is turned off
int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *) {
    return INVALID_OPERATION;
}

int HubConnection::removeDirectChannel(int) {
    return INVALID_OPERATION;
}

int HubConnection::configDirectReport(int, int, int) {
    return INVALID_OPERATION;
}

void HubConnection::sendDirectReportEvent(const sensors_event_t *, size_t) {
}

void HubConnection::mergeDirectReportRequest(struct ConfigCmd *, int) {
}

bool HubConnection::isDirectReportSupported() const {
    return false;
}

void HubConnection::updateSampleRate(int, int) {
}

bool HubConnection::isSampleIntervalSatisfied(int, uint64_t) {
    return true;
}
#endif // DIRECT_REPORT_ENABLED

} // namespace android
