summaryrefslogtreecommitdiff
path: root/chromium/services/device/generic_sensor/platform_sensor_accelerometer_mac.cc
blob: 8c1696c71bdac97d205f8386c5f0e5b9b94f2084 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// 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