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 #define LOG_TAG "nanohub" 18 #define LOG_NDEBUG 1 19 20 #include "hubconnection.h" 21 22 // TODO: remove the includes that introduce LIKELY and UNLIKELY (firmware/os/inc/toolchain.h) 23 #undef LIKELY 24 #undef UNLIKELY 25 26 #include "file.h" 27 #include "JSONObject.h" 28 29 #include <errno.h> 30 #include <unistd.h> 31 #include <math.h> 32 #include <inttypes.h> 33 #include <sched.h> 34 #include <sys/inotify.h> 35 36 #include <linux/input.h> 37 #include <linux/uinput.h> 38 39 #include <android/frameworks/schedulerservice/1.0/ISchedulingPolicyService.h> 40 #include <cutils/ashmem.h> 41 #include <cutils/properties.h> 42 #include <hardware_legacy/power.h> 43 #include <media/stagefright/foundation/ADebug.h> 44 #include <utils/Log.h> 45 #include <utils/SystemClock.h> 46 47 #include <algorithm> 48 #include <cmath> 49 #include <sstream> 50 #include <vector> 51 52 #define APP_ID_GET_VENDOR(appid) ((appid) >> 24) 53 #define APP_ID_MAKE(vendor, app) ((((uint64_t)(vendor)) << 24) | ((app) & 0x00FFFFFF)) 54 #define APP_ID_VENDOR_GOOGLE 0x476f6f676cULL // "Googl" 55 #define APP_ID_APP_BMI160 2 56 57 #define SENS_TYPE_TO_EVENT(_sensorType) (EVT_NO_FIRST_SENSOR_EVENT + (_sensorType)) 58 59 #define NANOHUB_FILE_PATH "/dev/nanohub" 60 #define NANOHUB_LOCK_DIR "/data/vendor/sensor/nanohub_lock" 61 #define NANOHUB_LOCK_FILE NANOHUB_LOCK_DIR "/lock" 62 #define MAG_BIAS_FILE_PATH "/sys/class/power_supply/battery/compass_compensation" 63 #define DOUBLE_TOUCH_FILE_PATH "/sys/android_touch/synaptics_rmi4_dsx/wake_event" 64 65 #define NANOHUB_LOCK_DIR_PERMS (S_IRUSR | S_IWUSR | S_IXUSR) 66 67 #define SENSOR_RATE_ONCHANGE 0xFFFFFF01UL 68 #define SENSOR_RATE_ONESHOT 0xFFFFFF02UL 69 70 #define MIN_MAG_SQ (10.0f * 10.0f) 71 #define MAX_MAG_SQ (80.0f * 80.0f) 72 73 #define OS_LOG_EVENT 0x474F4C41 // ascii: ALOG 74 75 #ifdef LID_STATE_REPORTING_ENABLED 76 const char LID_STATE_PROPERTY[] = "sensors.contexthub.lid_state"; 77 const char LID_STATE_UNKNOWN[] = "unknown"; 78 const char LID_STATE_OPEN[] = "open"; 79 const char LID_STATE_CLOSED[] = "closed"; 80 #endif // LID_STATE_REPORTING_ENABLED 81 82 static const uint32_t delta_time_encoded = 1; 83 static const uint32_t delta_time_shift_table[2] = {9, 0}; 84 85 #ifdef USE_SENSORSERVICE_TO_GET_FIFO 86 // TODO(b/35219747): retain sched_fifo before eval is done to avoid 87 // performance regression. 88 const char SCHED_FIFO_PRIOIRTY[] = "sensor.hubconnection.sched_fifo"; 89 #endif 90 91 namespace android { 92 93 // static 94 Mutex HubConnection::sInstanceLock; 95 96 // static 97 HubConnection *HubConnection::sInstance = NULL; 98 99 HubConnection *HubConnection::getInstance() 100 { 101 Mutex::Autolock autoLock(sInstanceLock); 102 if (sInstance == NULL) { 103 sInstance = new HubConnection; 104 } 105 return sInstance; 106 } 107 108 static bool isActivitySensor(int sensorIndex) { 109 return sensorIndex >= COMMS_SENSOR_ACTIVITY_FIRST 110 && sensorIndex <= COMMS_SENSOR_ACTIVITY_LAST; 111 } 112 113 HubConnection::HubConnection() 114 : Thread(false /* canCallJava */), 115 mRing(10 *1024), 116 mActivityEventHandler(NULL), 117 mScaleAccel(1.0f), 118 mScaleMag(1.0f), 119 mStepCounterOffset(0ull), 120 mLastStepCount(0ull) 121 { 122 mMagBias[0] = mMagBias[1] = mMagBias[2] = 0.0f; 123 mMagAccuracy = SENSOR_STATUS_UNRELIABLE; 124 mMagAccuracyRestore = SENSOR_STATUS_UNRELIABLE; 125 mGyroBias[0] = mGyroBias[1] = mGyroBias[2] = 0.0f; 126 mAccelBias[0] = mAccelBias[1] = mAccelBias[2] = 0.0f; 127 memset(&mGyroOtcData, 0, sizeof(mGyroOtcData)); 128 129 memset(&mSensorState, 0x00, sizeof(mSensorState)); 130 mFd = open(NANOHUB_FILE_PATH, O_RDWR); 131 mPollFds[0].fd = mFd; 132 mPollFds[0].events = POLLIN; 133 mPollFds[0].revents = 0; 134 mNumPollFds = 1; 135 136 mWakelockHeld = false; 137 mWakeEventCount = 0; 138 139 initNanohubLock(); 140 141 #ifdef USB_MAG_BIAS_REPORTING_ENABLED 142 mUsbMagBias = 0; 143 mMagBiasPollIndex = -1; 144 int magBiasFd = open(MAG_BIAS_FILE_PATH, O_RDONLY); 145 if (magBiasFd < 0) { 146 ALOGW("Mag bias file open failed: %s", strerror(errno)); 147 } else { 148 mPollFds[mNumPollFds].fd = magBiasFd; 149 mPollFds[mNumPollFds].events = 0; 150 mPollFds[mNumPollFds].revents = 0; 151 mMagBiasPollIndex = mNumPollFds; 152 mNumPollFds++; 153 } 154 #endif // USB_MAG_BIAS_REPORTING_ENABLED 155 156 #ifdef DOUBLE_TOUCH_ENABLED 157 mDoubleTouchPollIndex = -1; 158 int doubleTouchFd = open(DOUBLE_TOUCH_FILE_PATH, O_RDONLY); 159 if (doubleTouchFd < 0) { 160 ALOGW("Double touch file open failed: %s", strerror(errno)); 161 } else { 162 mPollFds[mNumPollFds].fd = doubleTouchFd; 163 mPollFds[mNumPollFds].events = 0; 164 mPollFds[mNumPollFds].revents = 0; 165 mDoubleTouchPollIndex = mNumPollFds; 166 mNumPollFds++; 167 } 168 #endif // DOUBLE_TOUCH_ENABLED 169 170 mSensorState[COMMS_SENSOR_ACCEL].sensorType = SENS_TYPE_ACCEL; 171 mSensorState[COMMS_SENSOR_ACCEL].alt = COMMS_SENSOR_ACCEL_UNCALIBRATED; 172 mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].sensorType = SENS_TYPE_ACCEL; 173 mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].alt = COMMS_SENSOR_ACCEL; 174 mSensorState[COMMS_SENSOR_GYRO].sensorType = SENS_TYPE_GYRO; 175 mSensorState[COMMS_SENSOR_GYRO].alt = COMMS_SENSOR_GYRO_UNCALIBRATED; 176 mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].sensorType = SENS_TYPE_GYRO; 177 mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].alt = COMMS_SENSOR_GYRO; 178 mSensorState[COMMS_SENSOR_MAG].sensorType = SENS_TYPE_MAG; 179 mSensorState[COMMS_SENSOR_MAG].alt = COMMS_SENSOR_MAG_UNCALIBRATED; 180 mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].sensorType = SENS_TYPE_MAG; 181 mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].alt = COMMS_SENSOR_MAG; 182 mSensorState[COMMS_SENSOR_LIGHT].sensorType = SENS_TYPE_ALS; 183 mSensorState[COMMS_SENSOR_PROXIMITY].sensorType = SENS_TYPE_PROX; 184 mSensorState[COMMS_SENSOR_PRESSURE].sensorType = SENS_TYPE_BARO; 185 mSensorState[COMMS_SENSOR_TEMPERATURE].sensorType = SENS_TYPE_TEMP; 186 mSensorState[COMMS_SENSOR_ORIENTATION].sensorType = SENS_TYPE_ORIENTATION; 187 mSensorState[COMMS_SENSOR_WINDOW_ORIENTATION].sensorType = SENS_TYPE_WIN_ORIENTATION; 188 mSensorState[COMMS_SENSOR_WINDOW_ORIENTATION].rate = SENSOR_RATE_ONCHANGE; 189 mSensorState[COMMS_SENSOR_STEP_DETECTOR].sensorType = SENS_TYPE_STEP_DETECT; 190 mSensorState[COMMS_SENSOR_STEP_DETECTOR].rate = SENSOR_RATE_ONCHANGE; 191 mSensorState[COMMS_SENSOR_STEP_COUNTER].sensorType = SENS_TYPE_STEP_COUNT; 192 mSensorState[COMMS_SENSOR_SIGNIFICANT_MOTION].sensorType = SENS_TYPE_SIG_MOTION; 193 mSensorState[COMMS_SENSOR_SIGNIFICANT_MOTION].rate = SENSOR_RATE_ONESHOT; 194 mSensorState[COMMS_SENSOR_GRAVITY].sensorType = SENS_TYPE_GRAVITY; 195 mSensorState[COMMS_SENSOR_LINEAR_ACCEL].sensorType = SENS_TYPE_LINEAR_ACCEL; 196 mSensorState[COMMS_SENSOR_ROTATION_VECTOR].sensorType = SENS_TYPE_ROTATION_VECTOR; 197 mSensorState[COMMS_SENSOR_GEO_MAG].sensorType = SENS_TYPE_GEO_MAG_ROT_VEC; 198 mSensorState[COMMS_SENSOR_GAME_ROTATION_VECTOR].sensorType = SENS_TYPE_GAME_ROT_VECTOR; 199 mSensorState[COMMS_SENSOR_HALL].sensorType = SENS_TYPE_HALL; 200 mSensorState[COMMS_SENSOR_HALL].rate = SENSOR_RATE_ONCHANGE; 201 mSensorState[COMMS_SENSOR_SYNC].sensorType = SENS_TYPE_VSYNC; 202 mSensorState[COMMS_SENSOR_SYNC].rate = SENSOR_RATE_ONCHANGE; 203 mSensorState[COMMS_SENSOR_TILT].sensorType = SENS_TYPE_TILT; 204 mSensorState[COMMS_SENSOR_TILT].rate = SENSOR_RATE_ONCHANGE; 205 mSensorState[COMMS_SENSOR_GESTURE].sensorType = SENS_TYPE_GESTURE; 206 mSensorState[COMMS_SENSOR_GESTURE].rate = SENSOR_RATE_ONESHOT; 207 mSensorState[COMMS_SENSOR_DOUBLE_TWIST].sensorType = SENS_TYPE_DOUBLE_TWIST; 208 mSensorState[COMMS_SENSOR_DOUBLE_TWIST].rate = SENSOR_RATE_ONCHANGE; 209 mSensorState[COMMS_SENSOR_DOUBLE_TAP].sensorType = SENS_TYPE_DOUBLE_TAP; 210 mSensorState[COMMS_SENSOR_DOUBLE_TAP].rate = SENSOR_RATE_ONCHANGE; 211 mSensorState[COMMS_SENSOR_WRIST_TILT].sensorType = SENS_TYPE_WRIST_TILT; 212 mSensorState[COMMS_SENSOR_WRIST_TILT].rate = SENSOR_RATE_ONCHANGE; 213 mSensorState[COMMS_SENSOR_DOUBLE_TOUCH].sensorType = SENS_TYPE_DOUBLE_TOUCH; 214 mSensorState[COMMS_SENSOR_DOUBLE_TOUCH].rate = SENSOR_RATE_ONESHOT; 215 mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_START].sensorType = SENS_TYPE_ACTIVITY_IN_VEHICLE_START; 216 mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_START].rate = SENSOR_RATE_ONCHANGE; 217 mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_STOP].sensorType = SENS_TYPE_ACTIVITY_IN_VEHICLE_STOP; 218 mSensorState[COMMS_SENSOR_ACTIVITY_IN_VEHICLE_STOP].rate = SENSOR_RATE_ONCHANGE; 219 mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_START].sensorType = SENS_TYPE_ACTIVITY_ON_BICYCLE_START; 220 mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_START].rate = SENSOR_RATE_ONCHANGE; 221 mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_STOP].sensorType = SENS_TYPE_ACTIVITY_ON_BICYCLE_STOP; 222 mSensorState[COMMS_SENSOR_ACTIVITY_ON_BICYCLE_STOP].rate = SENSOR_RATE_ONCHANGE; 223 mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_START].sensorType = SENS_TYPE_ACTIVITY_WALKING_START; 224 mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_START].rate = SENSOR_RATE_ONCHANGE; 225 mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_STOP].sensorType = SENS_TYPE_ACTIVITY_WALKING_STOP; 226 mSensorState[COMMS_SENSOR_ACTIVITY_WALKING_STOP].rate = SENSOR_RATE_ONCHANGE; 227 mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_START].sensorType = SENS_TYPE_ACTIVITY_RUNNING_START; 228 mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_START].rate = SENSOR_RATE_ONCHANGE; 229 mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_STOP].sensorType = SENS_TYPE_ACTIVITY_RUNNING_STOP; 230 mSensorState[COMMS_SENSOR_ACTIVITY_RUNNING_STOP].rate = SENSOR_RATE_ONCHANGE; 231 mSensorState[COMMS_SENSOR_ACTIVITY_STILL_START].sensorType = SENS_TYPE_ACTIVITY_STILL_START; 232 mSensorState[COMMS_SENSOR_ACTIVITY_STILL_START].rate = SENSOR_RATE_ONCHANGE; 233 mSensorState[COMMS_SENSOR_ACTIVITY_STILL_STOP].sensorType = SENS_TYPE_ACTIVITY_STILL_STOP; 234 mSensorState[COMMS_SENSOR_ACTIVITY_STILL_STOP].rate = SENSOR_RATE_ONCHANGE; 235 mSensorState[COMMS_SENSOR_ACTIVITY_TILTING].sensorType = SENS_TYPE_ACTIVITY_TILTING; 236 mSensorState[COMMS_SENSOR_ACTIVITY_TILTING].rate = SENSOR_RATE_ONCHANGE; 237 mSensorState[COMMS_SENSOR_GAZE].sensorType = SENS_TYPE_GAZE; 238 mSensorState[COMMS_SENSOR_GAZE].rate = SENSOR_RATE_ONESHOT; 239 mSensorState[COMMS_SENSOR_UNGAZE].sensorType = SENS_TYPE_UNGAZE; 240 mSensorState[COMMS_SENSOR_UNGAZE].rate = SENSOR_RATE_ONESHOT; 241 mSensorState[COMMS_SENSOR_HUMIDITY].sensorType = SENS_TYPE_HUMIDITY; 242 243 #ifdef LID_STATE_REPORTING_ENABLED 244 initializeUinputNode(); 245 246 // set initial lid state 247 if (property_set(LID_STATE_PROPERTY, LID_STATE_UNKNOWN) < 0) { 248 ALOGW("could not set lid_state property"); 249 } 250 251 // enable hall sensor for folio 252 if (mFd >= 0) { 253 queueActivate(COMMS_SENSOR_HALL, true /* enable */); 254 } 255 #endif // LID_STATE_REPORTING_ENABLED 256 257 #ifdef DIRECT_REPORT_ENABLED 258 mDirectChannelHandle = 1; 259 mSensorToChannel.emplace(COMMS_SENSOR_ACCEL, std::unordered_map<int32_t, int32_t>()); 260 mSensorToChannel.emplace(COMMS_SENSOR_GYRO, std::unordered_map<int32_t, int32_t>()); 261 mSensorToChannel.emplace(COMMS_SENSOR_MAG, std::unordered_map<int32_t, int32_t>()); 262 #endif // DIRECT_REPORT_ENABLED 263 } 264 265 HubConnection::~HubConnection() 266 { 267 close(mFd); 268 } 269 270 void HubConnection::onFirstRef() 271 { 272 run("HubConnection", PRIORITY_URGENT_DISPLAY); 273 #ifdef USE_SENSORSERVICE_TO_GET_FIFO 274 if (property_get_bool(SCHED_FIFO_PRIOIRTY, true)) { 275 ALOGV("Try activate sched-fifo priority for HubConnection thread"); 276 mEnableSchedFifoThread = std::thread(enableSchedFifoMode, this); 277 } 278 #else 279 enableSchedFifoMode(this); 280 #endif 281 } 282 283 // Set main thread to SCHED_FIFO to lower sensor event latency when system is under load 284 void HubConnection::enableSchedFifoMode(sp<HubConnection> hub) { 285 #ifdef USE_SENSORSERVICE_TO_GET_FIFO 286 using ::android::frameworks::schedulerservice::V1_0::ISchedulingPolicyService; 287 using ::android::hardware::Return; 288 289 // SchedulingPolicyService will not start until system server start. 290 // Thus, cannot block on this. 291 sp<ISchedulingPolicyService> scheduler = ISchedulingPolicyService::getService(); 292 293 if (scheduler == nullptr) { 294 ALOGW("Couldn't get scheduler scheduler to set SCHED_FIFO."); 295 } else { 296 Return<int32_t> max = scheduler->getMaxAllowedPriority(); 297 if (!max.isOk()) { 298 ALOGW("Failed to retrieve maximum allowed priority for HubConnection."); 299 return; 300 } 301 Return<bool> ret = scheduler->requestPriority(::getpid(), hub->getTid(), max); 302 if (!ret.isOk() || !ret) { 303 ALOGW("Failed to set SCHED_FIFO for HubConnection."); 304 } else { 305 ALOGV("Enabled sched fifo thread mode (prio %d)", static_cast<int32_t>(max)); 306 } 307 } 308 #else 309 #define HUBCONNECTION_SCHED_FIFO_PRIORITY 10 310 struct sched_param param = {0}; 311 param.sched_priority = HUBCONNECTION_SCHED_FIFO_PRIORITY; 312 if (sched_setscheduler(hub->getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) { 313 ALOGW("Couldn't set SCHED_FIFO for HubConnection thread"); 314 } 315 #endif 316 } 317 318 status_t HubConnection::initCheck() const 319 { 320 return mFd < 0 ? UNKNOWN_ERROR : OK; 321 } 322 323 status_t HubConnection::getAliveCheck() 324 { 325 return OK; 326 } 327 328 static sp<JSONObject> readSettings(File *file) { 329 off64_t size = file->seekTo(0, SEEK_END); 330 file->seekTo(0, SEEK_SET); 331 332 sp<JSONObject> root; 333 334 if (size > 0) { 335 char *buf = (char *)malloc(size); 336 CHECK_EQ(file->read(buf, size), (ssize_t)size); 337 file->seekTo(0, SEEK_SET); 338 339 sp<JSONCompound> in = JSONCompound::Parse(buf, size); 340 free(buf); 341 buf = NULL; 342 343 if (in != NULL && in->isObject()) { 344 root = (JSONObject *)in.get(); 345 } 346 } 347 348 if (root == NULL) { 349 root = new JSONObject; 350 } 351 352 return root; 353 } 354 355 static bool getCalibrationInt32( 356 const sp<JSONObject> &settings, const char *key, int32_t *out, 357 size_t numArgs) { 358 sp<JSONArray> array; 359 for (size_t i = 0; i < numArgs; i++) { 360 out[i] = 0; 361 } 362 if (!settings->getArray(key, &array)) { 363 return false; 364 } else { 365 for (size_t i = 0; i < numArgs; i++) { 366 if (!array->getInt32(i, &out[i])) { 367 return false; 368 } 369 } 370 } 371 return true; 372 } 373 374 static bool getCalibrationFloat( 375 const sp<JSONObject> &settings, const char *key, float out[3]) { 376 sp<JSONArray> array; 377 for (size_t i = 0; i < 3; i++) { 378 out[i] = 0.0f; 379 } 380 if (!settings->getArray(key, &array)) { 381 return false; 382 } else { 383 for (size_t i = 0; i < 3; i++) { 384 if (!array->getFloat(i, &out[i])) { 385 return false; 386 } 387 } 388 } 389 return true; 390 } 391 392 static std::vector<int32_t> getInt32Setting(const sp<JSONObject> &settings, const char *key) { 393 std::vector<int32_t> ret; 394 395 sp<JSONArray> array; 396 if (settings->getArray(key, &array)) { 397 ret.resize(array->size()); 398 for (size_t i = 0; i < array->size(); ++i) { 399 array->getInt32(i, &ret[i]); 400 } 401 } 402 return ret; 403 } 404 405 static std::vector<float> getFloatSetting(const sp<JSONObject> &settings, const char *key) { 406 std::vector<float> ret; 407 408 sp<JSONArray> array; 409 if (settings->getArray(key, &array)) { 410 ret.resize(array->size()); 411 for (size_t i = 0; i < array->size(); ++i) { 412 array->getFloat(i, &ret[i]); 413 } 414 } 415 return ret; 416 } 417 418 static void loadSensorSettings(sp<JSONObject>* settings, 419 sp<JSONObject>* saved_settings) { 420 File settings_file(CONTEXTHUB_SETTINGS_PATH, "r"); 421 File saved_settings_file(CONTEXTHUB_SAVED_SETTINGS_PATH, "r"); 422 423 status_t err; 424 if ((err = settings_file.initCheck()) != OK) { 425 ALOGW("settings file open failed: %d (%s)", 426 err, 427 strerror(-err)); 428 429 *settings = new JSONObject; 430 } else { 431 *settings = readSettings(&settings_file); 432 } 433 434 if ((err = saved_settings_file.initCheck()) != OK) { 435 ALOGW("saved settings file open failed: %d (%s)", 436 err, 437 strerror(-err)); 438 *saved_settings = new JSONObject; 439 } else { 440 *saved_settings = readSettings(&saved_settings_file); 441 } 442 } 443 444 void HubConnection::saveSensorSettings() const { 445 File saved_settings_file(CONTEXTHUB_SAVED_SETTINGS_PATH, "w"); 446 sp<JSONObject> settingsObject = new JSONObject; 447 448 status_t err; 449 if ((err = saved_settings_file.initCheck()) != OK) { 450 ALOGW("saved settings file open failed %d (%s)", 451 err, 452 strerror(-err)); 453 return; 454 } 455 456 // Build a settings object. 457 sp<JSONArray> magArray = new JSONArray; 458 #ifdef USB_MAG_BIAS_REPORTING_ENABLED 459 magArray->addFloat(mMagBias[0] + mUsbMagBias); 460 #else 461 magArray->addFloat(mMagBias[0]); 462 #endif // USB_MAG_BIAS_REPORTING_ENABLED 463 magArray->addFloat(mMagBias[1]); 464 magArray->addFloat(mMagBias[2]); 465 settingsObject->setArray(MAG_BIAS_TAG, magArray); 466 467 // Add gyro settings 468 sp<JSONArray> gyroArray = new JSONArray; 469 gyroArray->addFloat(mGyroBias[0]); 470 gyroArray->addFloat(mGyroBias[1]); 471 gyroArray->addFloat(mGyroBias[2]); 472 settingsObject->setArray(GYRO_SW_BIAS_TAG, gyroArray); 473 474 // Add accel settings 475 sp<JSONArray> accelArray = new JSONArray; 476 accelArray->addFloat(mAccelBias[0]); 477 accelArray->addFloat(mAccelBias[1]); 478 accelArray->addFloat(mAccelBias[2]); 479 settingsObject->setArray(ACCEL_SW_BIAS_TAG, accelArray); 480 481 // Add overtemp calibration values for gyro 482 sp<JSONArray> gyroOtcDataArray = new JSONArray; 483 const float *f; 484 size_t i; 485 for (f = reinterpret_cast<const float *>(&mGyroOtcData), i = 0; 486 i < sizeof(mGyroOtcData)/sizeof(float); ++i, ++f) { 487 gyroOtcDataArray->addFloat(*f); 488 } 489 settingsObject->setArray(GYRO_OTC_DATA_TAG, gyroOtcDataArray); 490 491 // Write the JSON string to disk. 492 AString serializedSettings = settingsObject->toString(); 493 size_t size = serializedSettings.size(); 494 if ((err = saved_settings_file.write(serializedSettings.c_str(), size)) != (ssize_t)size) { 495 ALOGW("saved settings file write failed %d (%s)", 496 err, 497 strerror(-err)); 498 } 499 } 500 501 sensors_event_t *HubConnection::initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor) 502 { 503 memset(ev, 0x00, sizeof(sensors_event_t)); 504 ev->version = sizeof(sensors_event_t); 505 ev->timestamp = timestamp; 506 ev->type = type; 507 ev->sensor = sensor; 508 509 return ev; 510 } 511 512 ssize_t HubConnection::getWakeEventCount() 513 { 514 return mWakeEventCount; 515 } 516 517 ssize_t HubConnection::decrementWakeEventCount() 518 { 519 return --mWakeEventCount; 520 } 521 522 bool HubConnection::isWakeEvent(int32_t sensor) 523 { 524 switch (sensor) { 525 case COMMS_SENSOR_PROXIMITY: 526 case COMMS_SENSOR_SIGNIFICANT_MOTION: 527 case COMMS_SENSOR_TILT: 528 case COMMS_SENSOR_DOUBLE_TWIST: 529 case COMMS_SENSOR_GESTURE: 530 return true; 531 default: 532 return false; 533 } 534 } 535 536 void HubConnection::protectIfWakeEvent(int32_t sensor) 537 { 538 if (isWakeEvent(sensor)) { 539 if (mWakelockHeld == false) { 540 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKELOCK_NAME); 541 mWakelockHeld = true; 542 } 543 mWakeEventCount++; 544 } 545 } 546 547 void HubConnection::releaseWakeLockIfAppropriate() 548 { 549 if (mWakelockHeld && (mWakeEventCount == 0)) { 550 mWakelockHeld = false; 551 release_wake_lock(WAKELOCK_NAME); 552 } 553 } 554 555 void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, __attribute__((unused)) bool highAccuracy) 556 { 557 sensors_event_t nev[1]; 558 int cnt = 0; 559 560 switch (sensor) { 561 case COMMS_SENSOR_ACTIVITY_IN_VEHICLE_START: 562 case COMMS_SENSOR_ACTIVITY_IN_VEHICLE_STOP: 563 case COMMS_SENSOR_ACTIVITY_ON_BICYCLE_START: 564 case COMMS_SENSOR_ACTIVITY_ON_BICYCLE_STOP: 565 case COMMS_SENSOR_ACTIVITY_WALKING_START: 566 case COMMS_SENSOR_ACTIVITY_WALKING_STOP: 567 case COMMS_SENSOR_ACTIVITY_RUNNING_START: 568 case COMMS_SENSOR_ACTIVITY_RUNNING_STOP: 569 case COMMS_SENSOR_ACTIVITY_STILL_START: 570 case COMMS_SENSOR_ACTIVITY_STILL_STOP: 571 case COMMS_SENSOR_ACTIVITY_TILTING: 572 if (mActivityEventHandler != NULL) { 573 mActivityEventHandler->OnActivityEvent(sensor, sample->idata & 0xff, 574 timestamp); 575 } 576 break; 577 case COMMS_SENSOR_PRESSURE: 578 initEv(&nev[cnt++], timestamp, type, sensor)->pressure = sample->fdata; 579 break; 580 case COMMS_SENSOR_HUMIDITY: 581 initEv(&nev[cnt++], timestamp, type, sensor)->relative_humidity = sample->fdata; 582 break; 583 case COMMS_SENSOR_TEMPERATURE: 584 initEv(&nev[cnt++], timestamp, type, sensor)->temperature = sample->fdata; 585 break; 586 case COMMS_SENSOR_PROXIMITY: 587 initEv(&nev[cnt++], timestamp, type, sensor)->distance = sample->fdata; 588 break; 589 case COMMS_SENSOR_LIGHT: 590 initEv(&nev[cnt++], timestamp, type, sensor)->light = sample->fdata; 591 break; 592 case COMMS_SENSOR_STEP_COUNTER: 593 // We'll stash away the last step count in case we need to reset 594 // the hub. This last step count would then become the new offset. 595 mLastStepCount = mStepCounterOffset + sample->idata; 596 initEv(&nev[cnt++], timestamp, type, sensor)->u64.step_counter = mLastStepCount; 597 break; 598 case COMMS_SENSOR_STEP_DETECTOR: 599 case COMMS_SENSOR_SIGNIFICANT_MOTION: 600 case COMMS_SENSOR_TILT: 601 case COMMS_SENSOR_DOUBLE_TWIST: 602 case COMMS_SENSOR_WRIST_TILT: 603 initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = 1.0f; 604 break; 605 case COMMS_SENSOR_GAZE: 606 case COMMS_SENSOR_UNGAZE: 607 case COMMS_SENSOR_GESTURE: 608 case COMMS_SENSOR_SYNC: 609 case COMMS_SENSOR_DOUBLE_TOUCH: 610 initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = sample->idata; 611 break; 612 case COMMS_SENSOR_HALL: 613 #ifdef LID_STATE_REPORTING_ENABLED 614 sendFolioEvent(sample->idata); 615 #endif // LID_STATE_REPORTING_ENABLED 616 break; 617 case COMMS_SENSOR_WINDOW_ORIENTATION: 618 initEv(&nev[cnt++], timestamp, type, sensor)->data[0] = sample->idata; 619 break; 620 default: 621 break; 622 } 623 624 if (cnt > 0) { 625 // If event is a wake event, protect it with a wakelock 626 protectIfWakeEvent(sensor); 627 write(nev, cnt); 628 } 629 } 630 631 uint8_t HubConnection::magAccuracyUpdate(sensors_vec_t *sv) 632 { 633 float magSq = sv->x * sv->x + sv->y * sv->y + sv->z * sv->z; 634 635 if (magSq < MIN_MAG_SQ || magSq > MAX_MAG_SQ) { 636 // save last good accuracy (either MEDIUM or HIGH) 637 if (mMagAccuracy != SENSOR_STATUS_UNRELIABLE) 638 mMagAccuracyRestore = mMagAccuracy; 639 mMagAccuracy = SENSOR_STATUS_UNRELIABLE; 640 } else if (mMagAccuracy == SENSOR_STATUS_UNRELIABLE) { 641 // restore 642 mMagAccuracy = mMagAccuracyRestore; 643 } 644 645 return mMagAccuracy; 646 } 647 648 void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, __attribute__((unused)) bool highAccuracy) 649 { 650 sensors_vec_t *sv; 651 uncalibrated_event_t *ue; 652 sensors_event_t nev[2]; 653 int cnt = 0; 654 655 switch (sensor) { 656 case COMMS_SENSOR_ACCEL: 657 sv = &initEv(&nev[cnt], timestamp, type, sensor)->acceleration; 658 sv->x = sample->ix * mScaleAccel; 659 sv->y = sample->iy * mScaleAccel; 660 sv->z = sample->iz * mScaleAccel; 661 sv->status = SENSOR_STATUS_ACCURACY_HIGH; 662 sendDirectReportEvent(&nev[cnt], 1); 663 664 if (mSensorState[sensor].enable) { 665 ++cnt; 666 } 667 668 if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable) { 669 ue = &initEv(&nev[cnt++], timestamp, 670 SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, 671 COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer; 672 ue->x_uncalib = sample->ix * mScaleAccel + mAccelBias[0]; 673 ue->y_uncalib = sample->iy * mScaleAccel + mAccelBias[1]; 674 ue->z_uncalib = sample->iz * mScaleAccel + mAccelBias[2]; 675 ue->x_bias = mAccelBias[0]; 676 ue->y_bias = mAccelBias[1]; 677 ue->z_bias = mAccelBias[2]; 678 } 679 break; 680 case COMMS_SENSOR_MAG: 681 sv = &initEv(&nev[cnt], timestamp, type, sensor)->magnetic; 682 sv->x = sample->ix * mScaleMag; 683 sv->y = sample->iy * mScaleMag; 684 sv->z = sample->iz * mScaleMag; 685 sv->status = magAccuracyUpdate(sv); 686 sendDirectReportEvent(&nev[cnt], 1); 687 688 if (mSensorState[sensor].enable) { 689 ++cnt; 690 } 691 692 if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable) { 693 ue = &initEv(&nev[cnt++], timestamp, 694 SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, 695 COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic; 696 ue->x_uncalib = sample->ix * mScaleMag + mMagBias[0]; 697 ue->y_uncalib = sample->iy * mScaleMag + mMagBias[1]; 698 ue->z_uncalib = sample->iz * mScaleMag + mMagBias[2]; 699 ue->x_bias = mMagBias[0]; 700 ue->y_bias = mMagBias[1]; 701 ue->z_bias = mMagBias[2]; 702 } 703 default: 704 break; 705 } 706 707 if (cnt > 0) { 708 // If event is a wake event, protect it with a wakelock 709 protectIfWakeEvent(sensor); 710 write(nev, cnt); 711 } 712 } 713 714 void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy) 715 { 716 sensors_vec_t *sv; 717 uncalibrated_event_t *ue; 718 sensors_event_t *ev; 719 sensors_event_t nev[2]; 720 static const float heading_accuracy = M_PI / 6.0f; 721 float w; 722 int cnt = 0; 723 724 switch (sensor) { 725 case COMMS_SENSOR_ACCEL: 726 sv = &initEv(&nev[cnt], timestamp, type, sensor)->acceleration; 727 sv->x = sample->x; 728 sv->y = sample->y; 729 sv->z = sample->z; 730 sv->status = SENSOR_STATUS_ACCURACY_HIGH; 731 sendDirectReportEvent(&nev[cnt], 1); 732 733 if (mSensorState[sensor].enable) { 734 ++cnt; 735 } 736 737 if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable) { 738 ue = &initEv(&nev[cnt++], timestamp, 739 SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, 740 COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer; 741 ue->x_uncalib = sample->x + mAccelBias[0]; 742 ue->y_uncalib = sample->y + mAccelBias[1]; 743 ue->z_uncalib = sample->z + mAccelBias[2]; 744 ue->x_bias = mAccelBias[0]; 745 ue->y_bias = mAccelBias[1]; 746 ue->z_bias = mAccelBias[2]; 747 } 748 break; 749 case COMMS_SENSOR_GYRO: 750 sv = &initEv(&nev[cnt], timestamp, type, sensor)->gyro; 751 sv->x = sample->x; 752 sv->y = sample->y; 753 sv->z = sample->z; 754 sv->status = SENSOR_STATUS_ACCURACY_HIGH; 755 sendDirectReportEvent(&nev[cnt], 1); 756 757 if (mSensorState[sensor].enable) { 758 ++cnt; 759 } 760 761 if (mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].enable) { 762 ue = &initEv(&nev[cnt++], timestamp, 763 SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, 764 COMMS_SENSOR_GYRO_UNCALIBRATED)->uncalibrated_gyro; 765 ue->x_uncalib = sample->x + mGyroBias[0]; 766 ue->y_uncalib = sample->y + mGyroBias[1]; 767 ue->z_uncalib = sample->z + mGyroBias[2]; 768 ue->x_bias = mGyroBias[0]; 769 ue->y_bias = mGyroBias[1]; 770 ue->z_bias = mGyroBias[2]; 771 } 772 break; 773 case COMMS_SENSOR_ACCEL_BIAS: 774 mAccelBias[0] = sample->x; 775 mAccelBias[1] = sample->y; 776 mAccelBias[2] = sample->z; 777 saveSensorSettings(); 778 break; 779 case COMMS_SENSOR_GYRO_BIAS: 780 mGyroBias[0] = sample->x; 781 mGyroBias[1] = sample->y; 782 mGyroBias[2] = sample->z; 783 saveSensorSettings(); 784 break; 785 case COMMS_SENSOR_MAG: 786 sv = &initEv(&nev[cnt], timestamp, type, sensor)->magnetic; 787 sv->x = sample->x; 788 sv->y = sample->y; 789 sv->z = sample->z; 790 sv->status = magAccuracyUpdate(sv); 791 sendDirectReportEvent(&nev[cnt], 1); 792 793 if (mSensorState[sensor].enable) { 794 ++cnt; 795 } 796 797 if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable) { 798 ue = &initEv(&nev[cnt++], timestamp, 799 SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, 800 COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic; 801 ue->x_uncalib = sample->x + mMagBias[0]; 802 ue->y_uncalib = sample->y + mMagBias[1]; 803 ue->z_uncalib = sample->z + mMagBias[2]; 804 ue->x_bias = mMagBias[0]; 805 ue->y_bias = mMagBias[1]; 806 ue->z_bias = mMagBias[2]; 807 } 808 break; 809 case COMMS_SENSOR_MAG_BIAS: 810 mMagAccuracy = highAccuracy ? SENSOR_STATUS_ACCURACY_HIGH : SENSOR_STATUS_ACCURACY_MEDIUM; 811 mMagBias[0] = sample->x; 812 mMagBias[1] = sample->y; 813 mMagBias[2] = sample->z; 814 815 saveSensorSettings(); 816 break; 817 case COMMS_SENSOR_ORIENTATION: 818 case COMMS_SENSOR_LINEAR_ACCEL: 819 case COMMS_SENSOR_GRAVITY: 820 sv = &initEv(&nev[cnt++], timestamp, type, sensor)->orientation; 821 sv->x = sample->x; 822 sv->y = sample->y; 823 sv->z = sample->z; 824 sv->status = mMagAccuracy; 825 break; 826 case COMMS_SENSOR_DOUBLE_TAP: 827 ev = initEv(&nev[cnt++], timestamp, type, sensor); 828 ev->data[0] = sample->x; 829 ev->data[1] = sample->y; 830 ev->data[2] = sample->z; 831 break; 832 case COMMS_SENSOR_ROTATION_VECTOR: 833 ev = initEv(&nev[cnt++], timestamp, type, sensor); 834 w = sample->x * sample->x + sample->y * sample->y + sample->z * sample->z; 835 if (w < 1.0f) 836 w = sqrt(1.0f - w); 837 else 838 w = 0.0f; 839 ev->data[0] = sample->x; 840 ev->data[1] = sample->y; 841 ev->data[2] = sample->z; 842 ev->data[3] = w; 843 ev->data[4] = (4 - mMagAccuracy) * heading_accuracy; 844 break; 845 case COMMS_SENSOR_GEO_MAG: 846 case COMMS_SENSOR_GAME_ROTATION_VECTOR: 847 ev = initEv(&nev[cnt++], timestamp, type, sensor); 848 w = sample->x * sample->x + sample->y * sample->y + sample->z * sample->z; 849 if (w < 1.0f) 850 w = sqrt(1.0f - w); 851 else 852 w = 0.0f; 853 ev->data[0] = sample->x; 854 ev->data[1] = sample->y; 855 ev->data[2] = sample->z; 856 ev->data[3] = w; 857 break; 858 default: 859 break; 860 } 861 862 if (cnt > 0) { 863 // If event is a wake event, protect it with a wakelock 864 protectIfWakeEvent(sensor); 865 write(nev, cnt); 866 } 867 } 868 869 void HubConnection::discardInotifyEvent() { 870 // Read & discard an inotify event. We only use the presence of an event as 871 // a trigger to perform the file existence check (for simplicity) 872 if (mInotifyPollIndex >= 0) { 873 char buf[sizeof(struct inotify_event) + NAME_MAX + 1]; 874 int ret = ::read(mPollFds[mInotifyPollIndex].fd, buf, sizeof(buf)); 875 ALOGV("Discarded %d bytes of inotify data", ret); 876 } 877 } 878 879 void HubConnection::waitOnNanohubLock() { 880 if (mInotifyPollIndex < 0) { 881 return; 882 } 883 struct pollfd *pfd = &mPollFds[mInotifyPollIndex]; 884 885 // While the lock file exists, poll on the inotify fd (with timeout) 886 while (access(NANOHUB_LOCK_FILE, F_OK) == 0) { 887 ALOGW("Nanohub is locked; blocking read thread"); 888 int ret = poll(pfd, 1, 5000); 889 if ((ret > 0) && (pfd->revents & POLLIN)) { 890 discardInotifyEvent(); 891 } 892 } 893 } 894 895 void HubConnection::restoreSensorState() 896 { 897 Mutex::Autolock autoLock(mLock); 898 899 sendCalibrationOffsets(); 900 901 for (int i = 0; i < NUM_COMMS_SENSORS_PLUS_1; i++) { 902 if (mSensorState[i].sensorType && mSensorState[i].enable) { 903 struct ConfigCmd cmd; 904 905 initConfigCmd(&cmd, i); 906 907 ALOGV("restoring: sensor=%d, handle=%d, enable=%d, period=%" PRId64 ", latency=%" PRId64, 908 cmd.sensorType, i, mSensorState[i].enable, frequency_q10_to_period_ns(mSensorState[i].rate), 909 mSensorState[i].latency); 910 911 int ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 912 if (ret != sizeof(cmd)) { 913 ALOGW("failed to send config command to restore sensor %d\n", cmd.sensorType); 914 } 915 916 cmd.cmd = CONFIG_CMD_FLUSH; 917 918 for (int j = 0; j < mSensorState[i].flushCnt; j++) { 919 int ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 920 if (ret != sizeof(cmd)) { 921 ALOGW("failed to send flush command to sensor %d\n", cmd.sensorType); 922 } 923 } 924 } 925 } 926 927 mStepCounterOffset = mLastStepCount; 928 929 if (mActivityEventHandler != NULL) { 930 mActivityEventHandler->OnSensorHubReset(); 931 } 932 } 933 934 void HubConnection::postOsLog(uint8_t *buf, ssize_t len) 935 { 936 // if len is less than 6, it's either an invalid or an empty log message. 937 if (len < 6) 938 return; 939 940 buf[len] = 0x00; 941 switch (buf[4]) { 942 case 'E': 943 ALOGE("osLog: %s", &buf[5]); 944 break; 945 case 'W': 946 ALOGW("osLog: %s", &buf[5]); 947 break; 948 case 'I': 949 // The other side of this is too chatty, reducing the priority to VERBOSE 950 ALOGV("osLog: %s", &buf[5]); 951 break; 952 case 'D': 953 // The other side of this is too chatty, reducing the priority to VERBOSE 954 ALOGV("osLog: %s", &buf[5]); 955 break; 956 default: 957 break; 958 } 959 } 960 961 void HubConnection::processAppData(uint8_t *buf, ssize_t len) { 962 if (len < static_cast<ssize_t>(sizeof(AppToSensorHalDataBuffer))) 963 return; 964 965 AppToSensorHalDataPayload *data = 966 &(reinterpret_cast<AppToSensorHalDataBuffer *>(buf)->payload); 967 if (data->size + sizeof(AppToSensorHalDataBuffer) != len) { 968 ALOGW("Received corrupted data update packet, len %zd, size %u", len, data->size); 969 return; 970 } 971 972 switch (data->type & APP_TO_SENSOR_HAL_TYPE_MASK) { 973 case HALINTF_TYPE_GYRO_OTC_DATA: 974 if (data->size != sizeof(GyroOtcData)) { 975 ALOGW("Corrupted HALINTF_TYPE_GYRO_OTC_DATA with size %u", data->size); 976 return; 977 } 978 mGyroOtcData = data->gyroOtcData[0]; 979 saveSensorSettings(); 980 break; 981 default: 982 ALOGW("Unknown app to hal data type 0x%04x", data->type); 983 break; 984 } 985 } 986 987 ssize_t HubConnection::processBuf(uint8_t *buf, size_t len) 988 { 989 struct nAxisEvent *data = (struct nAxisEvent *)buf; 990 uint32_t type, sensor, bias, currSensor; 991 int i, numSamples; 992 bool one, rawThree, three; 993 sensors_event_t ev; 994 uint64_t timestamp; 995 ssize_t ret = 0; 996 997 if (len >= sizeof(data->evtType)) { 998 ret = sizeof(data->evtType); 999 one = three = rawThree = false; 1000 bias = 0; 1001 switch (data->evtType) { 1002 case OS_LOG_EVENT: 1003 postOsLog(buf, len); 1004 return 0; 1005 case EVT_APP_TO_SENSOR_HAL_DATA: 1006 processAppData(buf, len); 1007 return 0; 1008 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACCEL): 1009 type = SENSOR_TYPE_ACCELEROMETER; 1010 sensor = COMMS_SENSOR_ACCEL; 1011 bias = COMMS_SENSOR_ACCEL_BIAS; 1012 three = true; 1013 break; 1014 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACCEL_RAW): 1015 type = SENSOR_TYPE_ACCELEROMETER; 1016 sensor = COMMS_SENSOR_ACCEL; 1017 rawThree = true; 1018 break; 1019 case SENS_TYPE_TO_EVENT(SENS_TYPE_GYRO): 1020 type = SENSOR_TYPE_GYROSCOPE; 1021 sensor = COMMS_SENSOR_GYRO; 1022 bias = COMMS_SENSOR_GYRO_BIAS; 1023 three = true; 1024 break; 1025 case SENS_TYPE_TO_EVENT(SENS_TYPE_MAG): 1026 type = SENSOR_TYPE_MAGNETIC_FIELD; 1027 sensor = COMMS_SENSOR_MAG; 1028 bias = COMMS_SENSOR_MAG_BIAS; 1029 three = true; 1030 break; 1031 case SENS_TYPE_TO_EVENT(SENS_TYPE_MAG_RAW): 1032 type = SENSOR_TYPE_MAGNETIC_FIELD; 1033 sensor = COMMS_SENSOR_MAG; 1034 rawThree = true; 1035 break; 1036 case SENS_TYPE_TO_EVENT(SENS_TYPE_ALS): 1037 type = SENSOR_TYPE_LIGHT; 1038 sensor = COMMS_SENSOR_LIGHT; 1039 one = true; 1040 break; 1041 case SENS_TYPE_TO_EVENT(SENS_TYPE_PROX): 1042 type = SENSOR_TYPE_PROXIMITY; 1043 sensor = COMMS_SENSOR_PROXIMITY; 1044 one = true; 1045 break; 1046 case SENS_TYPE_TO_EVENT(SENS_TYPE_BARO): 1047 type = SENSOR_TYPE_PRESSURE; 1048 sensor = COMMS_SENSOR_PRESSURE; 1049 one = true; 1050 break; 1051 case SENS_TYPE_TO_EVENT(SENS_TYPE_HUMIDITY): 1052 type = SENSOR_TYPE_RELATIVE_HUMIDITY; 1053 sensor = COMMS_SENSOR_HUMIDITY; 1054 one = true; 1055 break; 1056 case SENS_TYPE_TO_EVENT(SENS_TYPE_TEMP): 1057 // nanohub only has one temperature sensor type, which is mapped to 1058 // internal temp because we currently don't have ambient temp 1059 type = SENSOR_TYPE_INTERNAL_TEMPERATURE; 1060 sensor = COMMS_SENSOR_TEMPERATURE; 1061 one = true; 1062 break; 1063 case SENS_TYPE_TO_EVENT(SENS_TYPE_ORIENTATION): 1064 type = SENSOR_TYPE_ORIENTATION; 1065 sensor = COMMS_SENSOR_ORIENTATION; 1066 three = true; 1067 break; 1068 case SENS_TYPE_TO_EVENT(SENS_TYPE_WIN_ORIENTATION): 1069 type = SENSOR_TYPE_DEVICE_ORIENTATION; 1070 sensor = COMMS_SENSOR_WINDOW_ORIENTATION; 1071 one = true; 1072 break; 1073 case SENS_TYPE_TO_EVENT(SENS_TYPE_STEP_DETECT): 1074 type = SENSOR_TYPE_STEP_DETECTOR; 1075 sensor = COMMS_SENSOR_STEP_DETECTOR; 1076 one = true; 1077 break; 1078 case SENS_TYPE_TO_EVENT(SENS_TYPE_STEP_COUNT): 1079 type = SENSOR_TYPE_STEP_COUNTER; 1080 sensor = COMMS_SENSOR_STEP_COUNTER; 1081 one = true; 1082 break; 1083 case SENS_TYPE_TO_EVENT(SENS_TYPE_SIG_MOTION): 1084 type = SENSOR_TYPE_SIGNIFICANT_MOTION; 1085 sensor = COMMS_SENSOR_SIGNIFICANT_MOTION; 1086 one = true; 1087 break; 1088 case SENS_TYPE_TO_EVENT(SENS_TYPE_GRAVITY): 1089 type = SENSOR_TYPE_GRAVITY; 1090 sensor = COMMS_SENSOR_GRAVITY; 1091 three = true; 1092 break; 1093 case SENS_TYPE_TO_EVENT(SENS_TYPE_LINEAR_ACCEL): 1094 type = SENSOR_TYPE_LINEAR_ACCELERATION; 1095 sensor = COMMS_SENSOR_LINEAR_ACCEL; 1096 three = true; 1097 break; 1098 case SENS_TYPE_TO_EVENT(SENS_TYPE_ROTATION_VECTOR): 1099 type = SENSOR_TYPE_ROTATION_VECTOR; 1100 sensor = COMMS_SENSOR_ROTATION_VECTOR; 1101 three = true; 1102 break; 1103 case SENS_TYPE_TO_EVENT(SENS_TYPE_GEO_MAG_ROT_VEC): 1104 type = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR; 1105 sensor = COMMS_SENSOR_GEO_MAG; 1106 three = true; 1107 break; 1108 case SENS_TYPE_TO_EVENT(SENS_TYPE_GAME_ROT_VECTOR): 1109 type = SENSOR_TYPE_GAME_ROTATION_VECTOR; 1110 sensor = COMMS_SENSOR_GAME_ROTATION_VECTOR; 1111 three = true; 1112 break; 1113 case SENS_TYPE_TO_EVENT(SENS_TYPE_HALL): 1114 type = 0; 1115 sensor = COMMS_SENSOR_HALL; 1116 one = true; 1117 break; 1118 case SENS_TYPE_TO_EVENT(SENS_TYPE_VSYNC): 1119 type = SENSOR_TYPE_SYNC; 1120 sensor = COMMS_SENSOR_SYNC; 1121 one = true; 1122 break; 1123 case SENS_TYPE_TO_EVENT(SENS_TYPE_TILT): 1124 type = SENSOR_TYPE_TILT_DETECTOR; 1125 sensor = COMMS_SENSOR_TILT; 1126 one = true; 1127 break; 1128 case SENS_TYPE_TO_EVENT(SENS_TYPE_GESTURE): 1129 type = SENSOR_TYPE_PICK_UP_GESTURE; 1130 sensor = COMMS_SENSOR_GESTURE; 1131 one = true; 1132 break; 1133 case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TWIST): 1134 type = SENSOR_TYPE_DOUBLE_TWIST; 1135 sensor = COMMS_SENSOR_DOUBLE_TWIST; 1136 one = true; 1137 break; 1138 case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TAP): 1139 type = SENSOR_TYPE_DOUBLE_TAP; 1140 sensor = COMMS_SENSOR_DOUBLE_TAP; 1141 three = true; 1142 break; 1143 case SENS_TYPE_TO_EVENT(SENS_TYPE_WRIST_TILT): 1144 type = SENSOR_TYPE_WRIST_TILT_GESTURE; 1145 sensor = COMMS_SENSOR_WRIST_TILT; 1146 one = true; 1147 break; 1148 case SENS_TYPE_TO_EVENT(SENS_TYPE_DOUBLE_TOUCH): 1149 type = SENSOR_TYPE_DOUBLE_TOUCH; 1150 sensor = COMMS_SENSOR_DOUBLE_TOUCH; 1151 one = true; 1152 break; 1153 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_IN_VEHICLE_START): 1154 type = 0; 1155 sensor = COMMS_SENSOR_ACTIVITY_IN_VEHICLE_START; 1156 one = true; 1157 break; 1158 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_IN_VEHICLE_STOP): 1159 type = 0; 1160 sensor = COMMS_SENSOR_ACTIVITY_IN_VEHICLE_STOP; 1161 one = true; 1162 break; 1163 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_ON_BICYCLE_START): 1164 type = 0; 1165 sensor = COMMS_SENSOR_ACTIVITY_ON_BICYCLE_START; 1166 one = true; 1167 break; 1168 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_ON_BICYCLE_STOP): 1169 type = 0; 1170 sensor = COMMS_SENSOR_ACTIVITY_ON_BICYCLE_STOP; 1171 one = true; 1172 break; 1173 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_WALKING_START): 1174 type = 0; 1175 sensor = COMMS_SENSOR_ACTIVITY_WALKING_START; 1176 one = true; 1177 break; 1178 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_WALKING_STOP): 1179 type = 0; 1180 sensor = COMMS_SENSOR_ACTIVITY_WALKING_STOP; 1181 one = true; 1182 break; 1183 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_RUNNING_START): 1184 type = 0; 1185 sensor = COMMS_SENSOR_ACTIVITY_RUNNING_START; 1186 one = true; 1187 break; 1188 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_RUNNING_STOP): 1189 type = 0; 1190 sensor = COMMS_SENSOR_ACTIVITY_RUNNING_STOP; 1191 one = true; 1192 break; 1193 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_STILL_START): 1194 type = 0; 1195 sensor = COMMS_SENSOR_ACTIVITY_STILL_START; 1196 one = true; 1197 break; 1198 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_STILL_STOP): 1199 type = 0; 1200 sensor = COMMS_SENSOR_ACTIVITY_STILL_STOP; 1201 one = true; 1202 break; 1203 case SENS_TYPE_TO_EVENT(SENS_TYPE_ACTIVITY_TILTING): 1204 type = 0; 1205 sensor = COMMS_SENSOR_ACTIVITY_TILTING; 1206 one = true; 1207 break; 1208 case SENS_TYPE_TO_EVENT(SENS_TYPE_GAZE): 1209 type = SENSOR_TYPE_GAZE; 1210 sensor = COMMS_SENSOR_GAZE; 1211 one = true; 1212 break; 1213 case SENS_TYPE_TO_EVENT(SENS_TYPE_UNGAZE): 1214 type = SENSOR_TYPE_UNGAZE; 1215 sensor = COMMS_SENSOR_UNGAZE; 1216 one = true; 1217 break; 1218 case EVT_RESET_REASON: 1219 uint32_t resetReason; 1220 memcpy(&resetReason, data->buffer, sizeof(resetReason)); 1221 ALOGI("Observed hub reset: 0x%08" PRIx32, resetReason); 1222 restoreSensorState(); 1223 return 0; 1224 default: 1225 ALOGW("unknown evtType: 0x%08x len: %zu\n", data->evtType, len); 1226 return -1; 1227 } 1228 } else { 1229 ALOGW("too little data: len=%zu\n", len); 1230 return -1; 1231 } 1232 1233 if (len >= sizeof(data->evtType) + sizeof(data->referenceTime) + sizeof(data->firstSample)) { 1234 ret += sizeof(data->referenceTime); 1235 timestamp = data->referenceTime; 1236 numSamples = data->firstSample.numSamples; 1237 for (i=0; i<numSamples; i++) { 1238 if (data->firstSample.biasPresent && data->firstSample.biasSample == i) 1239 currSensor = bias; 1240 else 1241 currSensor = sensor; 1242 1243 if (one) { 1244 if (ret + sizeof(data->oneSamples[i]) > len) { 1245 ALOGW("sensor %d (one): ret=%zd, numSamples=%d, i=%d\n", currSensor, ret, numSamples, i); 1246 return -1; 1247 } 1248 if (i > 0) 1249 timestamp += ((uint64_t)data->oneSamples[i].deltaTime) << delta_time_shift_table[data->oneSamples[i].deltaTime & delta_time_encoded]; 1250 processSample(timestamp, type, currSensor, &data->oneSamples[i], data->firstSample.highAccuracy); 1251 ret += sizeof(data->oneSamples[i]); 1252 } else if (rawThree) { 1253 if (ret + sizeof(data->rawThreeSamples[i]) > len) { 1254 ALOGW("sensor %d (rawThree): ret=%zd, numSamples=%d, i=%d\n", currSensor, ret, numSamples, i); 1255 return -1; 1256 } 1257 if (i > 0) 1258 timestamp += ((uint64_t)data->rawThreeSamples[i].deltaTime) << delta_time_shift_table[data->rawThreeSamples[i].deltaTime & delta_time_encoded]; 1259 processSample(timestamp, type, currSensor, &data->rawThreeSamples[i], data->firstSample.highAccuracy); 1260 ret += sizeof(data->rawThreeSamples[i]); 1261 } else if (three) { 1262 if (ret + sizeof(data->threeSamples[i]) > len) { 1263 ALOGW("sensor %d (three): ret=%zd, numSamples=%d, i=%d\n", currSensor, ret, numSamples, i); 1264 return -1; 1265 } 1266 if (i > 0) 1267 timestamp += ((uint64_t)data->threeSamples[i].deltaTime) << delta_time_shift_table[data->threeSamples[i].deltaTime & delta_time_encoded]; 1268 processSample(timestamp, type, currSensor, &data->threeSamples[i], data->firstSample.highAccuracy); 1269 ret += sizeof(data->threeSamples[i]); 1270 } else { 1271 ALOGW("sensor %d (unknown): cannot processSample\n", currSensor); 1272 return -1; 1273 } 1274 } 1275 1276 if (!numSamples) 1277 ret += sizeof(data->firstSample); 1278 1279 for (i=0; i<data->firstSample.numFlushes; i++) { 1280 if (isActivitySensor(sensor) && mActivityEventHandler != NULL) { 1281 mActivityEventHandler->OnFlush(); 1282 } else { 1283 memset(&ev, 0x00, sizeof(sensors_event_t)); 1284 ev.version = META_DATA_VERSION; 1285 ev.timestamp = 0; 1286 ev.type = SENSOR_TYPE_META_DATA; 1287 ev.sensor = 0; 1288 ev.meta_data.what = META_DATA_FLUSH_COMPLETE; 1289 if (mSensorState[sensor].alt && mSensorState[mSensorState[sensor].alt].flushCnt > 0) { 1290 mSensorState[mSensorState[sensor].alt].flushCnt --; 1291 ev.meta_data.sensor = mSensorState[sensor].alt; 1292 } else { 1293 mSensorState[sensor].flushCnt --; 1294 ev.meta_data.sensor = sensor; 1295 } 1296 1297 write(&ev, 1); 1298 ALOGV("flushing %d", ev.meta_data.sensor); 1299 } 1300 } 1301 } else { 1302 ALOGW("too little data for sensor %d: len=%zu\n", sensor, len); 1303 return -1; 1304 } 1305 1306 return ret; 1307 } 1308 1309 void HubConnection::sendCalibrationOffsets() 1310 { 1311 sp<JSONObject> settings; 1312 sp<JSONObject> saved_settings; 1313 struct { 1314 int32_t hw[3]; 1315 float sw[3]; 1316 } accel; 1317 1318 int32_t proximity, proximity_array[4]; 1319 float barometer, humidity, light; 1320 bool accel_hw_cal_exists, accel_sw_cal_exists; 1321 1322 loadSensorSettings(&settings, &saved_settings); 1323 1324 accel_hw_cal_exists = getCalibrationInt32(settings, ACCEL_BIAS_TAG, accel.hw, 3); 1325 accel_sw_cal_exists = getCalibrationFloat(saved_settings, ACCEL_SW_BIAS_TAG, accel.sw); 1326 if (accel_hw_cal_exists || accel_sw_cal_exists) { 1327 // Store SW bias so we can remove bias for uncal data 1328 mAccelBias[0] = accel.sw[0]; 1329 mAccelBias[1] = accel.sw[1]; 1330 mAccelBias[2] = accel.sw[2]; 1331 1332 queueDataInternal(COMMS_SENSOR_ACCEL, &accel, sizeof(accel)); 1333 } 1334 1335 ALOGV("Use new configuration format"); 1336 std::vector<int32_t> hardwareGyroBias = getInt32Setting(settings, GYRO_BIAS_TAG); 1337 std::vector<float> softwareGyroBias = getFloatSetting(saved_settings, GYRO_SW_BIAS_TAG); 1338 if (hardwareGyroBias.size() == 3 || softwareGyroBias.size() == 3) { 1339 struct { 1340 AppToSensorHalDataPayload header; 1341 GyroCalBias data; 1342 } packet = { 1343 .header = { 1344 .size = sizeof(GyroCalBias), 1345 .type = HALINTF_TYPE_GYRO_CAL_BIAS } 1346 }; 1347 if (hardwareGyroBias.size() == 3) { 1348 std::copy(hardwareGyroBias.begin(), hardwareGyroBias.end(), 1349 packet.data.hardwareBias); 1350 } 1351 if (softwareGyroBias.size() == 3) { 1352 // Store SW bias so we can remove bias for uncal data 1353 std::copy(softwareGyroBias.begin(), softwareGyroBias.end(), 1354 mGyroBias); 1355 1356 std::copy(softwareGyroBias.begin(), softwareGyroBias.end(), 1357 packet.data.softwareBias); 1358 } 1359 // send packet to hub 1360 queueDataInternal(COMMS_SENSOR_GYRO, &packet, sizeof(packet)); 1361 } 1362 1363 // over temp cal 1364 std::vector<float> gyroOtcData = getFloatSetting(saved_settings, GYRO_OTC_DATA_TAG); 1365 if (gyroOtcData.size() == sizeof(GyroOtcData) / sizeof(float)) { 1366 std::copy(gyroOtcData.begin(), gyroOtcData.end(), 1367 reinterpret_cast<float*>(&mGyroOtcData)); 1368 struct { 1369 AppToSensorHalDataPayload header; 1370 GyroOtcData data; 1371 } packet = { 1372 .header = { 1373 .size = sizeof(GyroOtcData), 1374 .type = HALINTF_TYPE_GYRO_OTC_DATA }, 1375 .data = mGyroOtcData 1376 }; 1377 1378 // send it to hub 1379 queueDataInternal(COMMS_SENSOR_GYRO, &packet, sizeof(packet)); 1380 } else { 1381 ALOGW("Illegal otc_gyro data size = %zu", gyroOtcData.size()); 1382 } 1383 1384 std::vector<float> magBiasData = getFloatSetting(saved_settings, MAG_BIAS_TAG); 1385 if (magBiasData.size() == 3) { 1386 // Store SW bias so we can remove bias for uncal data 1387 std::copy(magBiasData.begin(), magBiasData.end(), mMagBias); 1388 1389 struct { 1390 AppToSensorHalDataPayload header; 1391 MagCalBias mag; 1392 } packet = { 1393 .header = { 1394 .size = sizeof(MagCalBias), 1395 .type = HALINTF_TYPE_MAG_CAL_BIAS } 1396 }; 1397 std::copy(magBiasData.begin(), magBiasData.end(), packet.mag.bias); 1398 queueDataInternal(COMMS_SENSOR_MAG, &packet, sizeof(packet)); 1399 } 1400 1401 if (settings->getFloat("barometer", &barometer)) 1402 queueDataInternal(COMMS_SENSOR_PRESSURE, &barometer, sizeof(barometer)); 1403 1404 if (settings->getFloat("humidity", &humidity)) 1405 queueDataInternal(COMMS_SENSOR_HUMIDITY, &humidity, sizeof(humidity)); 1406 1407 if (settings->getInt32("proximity", &proximity)) 1408 queueDataInternal(COMMS_SENSOR_PROXIMITY, &proximity, sizeof(proximity)); 1409 1410 if (getCalibrationInt32(settings, "proximity", proximity_array, 4)) 1411 queueDataInternal(COMMS_SENSOR_PROXIMITY, proximity_array, sizeof(proximity_array)); 1412 1413 if (settings->getFloat("light", &light)) 1414 queueDataInternal(COMMS_SENSOR_LIGHT, &light, sizeof(light)); 1415 } 1416 1417 bool HubConnection::threadLoop() { 1418 ALOGV("threadLoop: starting"); 1419 1420 if (mFd < 0) { 1421 ALOGW("threadLoop: exiting prematurely: nanohub is unavailable"); 1422 return false; 1423 } 1424 waitOnNanohubLock(); 1425 1426 sendCalibrationOffsets(); 1427 1428 while (!Thread::exitPending()) { 1429 ssize_t ret; 1430 1431 do { 1432 ret = poll(mPollFds, mNumPollFds, -1); 1433 } while (ret < 0 && errno == EINTR); 1434 1435 if (mInotifyPollIndex >= 0 && mPollFds[mInotifyPollIndex].revents & POLLIN) { 1436 discardInotifyEvent(); 1437 waitOnNanohubLock(); 1438 } 1439 1440 #ifdef USB_MAG_BIAS_REPORTING_ENABLED 1441 if (mMagBiasPollIndex >= 0 && mPollFds[mMagBiasPollIndex].revents & POLLERR) { 1442 // Read from mag bias file 1443 char buf[16]; 1444 lseek(mPollFds[mMagBiasPollIndex].fd, 0, SEEK_SET); 1445 ::read(mPollFds[mMagBiasPollIndex].fd, buf, 16); 1446 float bias = atof(buf); 1447 mUsbMagBias = bias; 1448 queueUsbMagBias(); 1449 } 1450 #endif // USB_MAG_BIAS_REPORTING_ENABLED 1451 1452 #ifdef DOUBLE_TOUCH_ENABLED 1453 if (mDoubleTouchPollIndex >= 0 && mPollFds[mDoubleTouchPollIndex].revents & POLLERR) { 1454 // Read from double touch file 1455 char buf[16]; 1456 lseek(mPollFds[mDoubleTouchPollIndex].fd, 0, SEEK_SET); 1457 ::read(mPollFds[mDoubleTouchPollIndex].fd, buf, 16); 1458 sensors_event_t gestureEvent; 1459 initEv(&gestureEvent, elapsedRealtimeNano(), SENSOR_TYPE_PICK_UP_GESTURE, COMMS_SENSOR_GESTURE)->data[0] = 8; 1460 write(&gestureEvent, 1); 1461 } 1462 #endif // DOUBLE_TOUCH_ENABLED 1463 1464 if (mPollFds[0].revents & POLLIN) { 1465 uint8_t recv[256]; 1466 ssize_t len = ::read(mFd, recv, sizeof(recv)); 1467 1468 if (len >= 0) { 1469 for (ssize_t offset = 0; offset < len;) { 1470 ret = processBuf(recv + offset, len - offset); 1471 1472 if (ret > 0) 1473 offset += ret; 1474 else 1475 break; 1476 } 1477 } else { 1478 ALOGW("read -1: errno=%d\n", errno); 1479 } 1480 } 1481 } 1482 1483 return false; 1484 } 1485 1486 ssize_t HubConnection::read(sensors_event_t *ev, size_t size) { 1487 return mRing.read(ev, size); 1488 } 1489 1490 void HubConnection::setActivityCallback(ActivityEventHandler *eventHandler) 1491 { 1492 Mutex::Autolock autoLock(mLock); 1493 mActivityEventHandler = eventHandler; 1494 } 1495 1496 void HubConnection::initConfigCmd(struct ConfigCmd *cmd, int handle) 1497 { 1498 uint8_t alt = mSensorState[handle].alt; 1499 1500 memset(cmd, 0x00, sizeof(*cmd)); 1501 1502 cmd->evtType = EVT_NO_SENSOR_CONFIG_EVENT; 1503 cmd->sensorType = mSensorState[handle].sensorType; 1504 1505 if (alt && mSensorState[alt].enable && mSensorState[handle].enable) { 1506 cmd->cmd = CONFIG_CMD_ENABLE; 1507 if (mSensorState[alt].rate > mSensorState[handle].rate) 1508 cmd->rate = mSensorState[alt].rate; 1509 else 1510 cmd->rate = mSensorState[handle].rate; 1511 if (mSensorState[alt].latency < mSensorState[handle].latency) 1512 cmd->latency = mSensorState[alt].latency; 1513 else 1514 cmd->latency = mSensorState[handle].latency; 1515 } else if (alt && mSensorState[alt].enable) { 1516 cmd->cmd = mSensorState[alt].enable ? CONFIG_CMD_ENABLE : CONFIG_CMD_DISABLE; 1517 cmd->rate = mSensorState[alt].rate; 1518 cmd->latency = mSensorState[alt].latency; 1519 } else { /* !alt || !mSensorState[alt].enable */ 1520 cmd->cmd = mSensorState[handle].enable ? CONFIG_CMD_ENABLE : CONFIG_CMD_DISABLE; 1521 cmd->rate = mSensorState[handle].rate; 1522 cmd->latency = mSensorState[handle].latency; 1523 } 1524 1525 // will be a nop if direct report mode is not enabled 1526 mergeDirectReportRequest(cmd, handle); 1527 } 1528 1529 void HubConnection::queueActivate(int handle, bool enable) 1530 { 1531 struct ConfigCmd cmd; 1532 int ret; 1533 1534 Mutex::Autolock autoLock(mLock); 1535 1536 if (isValidHandle(handle)) { 1537 mSensorState[handle].enable = enable; 1538 1539 initConfigCmd(&cmd, handle); 1540 1541 ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 1542 if (ret == sizeof(cmd)) 1543 ALOGV("queueActivate: sensor=%d, handle=%d, enable=%d", 1544 cmd.sensorType, handle, enable); 1545 else 1546 ALOGW("queueActivate: failed to send command: sensor=%d, handle=%d, enable=%d", 1547 cmd.sensorType, handle, enable); 1548 } else { 1549 ALOGV("queueActivate: unhandled handle=%d, enable=%d", handle, enable); 1550 } 1551 } 1552 1553 void HubConnection::queueSetDelay(int handle, nsecs_t sampling_period_ns) 1554 { 1555 struct ConfigCmd cmd; 1556 int ret; 1557 1558 Mutex::Autolock autoLock(mLock); 1559 1560 if (isValidHandle(handle)) { 1561 if (sampling_period_ns > 0 && 1562 mSensorState[handle].rate != SENSOR_RATE_ONCHANGE && 1563 mSensorState[handle].rate != SENSOR_RATE_ONESHOT) { 1564 mSensorState[handle].rate = period_ns_to_frequency_q10(sampling_period_ns); 1565 } 1566 1567 initConfigCmd(&cmd, handle); 1568 1569 ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 1570 if (ret == sizeof(cmd)) 1571 ALOGV("queueSetDelay: sensor=%d, handle=%d, period=%" PRId64, 1572 cmd.sensorType, handle, sampling_period_ns); 1573 else 1574 ALOGW("queueSetDelay: failed to send command: sensor=%d, handle=%d, period=%" PRId64, 1575 cmd.sensorType, handle, sampling_period_ns); 1576 } else { 1577 ALOGV("queueSetDelay: unhandled handle=%d, period=%" PRId64, handle, sampling_period_ns); 1578 } 1579 } 1580 1581 void HubConnection::queueBatch( 1582 int handle, 1583 nsecs_t sampling_period_ns, 1584 nsecs_t max_report_latency_ns) 1585 { 1586 struct ConfigCmd cmd; 1587 int ret; 1588 1589 Mutex::Autolock autoLock(mLock); 1590 1591 if (isValidHandle(handle)) { 1592 if (sampling_period_ns > 0 && 1593 mSensorState[handle].rate != SENSOR_RATE_ONCHANGE && 1594 mSensorState[handle].rate != SENSOR_RATE_ONESHOT) { 1595 mSensorState[handle].rate = period_ns_to_frequency_q10(sampling_period_ns); 1596 } 1597 mSensorState[handle].latency = max_report_latency_ns; 1598 1599 initConfigCmd(&cmd, handle); 1600 1601 ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 1602 if (ret == sizeof(cmd)) 1603 ALOGV("queueBatch: sensor=%d, handle=%d, period=%" PRId64 ", latency=%" PRId64, 1604 cmd.sensorType, handle, sampling_period_ns, max_report_latency_ns); 1605 else 1606 ALOGW("queueBatch: failed to send command: sensor=%d, handle=%d, period=%" PRId64 ", latency=%" PRId64, 1607 cmd.sensorType, handle, sampling_period_ns, max_report_latency_ns); 1608 } else { 1609 ALOGV("queueBatch: unhandled handle=%d, period=%" PRId64 ", latency=%" PRId64, 1610 handle, sampling_period_ns, max_report_latency_ns); 1611 } 1612 } 1613 1614 void HubConnection::queueFlush(int handle) 1615 { 1616 struct ConfigCmd cmd; 1617 int ret; 1618 1619 Mutex::Autolock autoLock(mLock); 1620 1621 if (isValidHandle(handle)) { 1622 mSensorState[handle].flushCnt++; 1623 1624 initConfigCmd(&cmd, handle); 1625 cmd.cmd = CONFIG_CMD_FLUSH; 1626 1627 ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 1628 if (ret == sizeof(cmd)) { 1629 ALOGV("queueFlush: sensor=%d, handle=%d", 1630 cmd.sensorType, handle); 1631 } else { 1632 ALOGW("queueFlush: failed to send command: sensor=%d, handle=%d" 1633 " with error %s", cmd.sensorType, handle, strerror(errno)); 1634 } 1635 } else { 1636 ALOGV("queueFlush: unhandled handle=%d", handle); 1637 } 1638 } 1639 1640 void HubConnection::queueDataInternal(int handle, void *data, size_t length) 1641 { 1642 struct ConfigCmd *cmd = (struct ConfigCmd *)malloc(sizeof(struct ConfigCmd) + length); 1643 size_t ret; 1644 1645 if (cmd && isValidHandle(handle)) { 1646 initConfigCmd(cmd, handle); 1647 memcpy(cmd->data, data, length); 1648 cmd->cmd = CONFIG_CMD_CFG_DATA; 1649 1650 ret = TEMP_FAILURE_RETRY(::write(mFd, cmd, sizeof(*cmd) + length)); 1651 if (ret == sizeof(*cmd) + length) 1652 ALOGV("queueData: sensor=%d, length=%zu", 1653 cmd->sensorType, length); 1654 else 1655 ALOGW("queueData: failed to send command: sensor=%d, length=%zu", 1656 cmd->sensorType, length); 1657 } else { 1658 ALOGV("queueData: unhandled handle=%d", handle); 1659 } 1660 free(cmd); 1661 } 1662 1663 void HubConnection::queueData(int handle, void *data, size_t length) 1664 { 1665 Mutex::Autolock autoLock(mLock); 1666 queueDataInternal(handle, data, length); 1667 } 1668 1669 void HubConnection::setOperationParameter(const additional_info_event_t &info) { 1670 switch (info.type) { 1671 case AINFO_LOCAL_GEOMAGNETIC_FIELD: { 1672 ALOGV("local geomag field update: strength %fuT, dec %fdeg, inc %fdeg", 1673 static_cast<double>(info.data_float[0]), 1674 info.data_float[1] * 180 / M_PI, 1675 info.data_float[2] * 180 / M_PI); 1676 1677 struct { 1678 AppToSensorHalDataPayload header; 1679 MagLocalField magLocalField; 1680 } packet = { 1681 .header = { 1682 .size = sizeof(MagLocalField), 1683 .type = HALINTF_TYPE_MAG_LOCAL_FIELD }, 1684 .magLocalField = { 1685 .strength = info.data_float[0], 1686 .declination = info.data_float[1], 1687 .inclination = info.data_float[2]} 1688 }; 1689 queueDataInternal(COMMS_SENSOR_MAG, &packet, sizeof(packet)); 1690 break; 1691 } 1692 default: 1693 break; 1694 } 1695 } 1696 1697 void HubConnection::initNanohubLock() { 1698 // Create the lock directory (if it doesn't already exist) 1699 if (mkdir(NANOHUB_LOCK_DIR, NANOHUB_LOCK_DIR_PERMS) < 0 && errno != EEXIST) { 1700 ALOGW("Couldn't create Nanohub lock directory: %s", strerror(errno)); 1701 return; 1702 } 1703 1704 mInotifyPollIndex = -1; 1705 int inotifyFd = inotify_init1(IN_NONBLOCK); 1706 if (inotifyFd < 0) { 1707 ALOGW("Couldn't initialize inotify: %s", strerror(errno)); 1708 } else if (inotify_add_watch(inotifyFd, NANOHUB_LOCK_DIR, IN_CREATE | IN_DELETE) < 0) { 1709 ALOGW("Couldn't add inotify watch: %s", strerror(errno)); 1710 close(inotifyFd); 1711 } else { 1712 mPollFds[mNumPollFds].fd = inotifyFd; 1713 mPollFds[mNumPollFds].events = POLLIN; 1714 mPollFds[mNumPollFds].revents = 0; 1715 mInotifyPollIndex = mNumPollFds; 1716 mNumPollFds++; 1717 } 1718 } 1719 1720 ssize_t HubConnection::write(const sensors_event_t *ev, size_t n) { 1721 return mRing.write(ev, n); 1722 } 1723 1724 #ifdef USB_MAG_BIAS_REPORTING_ENABLED 1725 void HubConnection::queueUsbMagBias() 1726 { 1727 struct MsgCmd *cmd = (struct MsgCmd *)malloc(sizeof(struct MsgCmd) + sizeof(float)); 1728 size_t ret; 1729 1730 if (cmd) { 1731 cmd->evtType = EVT_APP_FROM_HOST; 1732 cmd->msg.appId = APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, APP_ID_APP_BMI160); 1733 cmd->msg.dataLen = sizeof(float); 1734 memcpy((float *)(cmd+1), &mUsbMagBias, sizeof(float)); 1735 1736 ret = TEMP_FAILURE_RETRY(::write(mFd, cmd, sizeof(*cmd) + sizeof(float))); 1737 if (ret == sizeof(*cmd) + sizeof(float)) 1738 ALOGV("queueUsbMagBias: bias=%f\n", mUsbMagBias); 1739 else 1740 ALOGW("queueUsbMagBias: failed to send command: bias=%f\n", mUsbMagBias); 1741 free(cmd); 1742 } 1743 } 1744 #endif // USB_MAG_BIAS_REPORTING_ENABLED 1745 1746 #ifdef LID_STATE_REPORTING_ENABLED 1747 status_t HubConnection::initializeUinputNode() 1748 { 1749 int ret = 0; 1750 1751 // Open uinput dev node 1752 mUinputFd = TEMP_FAILURE_RETRY(open("/dev/uinput", O_WRONLY | O_NONBLOCK)); 1753 if (mUinputFd < 0) { 1754 ALOGW("could not open uinput node: %s", strerror(errno)); 1755 return UNKNOWN_ERROR; 1756 } 1757 1758 // Enable SW_LID events 1759 ret = TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_EVBIT, EV_SW)); 1760 ret |= TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_EVBIT, EV_SYN)); 1761 ret |= TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_SET_SWBIT, SW_LID)); 1762 if (ret < 0) { 1763 ALOGW("could not send ioctl to uinput node: %s", strerror(errno)); 1764 return UNKNOWN_ERROR; 1765 } 1766 1767 // Create uinput node for SW_LID 1768 struct uinput_user_dev uidev; 1769 memset(&uidev, 0, sizeof(uidev)); 1770 snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-folio"); 1771 uidev.id.bustype = BUS_SPI; 1772 uidev.id.vendor = 0; 1773 uidev.id.product = 0; 1774 uidev.id.version = 0; 1775 1776 ret = TEMP_FAILURE_RETRY(::write(mUinputFd, &uidev, sizeof(uidev))); 1777 if (ret < 0) { 1778 ALOGW("write to uinput node failed: %s", strerror(errno)); 1779 return UNKNOWN_ERROR; 1780 } 1781 1782 ret = TEMP_FAILURE_RETRY(ioctl(mUinputFd, UI_DEV_CREATE)); 1783 if (ret < 0) { 1784 ALOGW("could not send ioctl to uinput node: %s", strerror(errno)); 1785 return UNKNOWN_ERROR; 1786 } 1787 1788 return OK; 1789 } 1790 1791 void HubConnection::sendFolioEvent(int32_t data) { 1792 ssize_t ret = 0; 1793 struct input_event ev; 1794 1795 memset(&ev, 0, sizeof(ev)); 1796 1797 ev.type = EV_SW; 1798 ev.code = SW_LID; 1799 ev.value = data; 1800 ret = TEMP_FAILURE_RETRY(::write(mUinputFd, &ev, sizeof(ev))); 1801 if (ret < 0) { 1802 ALOGW("write to uinput node failed: %s", strerror(errno)); 1803 return; 1804 } 1805 1806 // Force flush with EV_SYN event 1807 ev.type = EV_SYN; 1808 ev.code = SYN_REPORT; 1809 ev.value = 0; 1810 ret = TEMP_FAILURE_RETRY(::write(mUinputFd, &ev, sizeof(ev))); 1811 if (ret < 0) { 1812 ALOGW("write to uinput node failed: %s", strerror(errno)); 1813 return; 1814 } 1815 1816 // Set lid state property 1817 if (property_set(LID_STATE_PROPERTY, 1818 (data ? LID_STATE_CLOSED : LID_STATE_OPEN)) < 0) { 1819 ALOGW("could not set lid_state property"); 1820 } 1821 } 1822 #endif // LID_STATE_REPORTING_ENABLED 1823 1824 #ifdef DIRECT_REPORT_ENABLED 1825 void HubConnection::sendDirectReportEvent(const sensors_event_t *nev, size_t n) { 1826 // short circuit to avoid lock operation 1827 if (n == 0) { 1828 return; 1829 } 1830 1831 // no intention to block sensor delivery thread. when lock is needed ignore 1832 // the event (this only happens when the channel is reconfiured, so it's ok 1833 if (mDirectChannelLock.tryLock() == NO_ERROR) { 1834 while (n--) { 1835 auto i = mSensorToChannel.find(nev->sensor); 1836 if (i != mSensorToChannel.end()) { 1837 for (auto &j : i->second) { 1838 mDirectChannel[j.first]->write(nev); 1839 } 1840 } 1841 ++nev; 1842 } 1843 mDirectChannelLock.unlock(); 1844 } 1845 } 1846 1847 void HubConnection::mergeDirectReportRequest(struct ConfigCmd *cmd, int handle) { 1848 auto j = mSensorToChannel.find(handle); 1849 if (j != mSensorToChannel.end()) { 1850 bool enable = false; 1851 rate_q10_t rate; 1852 1853 if (!j->second.empty()) { 1854 int maxRateLevel = SENSOR_DIRECT_RATE_STOP; 1855 for (auto &i : j->second) { 1856 maxRateLevel = (i.second) > maxRateLevel ? i.second : maxRateLevel; 1857 } 1858 switch(maxRateLevel) { 1859 case SENSOR_DIRECT_RATE_NORMAL: 1860 enable = true; 1861 rate = period_ns_to_frequency_q10(20000000ull); // NORMAL = 50Hz 1862 break; 1863 case SENSOR_DIRECT_RATE_FAST: 1864 enable = true; 1865 rate = period_ns_to_frequency_q10(5000000ull); // FAST = 200Hz 1866 break; 1867 default: 1868 break; 1869 } 1870 } 1871 1872 if (enable) { 1873 cmd->rate = (rate > cmd->rate || cmd->cmd == CONFIG_CMD_DISABLE) ? rate : cmd->rate; 1874 cmd->latency = 0; 1875 cmd->cmd = CONFIG_CMD_ENABLE; 1876 } 1877 } 1878 } 1879 1880 int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *mem) { 1881 std::unique_ptr<DirectChannelBase> ch; 1882 int ret = NO_MEMORY; 1883 1884 switch(mem->type) { 1885 case SENSOR_DIRECT_MEM_TYPE_ASHMEM: 1886 ch = std::make_unique<AshmemDirectChannel>(mem); 1887 break; 1888 case SENSOR_DIRECT_MEM_TYPE_GRALLOC: 1889 ch = std::make_unique<GrallocDirectChannel>(mem); 1890 break; 1891 default: 1892 ret = INVALID_OPERATION; 1893 } 1894 1895 if (ch) { 1896 if (ch->isValid()) { 1897 Mutex::Autolock autoLock(mDirectChannelLock); 1898 ret = mDirectChannelHandle++; 1899 mDirectChannel.insert(std::make_pair(ret, std::move(ch))); 1900 } else { 1901 ret = ch->getError(); 1902 ALOGW("Direct channel object(type:%d) has error %d upon init", mem->type, ret); 1903 } 1904 } 1905 1906 return ret; 1907 } 1908 1909 int HubConnection::removeDirectChannel(int channel_handle) { 1910 // make sure no active sensor in this channel 1911 std::vector<int32_t> activeSensorList; 1912 stopAllDirectReportOnChannel(channel_handle, &activeSensorList); 1913 1914 // sensor service is responsible for stop all sensors before remove direct 1915 // channel. Thus, this is an error. 1916 if (!activeSensorList.empty()) { 1917 std::stringstream ss; 1918 std::copy(activeSensorList.begin(), activeSensorList.end(), 1919 std::ostream_iterator<int32_t>(ss, ",")); 1920 ALOGW("Removing channel %d when sensors (%s) are not stopped.", 1921 channel_handle, ss.str().c_str()); 1922 } 1923 1924 // remove the channel record 1925 Mutex::Autolock autoLock(mDirectChannelLock); 1926 mDirectChannel.erase(channel_handle); 1927 return NO_ERROR; 1928 } 1929 1930 int HubConnection::stopAllDirectReportOnChannel( 1931 int channel_handle, std::vector<int32_t> *activeSensorList) { 1932 Mutex::Autolock autoLock(mDirectChannelLock); 1933 if (mDirectChannel.find(channel_handle) == mDirectChannel.end()) { 1934 return BAD_VALUE; 1935 } 1936 1937 std::vector<int32_t> sensorToStop; 1938 for (auto &it : mSensorToChannel) { 1939 auto j = it.second.find(channel_handle); 1940 if (j != it.second.end()) { 1941 it.second.erase(j); 1942 if (it.second.empty()) { 1943 sensorToStop.push_back(it.first); 1944 } 1945 } 1946 } 1947 1948 if (activeSensorList != nullptr) { 1949 *activeSensorList = sensorToStop; 1950 } 1951 1952 // re-evaluate and send config for all sensor that need to be stopped 1953 bool ret = true; 1954 for (auto sensor_handle : sensorToStop) { 1955 Mutex::Autolock autoLock2(mLock); 1956 struct ConfigCmd cmd; 1957 initConfigCmd(&cmd, sensor_handle); 1958 1959 int result = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 1960 ret = ret && (result == sizeof(cmd)); 1961 } 1962 return ret ? NO_ERROR : BAD_VALUE; 1963 } 1964 1965 int HubConnection::configDirectReport(int sensor_handle, int channel_handle, int rate_level) { 1966 if (sensor_handle == -1 && rate_level == SENSOR_DIRECT_RATE_STOP) { 1967 return stopAllDirectReportOnChannel(channel_handle, nullptr); 1968 } 1969 1970 if (!isValidHandle(sensor_handle)) { 1971 return BAD_VALUE; 1972 } 1973 1974 // clamp to fast 1975 if (rate_level > SENSOR_DIRECT_RATE_FAST) { 1976 rate_level = SENSOR_DIRECT_RATE_FAST; 1977 } 1978 1979 // manage direct channel data structure 1980 Mutex::Autolock autoLock(mDirectChannelLock); 1981 auto i = mDirectChannel.find(channel_handle); 1982 if (i == mDirectChannel.end()) { 1983 return BAD_VALUE; 1984 } 1985 1986 auto j = mSensorToChannel.find(sensor_handle); 1987 if (j == mSensorToChannel.end()) { 1988 return BAD_VALUE; 1989 } 1990 1991 j->second.erase(channel_handle); 1992 if (rate_level != SENSOR_DIRECT_RATE_STOP) { 1993 j->second.insert(std::make_pair(channel_handle, rate_level)); 1994 } 1995 1996 Mutex::Autolock autoLock2(mLock); 1997 struct ConfigCmd cmd; 1998 initConfigCmd(&cmd, sensor_handle); 1999 2000 int ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); 2001 2002 if (rate_level == SENSOR_DIRECT_RATE_STOP) { 2003 ret = NO_ERROR; 2004 } else { 2005 ret = (ret == sizeof(cmd)) ? sensor_handle : BAD_VALUE; 2006 } 2007 return ret; 2008 } 2009 2010 bool HubConnection::isDirectReportSupported() const { 2011 return true; 2012 } 2013 #else // DIRECT_REPORT_ENABLED 2014 // nop functions if feature is turned off 2015 int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *) { 2016 return INVALID_OPERATION; 2017 } 2018 2019 int HubConnection::removeDirectChannel(int) { 2020 return INVALID_OPERATION; 2021 } 2022 2023 int HubConnection::configDirectReport(int, int, int) { 2024 return INVALID_OPERATION; 2025 } 2026 2027 void HubConnection::sendDirectReportEvent(const sensors_event_t *, size_t) { 2028 } 2029 2030 void HubConnection::mergeDirectReportRequest(struct ConfigCmd *, int) { 2031 } 2032 2033 bool HubConnection::isDirectReportSupported() const { 2034 return false; 2035 } 2036 #endif // DIRECT_REPORT_ENABLED 2037 2038 } // namespace android 2039