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