Revert of [sensors] Ambient light sensor implementation for ChromeOS and Linux. (patchset #26 id:1050001 of https://codereview.chromium.org/2370343002/ )
Reason for revert: Causing a failure on Linux bot: https://build.chromium.org/p/chromium/builders/Linux%20x64/builds/28030 Original issue's description: > [sensors] Ambient light sensor implementation for ChromeOS and Linux. > > The patch introduces sensors implementation for > ChromeOS/Linux platforms using ambient light sensor. Both > platforms share the same code and require polling threads to > be used. > > SensorDataIio structure is used to initialize a generic > SensorReader, which is created only when sensor read files > are found, and to create a concrete sensor, which takes > an ownership of the SensorReader. > > A SensorReader must always be created on a polling thread, > which is further used by a sensor to poll data. Each new > sensor will have its own thread in order to avoid blocking of > each other. > > As a temp solution to manage polling threads, which are not > passed to new sensors, a manager thread is used. It kills a > polling thread if a sensor cannot be created. In the future, > the manager thread will evolve to a manager class that will > manage finding new sensors attached to a system and notify a > provider about that. The provider will have its own cache in > order to avoid trying to find sensors each time after it > fails to find a requested sensor. Once the manager notifies > the provider about a new sensor, the provider updates its > cache and starts to process requests for that type of sensor. > > Intent to Implement: > https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/TkfdVqYAYiE/xLGN2b1-AAAJ > > BUG=606766 > CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_site_isolation > > Committed: https://crrev.com/de2d07084492be68633a47bae161cf9014ac88e2 > Cr-Commit-Position: refs/heads/master@{#429584} TBR=reillyg@chromium.org,alexander.shalamov@intel.com,alexis.menard@intel.com,alexmos@chromium.org,mikhail.pozdnyakov@intel.com,rockot@chromium.org,timvolodine@chromium.org,maksim.sisov@intel.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=606766 Review-Url: https://codereview.chromium.org/2468283003 Cr-Commit-Position: refs/heads/master@{#429604}
This commit is contained in:
chrome/browser
content/browser/frame_host
device
BUILD.gn
generic_sensor
BUILD.gn
linux
platform_sensor_utils_linux.ccplatform_sensor_utils_linux.hsensor_data_linux.ccsensor_data_linux.hsensor_reader_unittest.cc
platform_sensor_linux.ccplatform_sensor_linux.hplatform_sensor_provider.ccplatform_sensor_provider_base.hplatform_sensor_provider_linux.ccplatform_sensor_provider_linux.hsensor_provider_impl.ccsensor_provider_impl.h@ -2038,7 +2038,7 @@ const FeatureEntry kFeatureEntries[] = {
|
||||
IDS_FLAGS_SAVEAS_MENU_LABEL_EXPERIMENT_DESCRIPTION, kOsDesktop,
|
||||
SINGLE_VALUE_TYPE(switches::kEnableSaveAsMenuLabelExperiment)},
|
||||
{"enable-generic-sensor", IDS_FLAGS_ENABLE_GENERIC_SENSOR_NAME,
|
||||
IDS_FLAGS_ENABLE_GENERIC_SENSOR_DESCRIPTION, kOsAll,
|
||||
IDS_FLAGS_ENABLE_GENERIC_SENSOR_DESCRIPTION, kOsAndroid | kOsMac | kOsWin,
|
||||
FEATURE_VALUE_TYPE(features::kGenericSensor)},
|
||||
{"expensive-background-timer-throttling",
|
||||
IDS_FLAGS_EXPENSIVE_BACKGROUND_TIMER_THROTTLING_NAME,
|
||||
|
@ -2212,8 +2212,7 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
|
||||
#endif
|
||||
if (base::FeatureList::IsEnabled(features::kGenericSensor)) {
|
||||
GetInterfaceRegistry()->AddInterface(
|
||||
base::Bind(&device::SensorProviderImpl::Create,
|
||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)),
|
||||
base::Bind(&device::SensorProviderImpl::Create),
|
||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
|
||||
}
|
||||
|
||||
|
@ -97,10 +97,6 @@ test("device_unittests") {
|
||||
deps += [ "//dbus:test_support" ]
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
sources += [ "generic_sensor/linux/sensor_reader_unittest.cc" ]
|
||||
}
|
||||
|
||||
# HID and Serial:
|
||||
# Android doesn't compile.
|
||||
# Linux, requires udev.
|
||||
|
@ -11,26 +11,18 @@ if (is_android) {
|
||||
component("generic_sensor") {
|
||||
output_name = "generic_sensor"
|
||||
sources = [
|
||||
"linux/platform_sensor_utils_linux.cc",
|
||||
"linux/platform_sensor_utils_linux.h",
|
||||
"linux/sensor_data_linux.cc",
|
||||
"linux/sensor_data_linux.h",
|
||||
"platform_sensor.cc",
|
||||
"platform_sensor.h",
|
||||
"platform_sensor_ambient_light_mac.cc",
|
||||
"platform_sensor_ambient_light_mac.h",
|
||||
"platform_sensor_android.cc",
|
||||
"platform_sensor_android.h",
|
||||
"platform_sensor_linux.cc",
|
||||
"platform_sensor_linux.h",
|
||||
"platform_sensor_provider.cc",
|
||||
"platform_sensor_provider.h",
|
||||
"platform_sensor_provider_android.cc",
|
||||
"platform_sensor_provider_android.h",
|
||||
"platform_sensor_provider_base.cc",
|
||||
"platform_sensor_provider_base.h",
|
||||
"platform_sensor_provider_linux.cc",
|
||||
"platform_sensor_provider_linux.h",
|
||||
"platform_sensor_provider_mac.cc",
|
||||
"platform_sensor_provider_mac.h",
|
||||
"platform_sensor_provider_win.cc",
|
||||
@ -66,11 +58,9 @@ component("generic_sensor") {
|
||||
deps += [ ":jni_headers" ]
|
||||
}
|
||||
|
||||
if (is_mac || is_linux) {
|
||||
deps += [ "//device/sensors/public/cpp" ]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
deps += [ "//device/sensors/public/cpp" ]
|
||||
|
||||
libs = [ "IOKit.framework" ]
|
||||
}
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
// Copyright 2016 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 "device/generic_sensor/linux/platform_sensor_utils_linux.h"
|
||||
|
||||
#include "base/files/file_enumerator.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "device/generic_sensor/linux/sensor_data_linux.h"
|
||||
#include "device/generic_sensor/public/cpp/sensor_reading.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
namespace {
|
||||
|
||||
bool InitSensorPaths(const std::vector<std::string>& input_names,
|
||||
const char* base_path,
|
||||
std::vector<base::FilePath>* sensor_paths) {
|
||||
// Search the iio/devices directory for a subdirectory (eg "device0" or
|
||||
// "iio:device0") that contains the specified input_name file (eg
|
||||
// "in_illuminance_input" or "in_illuminance0_input").
|
||||
base::FileEnumerator dir_enumerator(base::FilePath(base_path), false,
|
||||
base::FileEnumerator::DIRECTORIES);
|
||||
for (base::FilePath check_path = dir_enumerator.Next(); !check_path.empty();
|
||||
check_path = dir_enumerator.Next()) {
|
||||
for (auto const& file_name : input_names) {
|
||||
base::FilePath full_path = check_path.Append(file_name);
|
||||
if (base::PathExists(full_path)) {
|
||||
sensor_paths->push_back(full_path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetSensorFilePaths(const SensorDataLinux& data,
|
||||
std::vector<base::FilePath>* sensor_paths) {
|
||||
DCHECK(sensor_paths->empty());
|
||||
// Depending on a sensor, there can be up to three sets of files that need
|
||||
// to be checked. If one of three files is not found, a sensor is
|
||||
// treated as a non-existing one.
|
||||
for (auto const& file_names : data.sensor_file_names) {
|
||||
// Supply InitSensorPaths() with a set of files.
|
||||
// Only one file from each set should be found.
|
||||
if (!InitSensorPaths(file_names, data.base_path_sensor_linux, sensor_paths))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
std::unique_ptr<SensorReader> SensorReader::Create(
|
||||
const SensorDataLinux& data) {
|
||||
base::ThreadRestrictions::AssertIOAllowed();
|
||||
std::vector<base::FilePath> sensor_paths;
|
||||
if (!GetSensorFilePaths(data, &sensor_paths))
|
||||
return nullptr;
|
||||
return base::WrapUnique(new SensorReader(std::move(sensor_paths)));
|
||||
}
|
||||
|
||||
SensorReader::SensorReader(std::vector<base::FilePath> sensor_paths)
|
||||
: sensor_paths_(std::move(sensor_paths)) {
|
||||
DCHECK(!sensor_paths_.empty());
|
||||
}
|
||||
|
||||
SensorReader::~SensorReader() = default;
|
||||
|
||||
bool SensorReader::ReadSensorReading(SensorReading* reading) {
|
||||
base::ThreadRestrictions::AssertIOAllowed();
|
||||
SensorReading readings;
|
||||
DCHECK_LE(sensor_paths_.size(), arraysize(readings.values));
|
||||
int i = 0;
|
||||
for (const auto& path : sensor_paths_) {
|
||||
std::string new_read_value;
|
||||
if (!base::ReadFileToString(path, &new_read_value))
|
||||
return false;
|
||||
|
||||
double new_value = 0;
|
||||
base::TrimWhitespaceASCII(new_read_value, base::TRIM_ALL, &new_read_value);
|
||||
if (!base::StringToDouble(new_read_value, &new_value))
|
||||
return false;
|
||||
readings.values[i++] = new_value;
|
||||
}
|
||||
*reading = readings;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace device
|
@ -1,43 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
#ifndef DEVICE_GENERIC_SENSOR_LINUX_PLATFORM_SENSOR_UTILS_LINUX_H_
|
||||
#define DEVICE_GENERIC_SENSOR_LINUX_PLATFORM_SENSOR_UTILS_LINUX_H_
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "device/generic_sensor/generic_sensor_export.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
struct SensorDataLinux;
|
||||
struct SensorReading;
|
||||
|
||||
// Generic reader class that reads sensors data from
|
||||
// sensors files located in the base iio folder.
|
||||
class DEVICE_GENERIC_SENSOR_EXPORT SensorReader {
|
||||
public:
|
||||
~SensorReader();
|
||||
|
||||
// Creates a new instance of SensorReader if sensor read files
|
||||
// has been found and |sensor_paths_| are set.
|
||||
static std::unique_ptr<SensorReader> Create(const SensorDataLinux& data);
|
||||
|
||||
// Reads sensor values into |*reading| from sensor files
|
||||
// specified in |sensor_paths_|.
|
||||
bool ReadSensorReading(SensorReading* reading);
|
||||
|
||||
private:
|
||||
explicit SensorReader(std::vector<base::FilePath> sensor_paths);
|
||||
|
||||
// Contains paths to sensor files that are set when
|
||||
// Create() is called.
|
||||
const std::vector<base::FilePath> sensor_paths_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SensorReader);
|
||||
};
|
||||
|
||||
} // namespace device
|
||||
|
||||
#endif // DEVICE_GENERIC_SENSOR_LINUX_PLATFORM_SENSOR_UTILS_LINUX_H_
|
@ -1,51 +0,0 @@
|
||||
// Copyright 2016 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 "device/generic_sensor/linux/sensor_data_linux.h"
|
||||
#include "device/sensors/public/cpp/device_sensors_consts.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
namespace {
|
||||
|
||||
using mojom::SensorType;
|
||||
|
||||
const base::FilePath::CharType* kSensorsBasePath =
|
||||
FILE_PATH_LITERAL("/sys/bus/iio/devices");
|
||||
|
||||
const std::string kAmbientLightFileNames[] = {
|
||||
"in_illuminance0_input", "in_illuminance_input", "in_illuminance0_raw",
|
||||
"in_illuminance_raw", "illuminance0_input"};
|
||||
|
||||
} // namespace
|
||||
|
||||
SensorDataLinux::SensorDataLinux() : base_path_sensor_linux(kSensorsBasePath) {}
|
||||
|
||||
SensorDataLinux::~SensorDataLinux() = default;
|
||||
|
||||
SensorDataLinux::SensorDataLinux(const SensorDataLinux& other) = default;
|
||||
|
||||
bool InitSensorData(SensorType type, SensorDataLinux* data) {
|
||||
DCHECK(data);
|
||||
|
||||
switch (type) {
|
||||
case SensorType::AMBIENT_LIGHT: {
|
||||
std::vector<std::string> file_names(
|
||||
kAmbientLightFileNames,
|
||||
kAmbientLightFileNames + arraysize(kAmbientLightFileNames));
|
||||
data->sensor_file_names.push_back(std::move(file_names));
|
||||
data->reporting_mode = mojom::ReportingMode::ON_CHANGE;
|
||||
data->default_configuration =
|
||||
PlatformSensorConfiguration(kDefaultAmbientLightFrequencyHz);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace device
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
#ifndef DEVICE_GENERIC_SENSOR_LINUX_SENSOR_DATA_LINUX_H_
|
||||
#define DEVICE_GENERIC_SENSOR_LINUX_SENSOR_DATA_LINUX_H_
|
||||
|
||||
#include "device/generic_sensor/generic_sensor_export.h"
|
||||
#include "device/generic_sensor/public/interfaces/sensor.mojom.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
// This structure represents a context that is used to
|
||||
// create a type specific SensorReader and a concrete
|
||||
// sensor that uses the SensorReader to read sensor
|
||||
// data from files specified in the |sensor_file_names|.
|
||||
struct DEVICE_GENERIC_SENSOR_EXPORT SensorDataLinux {
|
||||
SensorDataLinux();
|
||||
~SensorDataLinux();
|
||||
SensorDataLinux(const SensorDataLinux& other);
|
||||
// Provides a base path to all sensors.
|
||||
const base::FilePath::CharType* base_path_sensor_linux;
|
||||
// Provides an array of sensor file names to be searched for.
|
||||
// Different sensors might have up to 3 different file name arrays.
|
||||
// One file must be found from each array.
|
||||
std::vector<std::vector<std::string>> sensor_file_names;
|
||||
// Reporting mode of a sensor.
|
||||
mojom::ReportingMode reporting_mode;
|
||||
// Default configuration of a sensor.
|
||||
PlatformSensorConfiguration default_configuration;
|
||||
};
|
||||
|
||||
// Initializes a sensor type specific data.
|
||||
bool InitSensorData(mojom::SensorType type, SensorDataLinux* data);
|
||||
|
||||
} // namespace device
|
||||
|
||||
#endif // DEVICE_GENERIC_SENSOR_LINUX_SENSOR_DATA_LINUX_H_
|
@ -1,260 +0,0 @@
|
||||
// Copyright 2016 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 "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "device/generic_sensor/linux/platform_sensor_utils_linux.h"
|
||||
#include "device/generic_sensor/linux/sensor_data_linux.h"
|
||||
#include "device/generic_sensor/public/cpp/sensor_reading.h"
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
namespace {
|
||||
|
||||
const base::FilePath::CharType* kDevice0Dir = FILE_PATH_LITERAL("device0");
|
||||
|
||||
const std::string kSensorFileNameTest1 = "sensor_data1";
|
||||
const std::string kSensorFileNameTest2 = "sensor_data2";
|
||||
const std::string kSensorFileNameTest3 = "sensor_data3";
|
||||
|
||||
const std::string kTestSensorFileNamesTest[3][5] = {
|
||||
{
|
||||
kSensorFileNameTest1, "sensor1_input", "sensor1_raw_input", "sensor1",
|
||||
"sensor1_data_raw",
|
||||
},
|
||||
{
|
||||
"sensor2", kSensorFileNameTest2, "sensor2_raw_input", "sensor2_input",
|
||||
"sensor2_data_raw",
|
||||
},
|
||||
{
|
||||
"sensor3", "sensor3_input", "sensor3_raw_input", "sensor3_data_raw",
|
||||
kSensorFileNameTest3,
|
||||
},
|
||||
};
|
||||
|
||||
void CreateFile(const base::FilePath& file) {
|
||||
EXPECT_EQ(base::WriteFile(file, nullptr, 0), 0);
|
||||
}
|
||||
|
||||
void DeleteFile(const base::FilePath& file) {
|
||||
EXPECT_TRUE(base::DeleteFile(file, false));
|
||||
}
|
||||
|
||||
void WriteReadingFieldToFile(const base::FilePath& path, double value) {
|
||||
const std::string str = base::DoubleToString(value);
|
||||
int bytes_written = base::WriteFile(path, str.data(), str.size());
|
||||
EXPECT_EQ(static_cast<size_t>(bytes_written), str.size());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class SensorReaderTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(base_temp_dir_.CreateUniqueTempDir());
|
||||
base_dir_ = base_temp_dir_.GetPath();
|
||||
sensors_dir_ = base_dir_.Append(kDevice0Dir);
|
||||
ASSERT_TRUE(base::CreateDirectory(sensors_dir_));
|
||||
}
|
||||
|
||||
// Deletes base dir recursively.
|
||||
void TearDown() override { ASSERT_TRUE(base_temp_dir_.Delete()); }
|
||||
|
||||
// Initialize SensorDataLinux with values for a sensor reader.
|
||||
void InitSensorDataForTest(size_t rows, SensorDataLinux* data) {
|
||||
// Corresponds to maximum values in SensorReading.
|
||||
// We must read only from up to three files. Thus - 3 sets of files
|
||||
// should be fill in here.
|
||||
const size_t max_rows = 3;
|
||||
if (rows > 3)
|
||||
rows = max_rows;
|
||||
|
||||
data->base_path_sensor_linux = base_dir_.value().c_str();
|
||||
for (size_t i = 0; i < rows; ++i) {
|
||||
std::vector<std::string> file_names(
|
||||
kTestSensorFileNamesTest[i],
|
||||
kTestSensorFileNamesTest[i] + arraysize(kTestSensorFileNamesTest[i]));
|
||||
data->sensor_file_names.push_back(std::move(file_names));
|
||||
}
|
||||
}
|
||||
|
||||
// Check SensorReading values are properly read.
|
||||
void CheckSensorDataFields(const SensorReading& data,
|
||||
double value1,
|
||||
double value2,
|
||||
double value3) {
|
||||
EXPECT_EQ(value1, data.values[0]);
|
||||
EXPECT_EQ(value2, data.values[1]);
|
||||
EXPECT_EQ(value3, data.values[2]);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Holds a path to a sensor dir that is located in |base_dir_|
|
||||
base::FilePath sensors_dir_;
|
||||
// Holds a path to a base dir.
|
||||
base::FilePath base_dir_;
|
||||
// Holds base dir where a sensor dir is located.
|
||||
base::ScopedTempDir base_temp_dir_;
|
||||
};
|
||||
|
||||
// Test a reader is not created if sensor read files
|
||||
// do not exist.
|
||||
TEST_F(SensorReaderTest, FileDoesNotExist) {
|
||||
const char* kGiberishFiles[] = {"temp1", "temp2", "temp3", "temp4"};
|
||||
const size_t rows = 3;
|
||||
// Create some gibberish files that we are not interested in.
|
||||
for (unsigned int i = 0; i < arraysize(kGiberishFiles); ++i) {
|
||||
base::FilePath some_file = sensors_dir_.Append(kGiberishFiles[i]);
|
||||
CreateFile(some_file);
|
||||
}
|
||||
|
||||
SensorDataLinux sensor_data;
|
||||
InitSensorDataForTest(rows, &sensor_data);
|
||||
|
||||
std::unique_ptr<SensorReader> reader = SensorReader::Create(sensor_data);
|
||||
EXPECT_FALSE(reader);
|
||||
}
|
||||
|
||||
// Simulate a sensor, which has only one file to be read from.
|
||||
TEST_F(SensorReaderTest, ReadValueFromOneFile) {
|
||||
const size_t rows = 1;
|
||||
const double value1 = 20;
|
||||
const double zero_value = 0;
|
||||
// Create a test sensor file, which must be found to be read from.
|
||||
base::FilePath temp_sensor_file = sensors_dir_.Append(kSensorFileNameTest1);
|
||||
CreateFile(temp_sensor_file);
|
||||
|
||||
// Initialize sensor data for a reader.
|
||||
SensorDataLinux sensor_data;
|
||||
InitSensorDataForTest(rows, &sensor_data);
|
||||
|
||||
std::unique_ptr<SensorReader> reader = SensorReader::Create(sensor_data);
|
||||
EXPECT_TRUE(reader);
|
||||
|
||||
// Write a value to the file.
|
||||
WriteReadingFieldToFile(temp_sensor_file, value1);
|
||||
|
||||
// Fill SensorReading's first field with read value. Other fields must
|
||||
// be 0.
|
||||
SensorReading reading;
|
||||
EXPECT_TRUE(reader->ReadSensorReading(&reading));
|
||||
CheckSensorDataFields(reading, value1, zero_value, zero_value);
|
||||
}
|
||||
|
||||
// Simulate a sensor, which has two files to be read from.
|
||||
TEST_F(SensorReaderTest, ReadValuesFromTwoFiles) {
|
||||
const size_t rows = 2;
|
||||
const double value1 = 20;
|
||||
const double value2 = 50;
|
||||
const double zero_value = 0;
|
||||
// Create a test sensor file, which must be found.
|
||||
base::FilePath temp_sensor_file1 = sensors_dir_.Append(kSensorFileNameTest1);
|
||||
CreateFile(temp_sensor_file1);
|
||||
|
||||
// Create another test sensor file, which must be found.
|
||||
base::FilePath temp_sensor_file2 = sensors_dir_.Append(kSensorFileNameTest2);
|
||||
CreateFile(temp_sensor_file2);
|
||||
|
||||
// Initialize sensor data for a reader.
|
||||
SensorDataLinux sensor_data;
|
||||
InitSensorDataForTest(rows, &sensor_data);
|
||||
|
||||
std::unique_ptr<SensorReader> reader = SensorReader::Create(sensor_data);
|
||||
EXPECT_TRUE(reader);
|
||||
|
||||
// Write a value to the file.
|
||||
WriteReadingFieldToFile(temp_sensor_file1, value1);
|
||||
WriteReadingFieldToFile(temp_sensor_file2, value2);
|
||||
|
||||
// Fill SensorReading's two first fields with read value. Last field must
|
||||
// be 0.
|
||||
SensorReading reading;
|
||||
EXPECT_TRUE(reader->ReadSensorReading(&reading));
|
||||
CheckSensorDataFields(reading, value1, value2, zero_value);
|
||||
}
|
||||
|
||||
// Simulate a sensor, which has the files to be read from.
|
||||
// After read is successful, remove one of the files and try
|
||||
// to read again. Reading must fail then.
|
||||
TEST_F(SensorReaderTest, ReadValuesFromThreeFilesAndFail) {
|
||||
const size_t rows = 4;
|
||||
const double value1 = 20;
|
||||
const double value2 = 50;
|
||||
const double value3 = 80;
|
||||
const double zero_value = 0;
|
||||
// Create a test sensor file, which must be found.
|
||||
base::FilePath temp_sensor_file1 = sensors_dir_.Append(kSensorFileNameTest1);
|
||||
CreateFile(temp_sensor_file1);
|
||||
|
||||
// Create another test sensor file, which must be found.
|
||||
base::FilePath temp_sensor_file2 = sensors_dir_.Append(kSensorFileNameTest2);
|
||||
CreateFile(temp_sensor_file2);
|
||||
|
||||
// Create third test sensor file, which must be found.
|
||||
base::FilePath temp_sensor_file3 = sensors_dir_.Append(kSensorFileNameTest3);
|
||||
CreateFile(temp_sensor_file3);
|
||||
|
||||
// Initialize sensor data for a reader.
|
||||
SensorDataLinux sensor_data;
|
||||
InitSensorDataForTest(rows, &sensor_data);
|
||||
|
||||
std::unique_ptr<SensorReader> reader = SensorReader::Create(sensor_data);
|
||||
EXPECT_TRUE(reader);
|
||||
|
||||
// Write a value to the file.
|
||||
WriteReadingFieldToFile(temp_sensor_file1, value1);
|
||||
WriteReadingFieldToFile(temp_sensor_file2, value2);
|
||||
WriteReadingFieldToFile(temp_sensor_file3, value3);
|
||||
|
||||
// Fill SensorReading's values with data from files.
|
||||
SensorReading reading;
|
||||
EXPECT_TRUE(reader->ReadSensorReading(&reading));
|
||||
CheckSensorDataFields(reading, value1, value2, value3);
|
||||
|
||||
SensorReading reading2;
|
||||
DeleteFile(temp_sensor_file2);
|
||||
EXPECT_FALSE(reader->ReadSensorReading(&reading2));
|
||||
CheckSensorDataFields(reading2, zero_value, zero_value, zero_value);
|
||||
}
|
||||
|
||||
// Fill in SensorDataLinux with three arrays of files that must be found
|
||||
// before creating a sensor reader. If even one file is not found,
|
||||
// a sensor reader must not be created. As soon as all the files are found,
|
||||
// check the reader is created.
|
||||
TEST_F(SensorReaderTest, SensorReadFilesDoNotExist) {
|
||||
const size_t rows = 3;
|
||||
// Create a test sensor file, which must be found. Other
|
||||
// files will not be created and the test must fail to create a reader.
|
||||
base::FilePath temp_sensor_file1 = sensors_dir_.Append(kSensorFileNameTest1);
|
||||
CreateFile(temp_sensor_file1);
|
||||
|
||||
// Initialize sensor data for a reader.
|
||||
SensorDataLinux sensor_data;
|
||||
InitSensorDataForTest(rows, &sensor_data);
|
||||
|
||||
std::unique_ptr<SensorReader> reader = SensorReader::Create(sensor_data);
|
||||
EXPECT_FALSE(reader);
|
||||
|
||||
// Create one more file. The reader mustn't be created as long as it
|
||||
// expects three files to be found.
|
||||
base::FilePath temp_sensor_file2 = sensors_dir_.Append(kSensorFileNameTest2);
|
||||
CreateFile(temp_sensor_file2);
|
||||
|
||||
reader.reset();
|
||||
reader = SensorReader::Create(sensor_data);
|
||||
EXPECT_FALSE(reader);
|
||||
|
||||
// Create last file.
|
||||
base::FilePath temp_sensor_file3 = sensors_dir_.Append(kSensorFileNameTest3);
|
||||
CreateFile(temp_sensor_file3);
|
||||
|
||||
reader.reset();
|
||||
reader = SensorReader::Create(sensor_data);
|
||||
EXPECT_TRUE(reader);
|
||||
}
|
||||
|
||||
} // namespace device
|
@ -1,114 +0,0 @@
|
||||
// Copyright 2016 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 "device/generic_sensor/platform_sensor_linux.h"
|
||||
|
||||
#include "base/threading/thread.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "device/generic_sensor/linux/platform_sensor_utils_linux.h"
|
||||
#include "device/generic_sensor/linux/sensor_data_linux.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
namespace {
|
||||
|
||||
// Checks if at least one value has been changed.
|
||||
bool HaveValuesChanged(const SensorReading& lhs, const SensorReading& rhs) {
|
||||
return lhs.values[0] != rhs.values[0] || lhs.values[1] != rhs.values[1] ||
|
||||
lhs.values[2] != rhs.values[2];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PlatformSensorLinux::PlatformSensorLinux(
|
||||
mojom::SensorType type,
|
||||
mojo::ScopedSharedBufferMapping mapping,
|
||||
PlatformSensorProvider* provider,
|
||||
const SensorDataLinux& data,
|
||||
std::unique_ptr<SensorReader> sensor_reader,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> polling_thread_task_runner_)
|
||||
: PlatformSensor(type, std::move(mapping), provider),
|
||||
timer_(new base::RepeatingTimer()),
|
||||
default_configuration_(data.default_configuration),
|
||||
reporting_mode_(data.reporting_mode),
|
||||
sensor_reader_(std::move(sensor_reader)),
|
||||
polling_thread_task_runner_(polling_thread_task_runner_),
|
||||
weak_factory_(this) {}
|
||||
|
||||
PlatformSensorLinux::~PlatformSensorLinux() {
|
||||
polling_thread_task_runner_->DeleteSoon(FROM_HERE, timer_);
|
||||
}
|
||||
|
||||
mojom::ReportingMode PlatformSensorLinux::GetReportingMode() {
|
||||
return reporting_mode_;
|
||||
}
|
||||
|
||||
bool PlatformSensorLinux::StartSensor(
|
||||
const PlatformSensorConfiguration& configuration) {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
return polling_thread_task_runner_->PostTask(
|
||||
FROM_HERE, base::Bind(&PlatformSensorLinux::BeginPoll,
|
||||
weak_factory_.GetWeakPtr(), configuration));
|
||||
}
|
||||
|
||||
void PlatformSensorLinux::StopSensor() {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
polling_thread_task_runner_->PostTask(
|
||||
FROM_HERE, base::Bind(&PlatformSensorLinux::StopPoll, this));
|
||||
}
|
||||
|
||||
bool PlatformSensorLinux::CheckSensorConfiguration(
|
||||
const PlatformSensorConfiguration& configuration) {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
// TODO(maksims): make this sensor dependent.
|
||||
// For example, in case of accelerometer, check current polling frequency
|
||||
// exposed by iio driver.
|
||||
return configuration.frequency() > 0 &&
|
||||
configuration.frequency() <=
|
||||
mojom::SensorConfiguration::kMaxAllowedFrequency;
|
||||
}
|
||||
|
||||
PlatformSensorConfiguration PlatformSensorLinux::GetDefaultConfiguration() {
|
||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
return default_configuration_;
|
||||
}
|
||||
|
||||
void PlatformSensorLinux::BeginPoll(
|
||||
const PlatformSensorConfiguration& configuration) {
|
||||
DCHECK(polling_thread_task_runner_->BelongsToCurrentThread());
|
||||
timer_->Start(FROM_HERE, base::TimeDelta::FromMicroseconds(
|
||||
base::Time::kMicrosecondsPerSecond /
|
||||
configuration.frequency()),
|
||||
this, &PlatformSensorLinux::PollForReadingData);
|
||||
}
|
||||
|
||||
void PlatformSensorLinux::StopPoll() {
|
||||
DCHECK(polling_thread_task_runner_->BelongsToCurrentThread());
|
||||
timer_->Stop();
|
||||
}
|
||||
|
||||
void PlatformSensorLinux::PollForReadingData() {
|
||||
DCHECK(polling_thread_task_runner_->BelongsToCurrentThread());
|
||||
|
||||
SensorReading reading;
|
||||
if (!sensor_reader_->ReadSensorReading(&reading)) {
|
||||
task_runner_->PostTask(
|
||||
FROM_HERE, base::Bind(&PlatformSensorLinux::NotifySensorError, this));
|
||||
StopPoll();
|
||||
return;
|
||||
}
|
||||
|
||||
bool notifyNeeded = false;
|
||||
if (GetReportingMode() == mojom::ReportingMode::ON_CHANGE) {
|
||||
if (!HaveValuesChanged(reading, old_values_))
|
||||
return;
|
||||
notifyNeeded = true;
|
||||
}
|
||||
|
||||
old_values_ = reading;
|
||||
reading.timestamp = (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
|
||||
UpdateSensorReading(reading, notifyNeeded);
|
||||
}
|
||||
|
||||
} // namespace device
|
@ -1,75 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
#ifndef DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_LINUX_H_
|
||||
#define DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_LINUX_H_
|
||||
|
||||
#include "device/generic_sensor/platform_sensor.h"
|
||||
|
||||
namespace base {
|
||||
class RepeatingTimer;
|
||||
class SingleThreadTaskRunner;
|
||||
class Thread;
|
||||
}
|
||||
|
||||
namespace device {
|
||||
|
||||
class SensorReader;
|
||||
struct SensorDataLinux;
|
||||
|
||||
class PlatformSensorLinux : public PlatformSensor {
|
||||
public:
|
||||
PlatformSensorLinux(
|
||||
mojom::SensorType type,
|
||||
mojo::ScopedSharedBufferMapping mapping,
|
||||
PlatformSensorProvider* provider,
|
||||
const SensorDataLinux& data,
|
||||
std::unique_ptr<SensorReader> sensor_reader,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> polling_thread_task_runner);
|
||||
|
||||
// Thread safe.
|
||||
mojom::ReportingMode GetReportingMode() override;
|
||||
|
||||
protected:
|
||||
~PlatformSensorLinux() override;
|
||||
bool StartSensor(const PlatformSensorConfiguration& configuration) override;
|
||||
void StopSensor() override;
|
||||
bool CheckSensorConfiguration(
|
||||
const PlatformSensorConfiguration& configuration) override;
|
||||
PlatformSensorConfiguration GetDefaultConfiguration() override;
|
||||
|
||||
private:
|
||||
void BeginPoll(const PlatformSensorConfiguration& configuration);
|
||||
void StopPoll();
|
||||
|
||||
// Triggers |sensor_reader_| to read new sensor data.
|
||||
// If new data is read, UpdateSensorReading() is called.
|
||||
void PollForReadingData();
|
||||
|
||||
// Owned timer to be deleted on a polling thread.
|
||||
base::RepeatingTimer* timer_;
|
||||
|
||||
const PlatformSensorConfiguration default_configuration_;
|
||||
const mojom::ReportingMode reporting_mode_;
|
||||
|
||||
// A sensor reader that reads values from sensor files
|
||||
// and stores them to a SensorReading structure.
|
||||
std::unique_ptr<SensorReader> sensor_reader_;
|
||||
|
||||
// A task runner that is used to poll sensor data.
|
||||
scoped_refptr<base::SingleThreadTaskRunner> polling_thread_task_runner_;
|
||||
|
||||
// Stores previously read values that are used to
|
||||
// determine whether the recent values are changed
|
||||
// and IPC can be notified that updates are available.
|
||||
SensorReading old_values_;
|
||||
|
||||
base::WeakPtrFactory<PlatformSensorLinux> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformSensorLinux);
|
||||
};
|
||||
|
||||
} // namespace device
|
||||
|
||||
#endif // DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_LINUX_H_
|
@ -10,8 +10,6 @@
|
||||
#include "device/generic_sensor/platform_sensor_provider_android.h"
|
||||
#elif defined(OS_WIN)
|
||||
#include "device/generic_sensor/platform_sensor_provider_win.h"
|
||||
#elif defined(OS_LINUX)
|
||||
#include "device/generic_sensor/platform_sensor_provider_linux.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@ -38,8 +36,8 @@ PlatformSensorProvider* PlatformSensorProvider::GetInstance() {
|
||||
return PlatformSensorProviderAndroid::GetInstance();
|
||||
#elif defined(OS_WIN)
|
||||
return PlatformSensorProviderWin::GetInstance();
|
||||
#elif defined(OS_LINUX)
|
||||
return PlatformSensorProviderLinux::GetInstance();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -35,11 +35,6 @@ class DEVICE_GENERIC_SENSOR_EXPORT PlatformSensorProviderBase
|
||||
// alive; 'false' otherwise.
|
||||
bool HasSensors() const;
|
||||
|
||||
// Implementations might want to override this in order to be able
|
||||
// to read from sensor files. For example, linux does so.
|
||||
virtual void SetFileTaskRunner(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {}
|
||||
|
||||
protected:
|
||||
PlatformSensorProviderBase();
|
||||
virtual ~PlatformSensorProviderBase();
|
||||
|
@ -1,102 +0,0 @@
|
||||
// Copyright 2016 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 "device/generic_sensor/platform_sensor_provider_linux.h"
|
||||
|
||||
#include "base/memory/singleton.h"
|
||||
#include "base/task_runner_util.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "device/generic_sensor/linux/platform_sensor_utils_linux.h"
|
||||
#include "device/generic_sensor/linux/sensor_data_linux.h"
|
||||
#include "device/generic_sensor/platform_sensor_linux.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
// static
|
||||
PlatformSensorProviderLinux* PlatformSensorProviderLinux::GetInstance() {
|
||||
return base::Singleton<
|
||||
PlatformSensorProviderLinux,
|
||||
base::LeakySingletonTraits<PlatformSensorProviderLinux>>::get();
|
||||
}
|
||||
|
||||
PlatformSensorProviderLinux::PlatformSensorProviderLinux() = default;
|
||||
|
||||
PlatformSensorProviderLinux::~PlatformSensorProviderLinux() = default;
|
||||
|
||||
void PlatformSensorProviderLinux::CreateSensorInternal(
|
||||
mojom::SensorType type,
|
||||
mojo::ScopedSharedBufferMapping mapping,
|
||||
const CreateSensorCallback& callback) {
|
||||
SensorDataLinux data;
|
||||
if (!InitSensorData(type, &data)) {
|
||||
callback.Run(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!polling_thread_)
|
||||
polling_thread_.reset(new base::Thread("Sensor polling thread"));
|
||||
|
||||
if (!polling_thread_->IsRunning()) {
|
||||
if (!polling_thread_->StartWithOptions(
|
||||
base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
|
||||
callback.Run(nullptr);
|
||||
return;
|
||||
}
|
||||
polling_thread_task_runner_ = polling_thread_->task_runner();
|
||||
}
|
||||
|
||||
base::PostTaskAndReplyWithResult(
|
||||
polling_thread_task_runner_.get(), FROM_HERE,
|
||||
base::Bind(SensorReader::Create, data),
|
||||
base::Bind(&PlatformSensorProviderLinux::SensorReaderFound,
|
||||
base::Unretained(this), type, base::Passed(&mapping), callback,
|
||||
data));
|
||||
}
|
||||
|
||||
void PlatformSensorProviderLinux::SensorReaderFound(
|
||||
mojom::SensorType type,
|
||||
mojo::ScopedSharedBufferMapping mapping,
|
||||
const PlatformSensorProviderBase::CreateSensorCallback& callback,
|
||||
const SensorDataLinux& data,
|
||||
std::unique_ptr<SensorReader> sensor_reader) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
|
||||
if (!sensor_reader) {
|
||||
// If there are no sensors, stop polling thread.
|
||||
if (!HasSensors())
|
||||
AllSensorsRemoved();
|
||||
callback.Run(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
callback.Run(new PlatformSensorLinux(type, std::move(mapping), this, data,
|
||||
std::move(sensor_reader),
|
||||
polling_thread_task_runner_));
|
||||
}
|
||||
|
||||
void PlatformSensorProviderLinux::SetFileTaskRunner(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
if (!file_task_runner_)
|
||||
file_task_runner_ = file_task_runner;
|
||||
}
|
||||
|
||||
void PlatformSensorProviderLinux::AllSensorsRemoved() {
|
||||
DCHECK(CalledOnValidThread());
|
||||
DCHECK(file_task_runner_);
|
||||
// When there are no sensors left, the polling thread must be stopped.
|
||||
// Stop() can only be called on a different thread that allows io.
|
||||
// Thus, browser's file thread is used for this purpose.
|
||||
file_task_runner_->PostTask(
|
||||
FROM_HERE, base::Bind(&PlatformSensorProviderLinux::StopPollingThread,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
void PlatformSensorProviderLinux::StopPollingThread() {
|
||||
DCHECK(file_task_runner_);
|
||||
DCHECK(file_task_runner_->BelongsToCurrentThread());
|
||||
polling_thread_->Stop();
|
||||
}
|
||||
|
||||
} // namespace device
|
@ -1,75 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
#ifndef DEVICE_GENERIC_SENSOR_PUBLIC_PLATFORM_SENSOR_PROVIDER_LINUX_H_
|
||||
#define DEVICE_GENERIC_SENSOR_PUBLIC_PLATFORM_SENSOR_PROVIDER_LINUX_H_
|
||||
|
||||
#include "device/generic_sensor/platform_sensor_provider.h"
|
||||
|
||||
namespace base {
|
||||
class Thread;
|
||||
}
|
||||
|
||||
namespace device {
|
||||
|
||||
struct SensorDataLinux;
|
||||
class SensorReader;
|
||||
|
||||
class PlatformSensorProviderLinux : public PlatformSensorProvider {
|
||||
public:
|
||||
PlatformSensorProviderLinux();
|
||||
~PlatformSensorProviderLinux() override;
|
||||
|
||||
static PlatformSensorProviderLinux* GetInstance();
|
||||
|
||||
protected:
|
||||
void CreateSensorInternal(mojom::SensorType type,
|
||||
mojo::ScopedSharedBufferMapping mapping,
|
||||
const CreateSensorCallback& callback) override;
|
||||
|
||||
void AllSensorsRemoved() override;
|
||||
|
||||
void SetFileTaskRunner(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) override;
|
||||
|
||||
private:
|
||||
void SensorReaderFound(
|
||||
mojom::SensorType type,
|
||||
mojo::ScopedSharedBufferMapping mapping,
|
||||
const PlatformSensorProviderBase::CreateSensorCallback& callback,
|
||||
const SensorDataLinux& data,
|
||||
std::unique_ptr<SensorReader> sensor_reader);
|
||||
|
||||
// Stops a polling thread if there are no sensors left. Must be called on
|
||||
// a different that polling thread that allows io.
|
||||
void StopPollingThread();
|
||||
|
||||
// TODO(maksims): make a separate class Manager that will
|
||||
// create provide sensors with a polling task runner, check sensors existence
|
||||
// and notify provider if a new sensor has appeared and it can be created if a
|
||||
// request comes again for the same sensor.
|
||||
// A use case example: a request for a sensor X comes, manager checks if the
|
||||
// sensor exists on a platform and notifies a provider it is not found.
|
||||
// The provider stores this information into its cache and doesn't try to
|
||||
// create this specific sensor if a request comes. But when, for example,
|
||||
// the sensor X is plugged into a usb port, the manager notices that and
|
||||
// notifies the provider, which updates its cache and starts handling requests
|
||||
// for the sensor X.
|
||||
//
|
||||
// Right now, this thread is used to find sensors files and poll data.
|
||||
std::unique_ptr<base::Thread> polling_thread_;
|
||||
|
||||
// A task runner that is passed to polling sensors to poll data.
|
||||
scoped_refptr<base::SingleThreadTaskRunner> polling_thread_task_runner_;
|
||||
|
||||
// Browser's file thread task runner passed from renderer. Used to
|
||||
// stop a polling thread.
|
||||
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformSensorProviderLinux);
|
||||
};
|
||||
|
||||
} // namespace device
|
||||
|
||||
#endif // DEVICE_GENERIC_SENSOR_PUBLIC_PLATFORM_SENSOR_PROVIDER_LINUX_H_
|
@ -32,12 +32,9 @@ void NotifySensorCreated(
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void SensorProviderImpl::Create(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,
|
||||
mojom::SensorProviderRequest request) {
|
||||
void SensorProviderImpl::Create(mojom::SensorProviderRequest request) {
|
||||
PlatformSensorProvider* provider = PlatformSensorProvider::GetInstance();
|
||||
if (provider) {
|
||||
provider->SetFileTaskRunner(file_task_runner);
|
||||
mojo::MakeStrongBinding(base::WrapUnique(new SensorProviderImpl(provider)),
|
||||
std::move(request));
|
||||
}
|
||||
|
@ -20,9 +20,7 @@ class PlatformSensor;
|
||||
class DEVICE_GENERIC_SENSOR_EXPORT SensorProviderImpl final
|
||||
: public mojom::SensorProvider {
|
||||
public:
|
||||
static void Create(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner,
|
||||
mojom::SensorProviderRequest request);
|
||||
static void Create(mojom::SensorProviderRequest request);
|
||||
|
||||
~SensorProviderImpl() override;
|
||||
|
||||
|
Reference in New Issue
Block a user