1 /*
2  * Copyright (C) 2016 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 "contexthub.h"
18 
19 #include <cstring>
20 #include <errno.h>
21 #include <vector>
22 
23 #include "apptohostevent.h"
24 #include "log.h"
25 #include "resetreasonevent.h"
26 #include "sensorevent.h"
27 #include "util.h"
28 
29 namespace android {
30 
31 #define UNUSED_PARAM(param) (void) (param)
32 
33 constexpr int kCalibrationTimeoutMs(10000);
34 constexpr int kTestTimeoutMs(10000);
35 constexpr int kBridgeVersionTimeoutMs(500);
36 
37 struct SensorTypeNames {
38     SensorType sensor_type;
39     const char *name_abbrev;
40 };
41 
42 static const SensorTypeNames sensor_names_[] = {
43     { SensorType::Accel,                "accel" },
44     { SensorType::AnyMotion,            "anymo" },
45     { SensorType::NoMotion,             "nomo" },
46     { SensorType::SignificantMotion,    "sigmo" },
47     { SensorType::Flat,                 "flat" },
48     { SensorType::Gyro,                 "gyro" },
49     //{ SensorType::GyroUncal,            "gyro_uncal" },
50     { SensorType::Magnetometer,         "mag" },
51     //{ SensorType::MagnetometerUncal,    "mag_uncal" },
52     { SensorType::Barometer,            "baro" },
53     { SensorType::Temperature,          "temp" },
54     { SensorType::AmbientLightSensor,   "als" },
55     { SensorType::Proximity,            "prox" },
56     { SensorType::Orientation,          "orien" },
57     //{ SensorType::HeartRateECG,         "ecg" },
58     //{ SensorType::HeartRatePPG,         "ppg" },
59     { SensorType::Gravity,              "gravity" },
60     { SensorType::LinearAccel,          "linear_acc" },
61     { SensorType::RotationVector,       "rotation" },
62     { SensorType::GeomagneticRotationVector, "geomag" },
63     { SensorType::GameRotationVector,   "game" },
64     { SensorType::StepCount,            "step_cnt" },
65     { SensorType::StepDetect,           "step_det" },
66     { SensorType::Gesture,              "gesture" },
67     { SensorType::Tilt,                 "tilt" },
68     { SensorType::DoubleTwist,          "twist" },
69     { SensorType::DoubleTap,            "doubletap" },
70     { SensorType::WindowOrientation,    "win_orien" },
71     { SensorType::Hall,                 "hall" },
72     { SensorType::Activity,             "activity" },
73     { SensorType::Vsync,                "vsync" },
74     { SensorType::WristTilt,            "wrist_tilt" },
75 };
76 
77 struct SensorTypeAlias {
78     SensorType sensor_type;
79     SensorType sensor_alias;
80     const char *name_abbrev;
81 };
82 
83 static const SensorTypeAlias sensor_aliases_[] = {
84     { SensorType::Accel, SensorType::CompressedAccel, "compressed_accel" },
85 };
86 
SensorTypeIsAliasOf(SensorType sensor_type,SensorType alias)87 bool SensorTypeIsAliasOf(SensorType sensor_type, SensorType alias) {
88     for (size_t i = 0; i < ARRAY_LEN(sensor_aliases_); i++) {
89         if (sensor_aliases_[i].sensor_type == sensor_type
90                 && sensor_aliases_[i].sensor_alias == alias) {
91             return true;
92         }
93     }
94 
95     return false;
96 }
97 
SensorAbbrevNameToType(const char * sensor_name_abbrev)98 SensorType ContextHub::SensorAbbrevNameToType(const char *sensor_name_abbrev) {
99     for (unsigned int i = 0; i < ARRAY_LEN(sensor_names_); i++) {
100         if (strcmp(sensor_names_[i].name_abbrev, sensor_name_abbrev) == 0) {
101             return sensor_names_[i].sensor_type;
102         }
103     }
104 
105     return SensorType::Invalid_;
106 }
107 
SensorAbbrevNameToType(const std::string & abbrev_name)108 SensorType ContextHub::SensorAbbrevNameToType(const std::string& abbrev_name) {
109     return ContextHub::SensorAbbrevNameToType(abbrev_name.c_str());
110 }
111 
SensorTypeToAbbrevName(SensorType sensor_type)112 std::string ContextHub::SensorTypeToAbbrevName(SensorType sensor_type) {
113     for (unsigned int i = 0; i < ARRAY_LEN(sensor_names_); i++) {
114         if (sensor_names_[i].sensor_type == sensor_type) {
115             return std::string(sensor_names_[i].name_abbrev);
116         }
117     }
118 
119     for (unsigned int i = 0; i < ARRAY_LEN(sensor_aliases_); i++) {
120         if (sensor_aliases_[i].sensor_alias == sensor_type) {
121             return std::string(sensor_aliases_[i].name_abbrev);
122         }
123     }
124 
125     char buffer[24];
126     snprintf(buffer, sizeof(buffer), "unknown (%d)",
127              static_cast<int>(sensor_type));
128     return std::string(buffer);
129 }
130 
ListAllSensorAbbrevNames()131 std::string ContextHub::ListAllSensorAbbrevNames() {
132     std::string sensor_list;
133     for (unsigned int i = 0; i < ARRAY_LEN(sensor_names_); i++) {
134         sensor_list += sensor_names_[i].name_abbrev;
135         if (i < ARRAY_LEN(sensor_names_) - 1) {
136             sensor_list += ", ";
137         }
138     }
139 
140     return sensor_list;
141 }
142 
Flash(const std::string & filename)143 bool ContextHub::Flash(const std::string& filename) {
144     FILE *firmware_file = fopen(filename.c_str(), "r");
145     if (!firmware_file) {
146         LOGE("Failed to open firmware image: %d (%s)", errno, strerror(errno));
147         return false;
148     }
149 
150     fseek(firmware_file, 0, SEEK_END);
151     long file_size = ftell(firmware_file);
152     fseek(firmware_file, 0, SEEK_SET);
153 
154     auto firmware_data = std::vector<uint8_t>(file_size);
155     size_t bytes_read = fread(firmware_data.data(), sizeof(uint8_t),
156         file_size, firmware_file);
157     fclose(firmware_file);
158 
159     if (bytes_read != static_cast<size_t>(file_size)) {
160         LOGE("Read of firmware file returned %zu, expected %ld",
161             bytes_read, file_size);
162         return false;
163     }
164     return FlashSensorHub(firmware_data);
165 }
166 
CalibrateSensors(const std::vector<SensorSpec> & sensors)167 bool ContextHub::CalibrateSensors(const std::vector<SensorSpec>& sensors) {
168     bool success = ForEachSensor(sensors, [this](const SensorSpec &spec) -> bool {
169         return CalibrateSingleSensor(spec);
170     });
171 
172     if (success) {
173         success = SaveCalibration();
174     }
175     return success;
176 }
177 
TestSensors(const std::vector<SensorSpec> & sensors)178 bool ContextHub::TestSensors(const std::vector<SensorSpec>& sensors) {
179     bool success = ForEachSensor(sensors, [this](const SensorSpec &spec) -> bool {
180         return TestSingleSensor(spec);
181     });
182 
183     return success;
184 }
185 
EnableSensor(const SensorSpec & spec)186 bool ContextHub::EnableSensor(const SensorSpec& spec) {
187     ConfigureSensorRequest req;
188 
189     req.config.event_type = static_cast<uint32_t>(EventType::ConfigureSensor);
190     req.config.sensor_type = static_cast<uint8_t>(spec.sensor_type);
191     req.config.command = static_cast<uint8_t>(
192         ConfigureSensorRequest::CommandType::Enable);
193     if (spec.special_rate != SensorSpecialRate::None) {
194         req.config.rate = static_cast<uint32_t>(spec.special_rate);
195     } else {
196         req.config.rate = ConfigureSensorRequest::FloatRateToFixedPoint(
197             spec.rate_hz);
198     }
199     req.config.latency = spec.latency_ns;
200 
201     LOGI("Enabling sensor %d at rate %.0f Hz (special 0x%x) and latency %.2f ms",
202          spec.sensor_type, spec.rate_hz, spec.special_rate,
203          spec.latency_ns / 1000000.0f);
204     auto result = WriteEvent(req);
205     if (result == TransportResult::Success) {
206         sensor_is_active_[static_cast<int>(spec.sensor_type)] = true;
207         return true;
208     }
209 
210     LOGE("Could not enable sensor %d", spec.sensor_type);
211     return false;
212 }
213 
EnableSensors(const std::vector<SensorSpec> & sensors)214 bool ContextHub::EnableSensors(const std::vector<SensorSpec>& sensors) {
215     return ForEachSensor(sensors, [this](const SensorSpec &spec) -> bool {
216         return EnableSensor(spec);
217     });
218 }
219 
DisableSensor(SensorType sensor_type)220 bool ContextHub::DisableSensor(SensorType sensor_type) {
221     ConfigureSensorRequest req;
222 
223     req.config.event_type = static_cast<uint32_t>(EventType::ConfigureSensor);
224     req.config.sensor_type = static_cast<uint8_t>(sensor_type);
225     req.config.command = static_cast<uint8_t>(
226         ConfigureSensorRequest::CommandType::Disable);
227 
228     // Note that nanohub treats us as a single client, so if we call enable
229     // twice then disable once, the sensor will be disabled
230     LOGI("Disabling sensor %d", sensor_type);
231     auto result = WriteEvent(req);
232     if (result == TransportResult::Success) {
233         sensor_is_active_[static_cast<int>(sensor_type)] = false;
234         return true;
235     }
236 
237     LOGE("Could not disable sensor %d", sensor_type);
238     return false;
239 }
240 
DisableSensors(const std::vector<SensorSpec> & sensors)241 bool ContextHub::DisableSensors(const std::vector<SensorSpec>& sensors) {
242     return ForEachSensor(sensors, [this](const SensorSpec &spec) -> bool {
243         return DisableSensor(spec.sensor_type);
244     });
245 }
246 
DisableAllSensors()247 bool ContextHub::DisableAllSensors() {
248     bool success = true;
249 
250     for (size_t i = 0; i < ARRAY_LEN(sensor_names_); i++) {
251         success &= DisableSensor(sensor_names_[i].sensor_type);
252     }
253 
254     return success;
255 }
256 
DisableActiveSensors()257 bool ContextHub::DisableActiveSensors() {
258     bool success = true;
259 
260     LOGD("Disabling all active sensors");
261     for (size_t i = 0; i < ARRAY_LEN(sensor_names_); i++) {
262         if (sensor_is_active_[static_cast<int>(sensor_names_[i].sensor_type)]) {
263             success &= DisableSensor(sensor_names_[i].sensor_type);
264         }
265     }
266 
267     return success;
268 }
269 
PrintAllEvents(unsigned int limit)270 void ContextHub::PrintAllEvents(unsigned int limit) {
271     bool continuous = (limit == 0);
272     auto event_printer = [&limit, continuous](const SensorEvent& event) -> bool {
273         printf("%s", event.ToString().c_str());
274         return (continuous || --limit > 0);
275     };
276     ReadSensorEvents(event_printer);
277 }
278 
PrintBridgeVersion()279 bool ContextHub::PrintBridgeVersion() {
280     BridgeVersionInfoRequest request;
281     TransportResult result = WriteEvent(request);
282     if (result != TransportResult::Success) {
283         LOGE("Failed to send bridge version info request: %d",
284              static_cast<int>(result));
285         return false;
286     }
287 
288     bool success = false;
289     auto event_handler = [&success](const AppToHostEvent &event) -> bool {
290         bool keep_going = true;
291         auto rsp = reinterpret_cast<const BrHostEventData *>(event.GetDataPtr());
292         if (event.GetAppId() != kAppIdBridge) {
293             LOGD("Ignored event from unexpected app");
294         } else if (event.GetDataLen() < sizeof(BrHostEventData)) {
295             LOGE("Got short app to host event from bridge: length %u, expected "
296                  "at least %zu", event.GetDataLen(), sizeof(BrHostEventData));
297         } else if (rsp->msgId != BRIDGE_HOST_EVENT_MSG_VERSION_INFO) {
298             LOGD("Ignored bridge event with unexpected message ID %u", rsp->msgId);
299         } else if (rsp->status) {
300             LOGE("Bridge version info request failed with status %u", rsp->status);
301             keep_going = false;
302         } else if (event.GetDataLen() < (sizeof(BrHostEventData) +
303                                          sizeof(BrVersionInfoRsp))) {
304             LOGE("Got successful version info response with short payload: "
305                  "length %u, expected at least %zu", event.GetDataLen(),
306                  (sizeof(BrHostEventData) + sizeof(BrVersionInfoRsp)));
307             keep_going = false;
308         } else {
309             auto ver = reinterpret_cast<const struct BrVersionInfoRsp *>(
310                 rsp->payload);
311             printf("Bridge version info:\n"
312                    "  HW type:         0x%04x\n"
313                    "  OS version:      0x%04x\n"
314                    "  Variant version: 0x%08x\n"
315                    "  Bridge version:  0x%08x\n",
316                    ver->hwType, ver->osVer, ver->variantVer, ver->bridgeVer);
317             keep_going = false;
318             success = true;
319         }
320 
321         return keep_going;
322     };
323 
324     ReadAppEvents(event_handler, kBridgeVersionTimeoutMs);
325     return success;
326 }
327 
PrintSensorEvents(SensorType type,int limit)328 void ContextHub::PrintSensorEvents(SensorType type, int limit) {
329     bool continuous = (limit == 0);
330     auto event_printer = [type, &limit, continuous](const SensorEvent& event) -> bool {
331         SensorType event_source = event.GetSensorType();
332         if (event_source == type || SensorTypeIsAliasOf(type, event_source)) {
333             printf("%s", event.ToString().c_str());
334             limit -= event.GetNumSamples();
335         }
336         return (continuous || limit > 0);
337     };
338     ReadSensorEvents(event_printer);
339 }
340 
PrintSensorEvents(const std::vector<SensorSpec> & sensors,int limit)341 void ContextHub::PrintSensorEvents(const std::vector<SensorSpec>& sensors, int limit) {
342     bool continuous = (limit == 0);
343     auto event_printer = [&sensors, &limit, continuous](const SensorEvent& event) -> bool {
344         SensorType event_source = event.GetSensorType();
345         for (unsigned int i = 0; i < sensors.size(); i++) {
346             if (sensors[i].sensor_type == event_source
347                     || SensorTypeIsAliasOf(sensors[i].sensor_type, event_source)) {
348                 printf("%s", event.ToString().c_str());
349                 limit -= event.GetNumSamples();
350                 break;
351             }
352         }
353         return (continuous || limit > 0);
354     };
355     ReadSensorEvents(event_printer);
356 }
357 
358 // Protected methods -----------------------------------------------------------
359 
CalibrateSingleSensor(const SensorSpec & sensor)360 bool ContextHub::CalibrateSingleSensor(const SensorSpec& sensor) {
361     ConfigureSensorRequest req;
362 
363     req.config.event_type = static_cast<uint32_t>(EventType::ConfigureSensor);
364     req.config.sensor_type = static_cast<uint8_t>(sensor.sensor_type);
365     req.config.command = static_cast<uint8_t>(
366         ConfigureSensorRequest::CommandType::Calibrate);
367 
368     LOGI("Issuing calibration request to sensor %d (%s)", sensor.sensor_type,
369          ContextHub::SensorTypeToAbbrevName(sensor.sensor_type).c_str());
370     auto result = WriteEvent(req);
371     if (result != TransportResult::Success) {
372         LOGE("Failed to calibrate sensor %d", sensor.sensor_type);
373         return false;
374     }
375 
376     bool success = false;
377     auto cal_event_handler = [this, &sensor, &success](const AppToHostEvent &event) -> bool {
378         if (event.IsCalibrationEventForSensor(sensor.sensor_type)) {
379             success = HandleCalibrationResult(sensor, event);
380             return false;
381         }
382         return true;
383     };
384 
385     result = ReadAppEvents(cal_event_handler, kCalibrationTimeoutMs);
386     if (result != TransportResult::Success) {
387       LOGE("Error reading calibration response %d", static_cast<int>(result));
388       return false;
389     }
390 
391     return success;
392 }
393 
TestSingleSensor(const SensorSpec & sensor)394 bool ContextHub::TestSingleSensor(const SensorSpec& sensor) {
395     ConfigureSensorRequest req;
396 
397     req.config.event_type = static_cast<uint32_t>(EventType::ConfigureSensor);
398     req.config.sensor_type = static_cast<uint8_t>(sensor.sensor_type);
399     req.config.command = static_cast<uint8_t>(
400         ConfigureSensorRequest::CommandType::SelfTest);
401 
402     LOGI("Issuing test request to sensor %d (%s)", sensor.sensor_type,
403          ContextHub::SensorTypeToAbbrevName(sensor.sensor_type).c_str());
404     auto result = WriteEvent(req);
405     if (result != TransportResult::Success) {
406         LOGE("Failed to test sensor %d", sensor.sensor_type);
407         return false;
408     }
409 
410     bool success = false;
411     auto test_event_handler = [this, &sensor, &success](const AppToHostEvent &event) -> bool {
412         if (event.IsTestEventForSensor(sensor.sensor_type)) {
413             success = HandleTestResult(sensor, event);
414             return false;
415         }
416         return true;
417     };
418 
419     result = ReadAppEvents(test_event_handler, kTestTimeoutMs);
420     if (result != TransportResult::Success) {
421       LOGE("Error reading test response %d", static_cast<int>(result));
422       return false;
423     }
424 
425     return success;
426 }
427 
ForEachSensor(const std::vector<SensorSpec> & sensors,std::function<bool (const SensorSpec &)> callback)428 bool ContextHub::ForEachSensor(const std::vector<SensorSpec>& sensors,
429         std::function<bool(const SensorSpec&)> callback) {
430     bool success = true;
431 
432     for (unsigned int i = 0; success && i < sensors.size(); i++) {
433         success &= callback(sensors[i]);
434     }
435 
436     return success;
437 }
438 
HandleCalibrationResult(const SensorSpec & sensor,const AppToHostEvent & event)439 bool ContextHub::HandleCalibrationResult(const SensorSpec& sensor,
440         const AppToHostEvent &event) {
441     auto hdr = reinterpret_cast<const SensorAppEventHeader *>(event.GetDataPtr());
442     if (hdr->status) {
443         LOGE("Calibration of sensor %d (%s) failed with status %u",
444              sensor.sensor_type,
445              ContextHub::SensorTypeToAbbrevName(sensor.sensor_type).c_str(),
446              hdr->status);
447         return false;
448     }
449 
450     bool success = false;
451     switch (sensor.sensor_type) {
452       case SensorType::Accel:
453       case SensorType::Gyro: {
454         auto result = reinterpret_cast<const TripleAxisCalibrationResult *>(
455             event.GetDataPtr());
456         success = SetCalibration(sensor.sensor_type, result->xBias,
457                                  result->yBias, result->zBias);
458         break;
459       }
460 
461       case SensorType::Barometer: {
462         auto result = reinterpret_cast<const FloatCalibrationResult *>(
463             event.GetDataPtr());
464         if (sensor.have_cal_ref) {
465             success = SetCalibration(sensor.sensor_type,
466                                      (sensor.cal_ref - result->value));
467         }
468         break;
469       }
470 
471       case SensorType::Proximity: {
472         auto result = reinterpret_cast<const FourAxisCalibrationResult *>(
473             event.GetDataPtr());
474         success = SetCalibration(sensor.sensor_type, result->xBias,
475                                  result->yBias, result->zBias, result->wBias);
476         break;
477       }
478 
479       case SensorType::AmbientLightSensor: {
480         auto result = reinterpret_cast<const FloatCalibrationResult *>(
481             event.GetDataPtr());
482         if (sensor.have_cal_ref && (result->value != 0.0f)) {
483             success = SetCalibration(sensor.sensor_type,
484                                      (sensor.cal_ref / result->value));
485         }
486         break;
487       }
488 
489       default:
490         LOGE("Calibration not supported for sensor type %d",
491              static_cast<int>(sensor.sensor_type));
492     }
493 
494     return success;
495 }
496 
HandleTestResult(const SensorSpec & sensor,const AppToHostEvent & event)497 bool ContextHub::HandleTestResult(const SensorSpec& sensor,
498         const AppToHostEvent &event) {
499     auto hdr = reinterpret_cast<const SensorAppEventHeader *>(event.GetDataPtr());
500     if (!hdr->status) {
501         LOGI("Self-test of sensor %d (%s) succeeded",
502              sensor.sensor_type,
503              ContextHub::SensorTypeToAbbrevName(sensor.sensor_type).c_str());
504         return true;
505     } else {
506         LOGE("Self-test of sensor %d (%s) failed with status %u",
507              sensor.sensor_type,
508              ContextHub::SensorTypeToAbbrevName(sensor.sensor_type).c_str(),
509              hdr->status);
510         return false;
511     }
512 }
513 
ReadAppEvents(std::function<bool (const AppToHostEvent &)> callback,int timeout_ms)514 ContextHub::TransportResult ContextHub::ReadAppEvents(
515         std::function<bool(const AppToHostEvent&)> callback, int timeout_ms) {
516     using Milliseconds = std::chrono::milliseconds;
517 
518     TransportResult result;
519     bool timeout_required = timeout_ms > 0;
520     bool keep_going = true;
521 
522     while (keep_going) {
523         if (timeout_required && timeout_ms <= 0) {
524             return TransportResult::Timeout;
525         }
526 
527         std::unique_ptr<ReadEventResponse> event;
528 
529         SteadyClock start_time = std::chrono::steady_clock::now();
530         result = ReadEvent(&event, timeout_ms);
531         SteadyClock end_time = std::chrono::steady_clock::now();
532 
533         auto delta = end_time - start_time;
534         timeout_ms -= std::chrono::duration_cast<Milliseconds>(delta).count();
535 
536         if (result == TransportResult::Success && event->IsAppToHostEvent()) {
537             AppToHostEvent *app_event = reinterpret_cast<AppToHostEvent*>(
538                 event.get());
539             keep_going = callback(*app_event);
540         } else {
541             if (result != TransportResult::Success) {
542                 LOGE("Error %d while reading", static_cast<int>(result));
543                 if (result != TransportResult::ParseFailure) {
544                     return result;
545                 }
546             } else {
547                 LOGD("Ignoring non-app-to-host event");
548             }
549         }
550     }
551 
552     return TransportResult::Success;
553 }
554 
ReadSensorEvents(std::function<bool (const SensorEvent &)> callback)555 void ContextHub::ReadSensorEvents(std::function<bool(const SensorEvent&)> callback) {
556     TransportResult result;
557     bool keep_going = true;
558 
559     while (keep_going) {
560         std::unique_ptr<ReadEventResponse> event;
561         result = ReadEvent(&event);
562         if (result == TransportResult::Success && event->IsSensorEvent()) {
563             SensorEvent *sensor_event = reinterpret_cast<SensorEvent*>(
564                 event.get());
565             keep_going = callback(*sensor_event);
566         } else {
567             if (result != TransportResult::Success) {
568                 LOGE("Error %d while reading", static_cast<int>(result));
569                 if (result != TransportResult::ParseFailure) {
570                     break;
571                 }
572             } else {
573                 LOGD("Ignoring non-sensor event");
574             }
575         }
576     }
577 }
578 
SendCalibrationData(SensorType sensor_type,const std::vector<uint8_t> & cal_data)579 bool ContextHub::SendCalibrationData(SensorType sensor_type,
580         const std::vector<uint8_t>& cal_data) {
581     ConfigureSensorRequest req;
582 
583     req.config.event_type = static_cast<uint32_t>(EventType::ConfigureSensor);
584     req.config.sensor_type = static_cast<uint8_t>(sensor_type);
585     req.config.command = static_cast<uint8_t>(
586         ConfigureSensorRequest::CommandType::ConfigData);
587     req.SetAdditionalData(cal_data);
588 
589     auto result = WriteEvent(req);
590     return (result == TransportResult::Success);
591 }
592 
WriteEvent(const WriteEventRequest & request)593 ContextHub::TransportResult ContextHub::WriteEvent(
594         const WriteEventRequest& request) {
595     return WriteEvent(request.GetBytes());
596 }
597 
ReadEvent(std::unique_ptr<ReadEventResponse> * response,int timeout_ms)598 ContextHub::TransportResult ContextHub::ReadEvent(
599         std::unique_ptr<ReadEventResponse>* response, int timeout_ms) {
600     std::vector<uint8_t> responseBuf(256);
601     ContextHub::TransportResult result = ReadEvent(responseBuf, timeout_ms);
602     if (result == TransportResult::Success) {
603         *response = ReadEventResponse::FromBytes(responseBuf);
604         if (*response == nullptr) {
605             result = TransportResult::ParseFailure;
606         }
607     }
608     return result;
609 }
610 
611 // Stubs for subclasses that don't implement calibration support
LoadCalibration()612 bool ContextHub::LoadCalibration() {
613     LOGE("Loading calibration data not implemented");
614     return false;
615 }
616 
SetCalibration(SensorType sensor_type,int32_t data)617 bool ContextHub::SetCalibration(SensorType sensor_type, int32_t data) {
618     UNUSED_PARAM(sensor_type);
619     UNUSED_PARAM(data);
620     return false;
621 }
622 
SetCalibration(SensorType sensor_type,float data)623 bool ContextHub::SetCalibration(SensorType sensor_type, float data) {
624     UNUSED_PARAM(sensor_type);
625     UNUSED_PARAM(data);
626     return false;
627 }
628 
SetCalibration(SensorType sensor_type,int32_t x,int32_t y,int32_t z)629 bool ContextHub::SetCalibration(SensorType sensor_type, int32_t x,
630         int32_t y, int32_t z) {
631     UNUSED_PARAM(sensor_type);
632     UNUSED_PARAM(x);
633     UNUSED_PARAM(y);
634     UNUSED_PARAM(z);
635     return false;
636 }
637 
SetCalibration(SensorType sensor_type,int32_t x,int32_t y,int32_t z,int32_t w)638 bool ContextHub::SetCalibration(SensorType sensor_type, int32_t x,
639         int32_t y, int32_t z, int32_t w) {
640     UNUSED_PARAM(sensor_type);
641     UNUSED_PARAM(x);
642     UNUSED_PARAM(y);
643     UNUSED_PARAM(z);
644     UNUSED_PARAM(w);
645     return false;
646 }
647 
SaveCalibration()648 bool ContextHub::SaveCalibration() {
649     LOGE("Saving calibration data not implemented");
650     return false;
651 }
652 
653 }  // namespace android
654