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