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, &param) != 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