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