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
getInstance()99 HubConnection *HubConnection::getInstance()
100 {
101 Mutex::Autolock autoLock(sInstanceLock);
102 if (sInstance == NULL) {
103 sInstance = new HubConnection;
104 }
105 return sInstance;
106 }
107
isActivitySensor(int sensorIndex)108 static bool isActivitySensor(int sensorIndex) {
109 return sensorIndex >= COMMS_SENSOR_ACTIVITY_FIRST
110 && sensorIndex <= COMMS_SENSOR_ACTIVITY_LAST;
111 }
112
HubConnection()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
~HubConnection()265 HubConnection::~HubConnection()
266 {
267 close(mFd);
268 }
269
onFirstRef()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
enableSchedFifoMode(sp<HubConnection> hub)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
initCheck() const318 status_t HubConnection::initCheck() const
319 {
320 return mFd < 0 ? UNKNOWN_ERROR : OK;
321 }
322
getAliveCheck()323 status_t HubConnection::getAliveCheck()
324 {
325 return OK;
326 }
327
readSettings(File * file)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
getCalibrationInt32(const sp<JSONObject> & settings,const char * key,int32_t * out,size_t numArgs)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
getCalibrationFloat(const sp<JSONObject> & settings,const char * key,float out[3])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
getInt32Setting(const sp<JSONObject> & settings,const char * key)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
getFloatSetting(const sp<JSONObject> & settings,const char * key)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
loadSensorSettings(sp<JSONObject> * settings,sp<JSONObject> * saved_settings)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
saveSensorSettings() const444 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
initEv(sensors_event_t * ev,uint64_t timestamp,uint32_t type,uint32_t sensor)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
getWakeEventCount()512 ssize_t HubConnection::getWakeEventCount()
513 {
514 return mWakeEventCount;
515 }
516
decrementWakeEventCount()517 ssize_t HubConnection::decrementWakeEventCount()
518 {
519 return --mWakeEventCount;
520 }
521
isWakeEvent(int32_t sensor)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
protectIfWakeEvent(int32_t sensor)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
releaseWakeLockIfAppropriate()547 void HubConnection::releaseWakeLockIfAppropriate()
548 {
549 if (mWakelockHeld && (mWakeEventCount == 0)) {
550 mWakelockHeld = false;
551 release_wake_lock(WAKELOCK_NAME);
552 }
553 }
554
processSample(uint64_t timestamp,uint32_t type,uint32_t sensor,struct OneAxisSample * sample,bool highAccuracy)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
magAccuracyUpdate(sensors_vec_t * sv)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
processSample(uint64_t timestamp,uint32_t type,uint32_t sensor,struct RawThreeAxisSample * sample,bool highAccuracy)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
processSample(uint64_t timestamp,uint32_t type,uint32_t sensor,struct ThreeAxisSample * sample,bool highAccuracy)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
discardInotifyEvent()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
waitOnNanohubLock()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
restoreSensorState()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
postOsLog(uint8_t * buf,ssize_t len)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
processAppData(uint8_t * buf,ssize_t len)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
processBuf(uint8_t * buf,size_t len)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
sendCalibrationOffsets()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
threadLoop()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
read(sensors_event_t * ev,size_t size)1486 ssize_t HubConnection::read(sensors_event_t *ev, size_t size) {
1487 return mRing.read(ev, size);
1488 }
1489
setActivityCallback(ActivityEventHandler * eventHandler)1490 void HubConnection::setActivityCallback(ActivityEventHandler *eventHandler)
1491 {
1492 Mutex::Autolock autoLock(mLock);
1493 mActivityEventHandler = eventHandler;
1494 }
1495
initConfigCmd(struct ConfigCmd * cmd,int handle)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
queueActivate(int handle,bool enable)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
queueSetDelay(int handle,nsecs_t sampling_period_ns)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
queueBatch(int handle,nsecs_t sampling_period_ns,nsecs_t max_report_latency_ns)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
queueFlush(int handle)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
queueDataInternal(int handle,void * data,size_t length)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
queueData(int handle,void * data,size_t length)1663 void HubConnection::queueData(int handle, void *data, size_t length)
1664 {
1665 Mutex::Autolock autoLock(mLock);
1666 queueDataInternal(handle, data, length);
1667 }
1668
setOperationParameter(const additional_info_event_t & info)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
initNanohubLock()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
write(const sensors_event_t * ev,size_t n)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
queueUsbMagBias()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
initializeUinputNode()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
sendFolioEvent(int32_t data)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
sendDirectReportEvent(const sensors_event_t * nev,size_t n)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
mergeDirectReportRequest(struct ConfigCmd * cmd,int handle)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
addDirectChannel(const struct sensors_direct_mem_t * mem)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
removeDirectChannel(int channel_handle)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
stopAllDirectReportOnChannel(int channel_handle,std::vector<int32_t> * activeSensorList)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
configDirectReport(int sensor_handle,int channel_handle,int rate_level)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
isDirectReportSupported() const2010 bool HubConnection::isDirectReportSupported() const {
2011 return true;
2012 }
2013 #else // DIRECT_REPORT_ENABLED
2014 // nop functions if feature is turned off
addDirectChannel(const struct sensors_direct_mem_t *)2015 int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *) {
2016 return INVALID_OPERATION;
2017 }
2018
removeDirectChannel(int)2019 int HubConnection::removeDirectChannel(int) {
2020 return INVALID_OPERATION;
2021 }
2022
configDirectReport(int,int,int)2023 int HubConnection::configDirectReport(int, int, int) {
2024 return INVALID_OPERATION;
2025 }
2026
sendDirectReportEvent(const sensors_event_t *,size_t)2027 void HubConnection::sendDirectReportEvent(const sensors_event_t *, size_t) {
2028 }
2029
mergeDirectReportRequest(struct ConfigCmd *,int)2030 void HubConnection::mergeDirectReportRequest(struct ConfigCmd *, int) {
2031 }
2032
isDirectReportSupported() const2033 bool HubConnection::isDirectReportSupported() const {
2034 return false;
2035 }
2036 #endif // DIRECT_REPORT_ENABLED
2037
2038 } // namespace android
2039