File: platform_sensor.h

package info (click to toggle)
chromium 145.0.7632.159-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,976,224 kB
  • sloc: cpp: 36,198,469; ansic: 7,634,080; javascript: 3,564,060; python: 1,649,622; xml: 838,470; asm: 717,087; pascal: 185,708; sh: 88,786; perl: 88,718; objc: 79,984; sql: 59,811; cs: 42,452; fortran: 24,101; makefile: 21,144; tcl: 15,277; php: 14,022; yacc: 9,066; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,328; ada: 727; jsp: 228; sed: 36
file content (180 lines) | stat: -rw-r--r-- 6,964 bytes parent folder | download | duplicates (9)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_H_
#define SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_H_

#include <list>
#include <map>
#include <memory>
#include <optional>

#include "base/functional/callback_forward.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/thread_annotations.h"
#include "mojo/public/cpp/system/buffer.h"
#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
#include "services/device/public/mojom/sensor.mojom.h"

namespace device {

class PlatformSensorProvider;
class PlatformSensorConfiguration;
template <class T>
struct SensorReadingSharedBufferImpl;
using SensorReadingSharedBuffer = SensorReadingSharedBufferImpl<void>;

// Base class for the sensors provided by the platform. Concrete instances of
// this class are created by platform specific PlatformSensorProvider.
class PlatformSensor : public base::RefCountedThreadSafe<PlatformSensor> {
 public:
  // The interface that must be implemented by PlatformSensor clients.
  class Client {
   public:
    virtual void OnSensorReadingChanged(mojom::SensorType type) = 0;
    virtual void OnSensorError() = 0;
    virtual bool IsSuspended() = 0;

   protected:
    virtual ~Client() {}
  };

  PlatformSensor(const PlatformSensor&) = delete;
  PlatformSensor& operator=(const PlatformSensor&) = delete;

  virtual mojom::ReportingMode GetReportingMode() = 0;
  virtual PlatformSensorConfiguration GetDefaultConfiguration() = 0;
  virtual bool CheckSensorConfiguration(
      const PlatformSensorConfiguration& configuration) = 0;

  // Can be overridden to return the sensor maximum sampling frequency
  // value obtained from the platform if it is available. If platform
  // does not provide maximum sampling frequency this method must
  // return default frequency.
  // The default implementation returns default frequency.
  virtual double GetMaximumSupportedFrequency();

  // Can be overridden to return the sensor minimum sampling frequency.
  // The default implementation returns '1.0 / (60 * 60)', i.e. once per hour.
  virtual double GetMinimumSupportedFrequency();

  // Can be overridden to reset this sensor by the PlatformSensorProvider.
  virtual void SensorReplaced();

  // Checks if new value is significantly different than old value.
  // When the reading we get does not differ significantly from our current
  // value, we discard this reading and do not emit any events. This is a
  // privacy measure to avoid giving readings that are too specific.
  virtual bool IsSignificantlyDifferent(const SensorReading& lhs,
                                        const SensorReading& rhs,
                                        mojom::SensorType sensor_type);

  mojom::SensorType GetType() const;

  bool StartListening(Client* client,
                      const PlatformSensorConfiguration& config);
  bool StopListening(Client* client, const PlatformSensorConfiguration& config);
  // Stops all the configurations tied to the |client|, but the |client| still
  // gets notification.
  bool StopListening(Client* client);

  void UpdateSensor();

  void AddClient(Client*);
  void RemoveClient(Client*);

  bool GetLatestReading(SensorReading* result);
  // Return the last raw (i.e. unrounded) sensor reading.
  bool GetLatestRawReading(SensorReading* result) const;
  // Returns 'true' if the sensor is started; returns 'false' otherwise.
  bool IsActiveForTesting() const;
  using ConfigMap = std::map<Client*, std::list<PlatformSensorConfiguration>>;
  const ConfigMap& GetConfigMapForTesting() const;

  // Called by API users to post a task on |main_task_runner_| when run from a
  // different sequence.
  void PostTaskToMainSequence(const base::Location& location,
                              base::OnceClosure task);

 protected:
  virtual ~PlatformSensor();
  PlatformSensor(mojom::SensorType type,
                 SensorReadingSharedBuffer* reading_buffer,
                 base::WeakPtr<PlatformSensorProvider> provider);

  using ReadingBuffer = SensorReadingSharedBuffer;

  virtual bool UpdateSensorInternal(const ConfigMap& configurations);
  virtual bool StartSensor(
      const PlatformSensorConfiguration& configuration) = 0;
  virtual void StopSensor() = 0;

  // Updates the shared buffer with new sensor reading data and posts a task to
  // invoke NotifySensorReadingChanged() on |main_task_runner_|.
  // Note: this method is thread-safe.
  void UpdateSharedBufferAndNotifyClients(const SensorReading& reading);

  void NotifySensorReadingChanged();
  void NotifySensorError();

  void ResetReadingBuffer();

  // Returns the task runner where this object has been created. Subclasses can
  // use it to post tasks to the right sequence when running on a different task
  // runner.
  scoped_refptr<base::SequencedTaskRunner> main_task_runner() const {
    return main_task_runner_;
  }

  base::ObserverList<Client, true>::Unchecked clients_;

  base::WeakPtr<PlatformSensor> AsWeakPtr();

 private:
  friend class base::RefCountedThreadSafe<PlatformSensor>;

  // Updates shared buffer with provided SensorReading. For sensors whose
  // reporting mode is ON_CHANGE, |reading_buffer_| is updated only if
  // |reading| and its rounded version pass the required threshold and
  // significance checks. Returns true if |reading_buffer_| has been updated,
  // and false otherwise.
  // Note: this method is thread-safe.
  bool UpdateSharedBuffer(const SensorReading& reading)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);

  // Stores an empty reading into the shared buffer and resets
  // |last_{raw,rounded}_reading|.
  void ResetSharedBuffer() EXCLUSIVE_LOCKS_REQUIRED(lock_);

  // Writes the given reading to |reading_buffer_|. Requires |is_active_| to be
  // true.
  void WriteToSharedBuffer(const SensorReading&)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);

  scoped_refptr<base::SequencedTaskRunner> main_task_runner_;

  // Pointer to the buffer where sensor readings will be written. The buffer is
  // owned by `provider_` and must not be accessed if `provider_` is null.
  raw_ptr<SensorReadingSharedBuffer> reading_buffer_;

  mojom::SensorType type_;
  ConfigMap config_map_;
  base::WeakPtr<PlatformSensorProvider> provider_;
  bool is_active_ GUARDED_BY(lock_);
  std::optional<SensorReading> last_raw_reading_ GUARDED_BY(lock_);
  std::optional<SensorReading> last_rounded_reading_ GUARDED_BY(lock_);
  // Protect last_raw_reading_ & last_rounded_reading_.
  mutable base::Lock lock_;
  base::WeakPtrFactory<PlatformSensor> weak_factory_{this};
};

}  // namespace device

#endif  // SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_H_