blob: 8c1696c71bdac97d205f8386c5f0e5b9b94f2084 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/device/generic_sensor/platform_sensor_accelerometer_mac.h"
#include <stdint.h>
#include <cmath>
#include "base/bind.h"
#include "device/base/synchronization/shared_memory_seqlock_buffer.h"
#include "services/device/generic_sensor/generic_sensor_consts.h"
#include "services/device/generic_sensor/platform_sensor_provider_mac.h"
#include "services/device/public/cpp/generic_sensor/sensor_traits.h"
#include "third_party/sudden_motion_sensor/sudden_motion_sensor_mac.h"
namespace {
constexpr double kGravityThreshold = device::kMeanGravity * 0.01;
bool IsSignificantlyDifferent(const device::SensorReading& reading1,
const device::SensorReading& reading2) {
return (std::fabs(reading1.accel.x - reading2.accel.x) >=
kGravityThreshold) ||
(std::fabs(reading1.accel.y - reading2.accel.y) >=
kGravityThreshold) ||
(std::fabs(reading1.accel.z - reading2.accel.z) >= kGravityThreshold);
}
} // namespace
namespace device {
using mojom::SensorType;
PlatformSensorAccelerometerMac::PlatformSensorAccelerometerMac(
mojo::ScopedSharedBufferMapping mapping,
PlatformSensorProvider* provider)
: PlatformSensor(SensorType::ACCELEROMETER, std::move(mapping), provider),
sudden_motion_sensor_(SuddenMotionSensor::Create()) {}
PlatformSensorAccelerometerMac::~PlatformSensorAccelerometerMac() = default;
mojom::ReportingMode PlatformSensorAccelerometerMac::GetReportingMode() {
return mojom::ReportingMode::ON_CHANGE;
}
bool PlatformSensorAccelerometerMac::CheckSensorConfiguration(
const PlatformSensorConfiguration& configuration) {
return configuration.frequency() > 0 &&
configuration.frequency() <=
SensorTraits<SensorType::ACCELEROMETER>::kMaxAllowedFrequency;
}
PlatformSensorConfiguration
PlatformSensorAccelerometerMac::GetDefaultConfiguration() {
return PlatformSensorConfiguration(
SensorTraits<SensorType::ACCELEROMETER>::kDefaultFrequency);
}
bool PlatformSensorAccelerometerMac::StartSensor(
const PlatformSensorConfiguration& configuration) {
if (!sudden_motion_sensor_)
return false;
float axis_value[3];
if (!sudden_motion_sensor_->ReadSensorValues(axis_value))
return false;
timer_.Start(
FROM_HERE,
base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond /
configuration.frequency()),
this, &PlatformSensorAccelerometerMac::PollForData);
return true;
}
void PlatformSensorAccelerometerMac::StopSensor() {
timer_.Stop();
}
void PlatformSensorAccelerometerMac::PollForData() {
// Retrieve per-axis calibrated values.
float axis_value[3];
if (!sudden_motion_sensor_->ReadSensorValues(axis_value))
return;
SensorReading reading;
reading.accel.timestamp =
(base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
reading.accel.x = axis_value[0] * kMeanGravity;
reading.accel.y = axis_value[1] * kMeanGravity;
reading.accel.z = axis_value[2] * kMeanGravity;
if (IsSignificantlyDifferent(reading_, reading)) {
reading_ = reading;
UpdateSharedBufferAndNotifyClients(reading);
}
}
} // namespace device