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, ¶m) != 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