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