Commit 2079112a authored by Harvey Yang's avatar Harvey Yang Committed by Chromium LUCI CQ

accelerometer: Refactor AccelerometerFileReader

This commit simplifies the logic and puts only the blocking code in the
created USER_VISIBLE sequenced task runner. In this way, most of the
tasks are run on the UI thread.

BUG=b:175355860
TEST=run on octopus

Change-Id: I50b9380c5d0667513430f4f3b685317687be844d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586288
Commit-Queue: Cheng-Hao Yang <chenghaoyang@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839057}
parent b7de6671
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
#include "ash/accelerometer/accelerometer_reader.h" #include "ash/accelerometer/accelerometer_reader.h"
#include "ash/public/cpp/tablet_mode_observer.h" #include "ash/public/cpp/tablet_mode_observer.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/observer_list_threadsafe.h" #include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "base/timer/timer.h"
namespace ash { namespace ash {
...@@ -33,18 +35,10 @@ class AccelerometerFileReader : public AccelerometerProviderInterface, ...@@ -33,18 +35,10 @@ class AccelerometerFileReader : public AccelerometerProviderInterface,
void StopListenToTabletModeController() override; void StopListenToTabletModeController() override;
void SetEmitEvents(bool emit_events) override; void SetEmitEvents(bool emit_events) override;
// Attempts to read the accelerometer data. Upon success, converts the raw
// reading to an AccelerometerUpdate and notifies observers. Triggers another
// read at the current sampling rate.
void Read();
// Controls accelerometer reading. // Controls accelerometer reading.
void EnableAccelerometerReading(); void EnableAccelerometerReading();
void DisableAccelerometerReading(); void DisableAccelerometerReading();
// Tracks if accelerometer initialization is completed.
void CheckInitStatus();
// With ChromeOS EC lid angle driver present, it's triggered when the device // 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 // is physically used as a tablet (even thought its UI might be in clamshell
// mode), cancelled otherwise. // mode), cancelled otherwise.
...@@ -55,6 +49,14 @@ class AccelerometerFileReader : public AccelerometerProviderInterface, ...@@ -55,6 +49,14 @@ class AccelerometerFileReader : public AccelerometerProviderInterface,
void OnTabletPhysicalStateChanged() override; void OnTabletPhysicalStateChanged() override;
private: private:
struct InitializationResult {
InitializationResult();
~InitializationResult();
State initialization_state;
ECLidAngleDriverStatus ec_lid_angle_driver_status;
};
// Represents necessary information in order to read an accelerometer device. // Represents necessary information in order to read an accelerometer device.
struct ReadingData { struct ReadingData {
ReadingData(); ReadingData();
...@@ -95,18 +97,24 @@ class AccelerometerFileReader : public AccelerometerProviderInterface, ...@@ -95,18 +97,24 @@ class AccelerometerFileReader : public AccelerometerProviderInterface,
~AccelerometerFileReader() override; ~AccelerometerFileReader() override;
// Detects the accelerometer configuration. // Post a task to initialize on |task_runner_| and process the result on the
// UI thread. May be called multiple times in the retries.
void TryScheduleInitialize();
// Detects the accelerometer configuration in |task_runner_|.
// If an accelerometer is available, it triggers reads. // If an accelerometer is available, it triggers reads.
// This function MAY be called more than once. // This function MAY be called more than once.
// This function contains the actual initialization code to be run by the // This function contains the actual initialization code to be run by the
// Initialize function. It is needed because on some devices the sensor hub // Initialize function. It is needed because on some devices the sensor hub
// isn't available at the time the call to Initialize is made. If the sensor // isn't available at the time the call to Initialize is made.
// is found to be missing we'll make a call to TryScheduleInitializeInternal. // If the sensor is found to be missing we'll request a re-run of this
void InitializeInternal(); // function by returning State::INITIALIZING. TryScheduleInitializeInternal.
InitializationResult InitializeInternal();
// Attempt to reschedule a run of InitializeInternal(). The function will be // Attempt to finish the initialization with the result state. If it's
// scheduled to run again if Now() < initialization_timeout_. // State::INITIALIZING, it means something is missing and need to re-run
void TryScheduleInitializeInternal(); // |TryScheduleInitialize|, if not timed out yet.
void SetStatesWithInitializationResult(InitializationResult result);
// When accelerometers are presented as separate iio_devices this will perform // When accelerometers are presented as separate iio_devices this will perform
// the initialize for one of the devices, at the given |iio_path| and the // the initialize for one of the devices, at the given |iio_path| and the
...@@ -122,14 +130,10 @@ class AccelerometerFileReader : public AccelerometerProviderInterface, ...@@ -122,14 +130,10 @@ class AccelerometerFileReader : public AccelerometerProviderInterface,
bool InitializeLegacyAccelerometers(const base::FilePath& iio_path, bool InitializeLegacyAccelerometers(const base::FilePath& iio_path,
const base::FilePath& name); const base::FilePath& name);
// Attempts to read the accelerometer data. Upon a success, converts the raw // Attempts to read the accelerometer data in |task_runner_|. Upon a success,
// reading to an AccelerometerUpdate and notifies observers. // converts the raw reading to an AccelerometerUpdate and notifies observers.
void ReadFileAndNotify(); void ReadSample();
void NotifyObserversWithUpdate(scoped_refptr<AccelerometerUpdate> update);
void SetEmitEventsInternal(bool emit_events);
// True if periodical accelerometer read is on.
bool accelerometer_read_on_ = false;
bool emit_events_ = true; bool emit_events_ = true;
...@@ -137,17 +141,24 @@ class AccelerometerFileReader : public AccelerometerProviderInterface, ...@@ -137,17 +141,24 @@ class AccelerometerFileReader : public AccelerometerProviderInterface,
base::TimeTicks initialization_timeout_; base::TimeTicks initialization_timeout_;
// The accelerometer configuration. // The accelerometer configuration.
ConfigurationData configuration_; // Only used in |blocking_task_runner_|.
ConfigurationData configuration_ GUARDED_BY_CONTEXT(sequence_checker_);
// The timer to repeatedly read samples.
// Only used in |blocking_task_runner_|.
base::RepeatingTimer read_refresh_timer_
GUARDED_BY_CONTEXT(sequence_checker_);
// The observers to notify of accelerometer updates. // The observers to notify of accelerometer updates.
scoped_refptr<base::ObserverListThreadSafe<AccelerometerReader::Observer>> base::ObserverList<AccelerometerReader::Observer>::Unchecked observers_;
observers_;
// The task runner to use for blocking tasks. // The task runner to use for blocking tasks.
scoped_refptr<base::SequencedTaskRunner> task_runner_; scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
// The task runner of the UI thread.
scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
// The last seen accelerometer data. SEQUENCE_CHECKER(sequence_checker_);
scoped_refptr<AccelerometerUpdate> update_;
}; };
} // namespace ash } // namespace ash
......
...@@ -25,8 +25,15 @@ enum class ECLidAngleDriverStatus { UNKNOWN, SUPPORTED, NOT_SUPPORTED }; ...@@ -25,8 +25,15 @@ enum class ECLidAngleDriverStatus { UNKNOWN, SUPPORTED, NOT_SUPPORTED };
class AccelerometerProviderInterface; class AccelerometerProviderInterface;
// Reads an accelerometer device and reports data back to an // AccelerometerReader should only be used on the UI thread.
// AccelerometerDelegate. // 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 { class ASH_EXPORT AccelerometerReader {
public: public:
// An interface to receive data from the AccelerometerReader. // An interface to receive data from the AccelerometerReader.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment