File: accelerometer_reader.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (154 lines) | stat: -rw-r--r-- 5,706 bytes parent folder | download | duplicates (7)
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
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_ACCELEROMETER_ACCELEROMETER_READER_H_
#define ASH_ACCELEROMETER_ACCELEROMETER_READER_H_

#include "ash/accelerometer/accelerometer_types.h"
#include "ash/ash_export.h"
#include "ash/public/cpp/tablet_mode_observer.h"
#include "base/memory/ref_counted.h"
#include "base/no_destructor.h"
#include "base/observer_list.h"

namespace base {
class SequencedTaskRunner;
}  // namespace base

namespace ash {

enum class ECLidAngleDriverStatus { UNKNOWN, SUPPORTED, NOT_SUPPORTED };

class AccelerometerProviderInterface;

// AccelerometerReader should only be used on the UI thread.
// It notifies observers if EC Lid Angle Driver is supported, and provides
// accelerometers' (lid and base) samples.
// The current usages of accelerometers' samples are for calculating the angle
// between the lid and the base, which can be substituted by EC Lid Angle
// Driver, if it exists, and the auto rotation, which only needs
// lid-accelerometer's data.
// Therefore, if EC Lid Angle Driver is present, base-accelerometer's samples
// may be ignored and not sent to the observers.
class ASH_EXPORT AccelerometerReader {
 public:
  // An interface to receive data from the AccelerometerReader.
  class Observer {
   public:
    // Normally called only once, when
    // |AcceleromterProviderInterface::ec_lid_angle_driver_status_| is set to
    // either SUPPORTED or NOT_SUPPORTED, unless the lid angle driver is
    // late-present after timed out, which will be called twice with
    // |is_supported| being false and true respectively.
    // It's guaranteed to be called before |OnAccelerometerUpdated|.
    virtual void OnECLidAngleDriverStatusChanged(bool is_supported) = 0;
    virtual void OnAccelerometerUpdated(const AccelerometerUpdate& update) = 0;

   protected:
    virtual ~Observer() {}
  };

  static AccelerometerReader* GetInstance();

  void Initialize();

  // Add/Remove observers.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Accelerometer file reader starts/stops listening to tablet mode controller.
  void StartListenToTabletModeController();
  void StopListenToTabletModeController();

  // Controls the availability of emitting acccelerometer reader events to
  // its observers. This shouldn't be called normally, but Tast tests should
  // be able to control the accelerometer feature.
  void SetEnabled(bool enabled);

  void SetECLidAngleDriverStatusForTesting(
      ECLidAngleDriverStatus ec_lid_angle_driver_status);

 protected:
  AccelerometerReader();
  AccelerometerReader(const AccelerometerReader&) = delete;
  AccelerometerReader& operator=(const AccelerometerReader&) = delete;
  virtual ~AccelerometerReader();

 private:
  friend class base::NoDestructor<AccelerometerReader>;

  // Worker that will run on the base::SequencedTaskRunner provided to
  // Initialize. It will determine accelerometer configuration, read the data,
  // and notify observers.
  scoped_refptr<AccelerometerProviderInterface> accelerometer_provider_;
};

class ASH_EXPORT AccelerometerProviderInterface
    : public base::RefCountedThreadSafe<AccelerometerProviderInterface>,
      public TabletModeObserver {
 public:
  // Prepare and start async initialization.
  virtual void PrepareAndInitialize() = 0;
  // With ChromeOS EC lid angle driver present, it's triggered when the device
  // is physically used as a tablet (even thought its UI might be in clamshell
  // mode), cancelled otherwise.
  virtual void TriggerRead() = 0;
  virtual void CancelRead() = 0;

  // TabletModeObserver:
  void OnTabletPhysicalStateChanged() override;

  // Add/Remove observers.
  void AddObserver(AccelerometerReader::Observer* observer);
  void RemoveObserver(AccelerometerReader::Observer* observer);

  // Start/Stop listening to tablet mode controller.
  void StartListenToTabletModeController();
  void StopListenToTabletModeController();

  // Set emitting events (samples) to observers or not.
  void SetEmitEvents(bool emit_events);

  void SetECLidAngleDriverStatusForTesting(ECLidAngleDriverStatus status);

 protected:
  AccelerometerProviderInterface();
  ~AccelerometerProviderInterface() override;

  // Used in |OnTabletPhysicalStateChanged()|. As there might be
  // initialization steps, each implementation can override this function to
  // determine if this class is ready to process the state changed.
  // If returns true, |OnTabletPhysicalStateChanged()| will be skipped, and it's
  // the implementation's responsibility to call it again when the class is
  // ready. If returns false, |OnTabletPhysicalStateChanged()| will be processed
  // as usual.
  // Default to return false.
  virtual bool ShouldDelayOnTabletPhysicalStateChanged();

  void SetECLidAngleDriverStatus(ECLidAngleDriverStatus status);
  ECLidAngleDriverStatus GetECLidAngleDriverStatus() const;

  void NotifyAccelerometerUpdated(const AccelerometerUpdate& update);

  // Set in the constructor.
  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;

 private:
  // State of ChromeOS EC lid angle driver, if SUPPORTED, it means EC can handle
  // lid angle calculation.
  ECLidAngleDriverStatus ec_lid_angle_driver_status_ =
      ECLidAngleDriverStatus::UNKNOWN;

  bool emit_events_ = true;

  // The observers to notify of accelerometer updates.
  // Bound to the UI thread.
  base::ObserverList<AccelerometerReader::Observer>::Unchecked observers_;

  friend class base::RefCountedThreadSafe<AccelerometerProviderInterface>;
};

}  // namespace ash

#endif  // ASH_ACCELEROMETER_ACCELEROMETER_READER_H_