Chromium Code Reviews| Index: device/generic_sensor/platform_sensor_provider_linux.cc | 
| diff --git a/device/generic_sensor/platform_sensor_provider_linux.cc b/device/generic_sensor/platform_sensor_provider_linux.cc | 
| index ec5226bf5ca69ec5047cb97ce11542c6ec91957f..258f691422fb65256ad80085f6e11205afe25eef 100644 | 
| --- a/device/generic_sensor/platform_sensor_provider_linux.cc | 
| +++ b/device/generic_sensor/platform_sensor_provider_linux.cc | 
| @@ -5,11 +5,10 @@ | 
| #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" | 
| +#include "device/generic_sensor/platform_sensor_manager_linux.h" | 
| namespace device { | 
| @@ -20,59 +19,54 @@ PlatformSensorProviderLinux* PlatformSensorProviderLinux::GetInstance() { | 
| base::LeakySingletonTraits<PlatformSensorProviderLinux>>::get(); | 
| } | 
| -PlatformSensorProviderLinux::PlatformSensorProviderLinux() = default; | 
| +PlatformSensorProviderLinux::PlatformSensorProviderLinux() | 
| + : enumeration_ready_(false), | 
| + sensor_device_manager_started_(false), | 
| + sensor_device_manager_(nullptr) {} | 
| -PlatformSensorProviderLinux::~PlatformSensorProviderLinux() = default; | 
| +PlatformSensorProviderLinux::~PlatformSensorProviderLinux() { | 
| + DCHECK(!sensor_device_manager_); | 
| +} | 
| void PlatformSensorProviderLinux::CreateSensorInternal( | 
| mojom::SensorType type, | 
| mojo::ScopedSharedBufferMapping mapping, | 
| const CreateSensorCallback& callback) { | 
| - SensorDataLinux data; | 
| - if (!InitSensorData(type, &data)) { | 
| + if (!InitializeSenorDeviceManager()) { | 
| callback.Run(nullptr); | 
| return; | 
| } | 
| - if (!polling_thread_) | 
| - polling_thread_.reset(new base::Thread("Sensor polling thread")); | 
| + if (!enumeration_ready()) | 
| + return; | 
| - 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(); | 
| + SensorInfoLinux* sensor_device = GetSensorDevice(type); | 
| + if (!sensor_device) { | 
| + // If there are no sensors, stop polling thread. | 
| + if (!HasSensors()) | 
| + AllSensorsRemoved(); | 
| + callback.Run(nullptr); | 
| + return; | 
| } | 
| - | 
| - 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)); | 
| + SensorDeviceFound(type, std::move(mapping), callback, sensor_device); | 
| } | 
| -void PlatformSensorProviderLinux::SensorReaderFound( | 
| +void PlatformSensorProviderLinux::SensorDeviceFound( | 
| mojom::SensorType type, | 
| mojo::ScopedSharedBufferMapping mapping, | 
| const PlatformSensorProviderBase::CreateSensorCallback& callback, | 
| - const SensorDataLinux& data, | 
| - std::unique_ptr<SensorReader> sensor_reader) { | 
| + SensorInfoLinux* sensor_device) { | 
| DCHECK(CalledOnValidThread()); | 
| - if (!sensor_reader) { | 
| - // If there are no sensors, stop polling thread. | 
| - if (!HasSensors()) | 
| - AllSensorsRemoved(); | 
| + if (!StartPollingThread()) { | 
| callback.Run(nullptr); | 
| return; | 
| } | 
| - callback.Run(new PlatformSensorLinux(type, std::move(mapping), this, data, | 
| - std::move(sensor_reader), | 
| - polling_thread_task_runner_)); | 
| + scoped_refptr<PlatformSensorLinux> sensor = | 
| + new PlatformSensorLinux(type, std::move(mapping), this, sensor_device, | 
| + polling_thread_->task_runner()); | 
| + callback.Run(sensor); | 
| } | 
| void PlatformSensorProviderLinux::SetFileTaskRunner( | 
| @@ -85,18 +79,139 @@ void PlatformSensorProviderLinux::SetFileTaskRunner( | 
| void PlatformSensorProviderLinux::AllSensorsRemoved() { | 
| DCHECK(CalledOnValidThread()); | 
| DCHECK(file_task_runner_); | 
| + Shutdown(); | 
| // When there are no sensors left, the polling thread must be stopped. | 
| - // Stop() can only be called on a different thread that allows io. | 
| + // Stop() can only be called on a different thread that allows I/O. | 
| // Thus, browser's file thread is used for this purpose. | 
| file_task_runner_->PostTask( | 
| FROM_HERE, base::Bind(&PlatformSensorProviderLinux::StopPollingThread, | 
| base::Unretained(this))); | 
| } | 
| +bool PlatformSensorProviderLinux::StartPollingThread() { | 
| + if (!polling_thread_) | 
| + polling_thread_.reset(new base::Thread("Sensor polling thread")); | 
| + | 
| + if (!polling_thread_->IsRunning()) { | 
| + return polling_thread_->StartWithOptions( | 
| + base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 
| + } | 
| + return true; | 
| +} | 
| + | 
| void PlatformSensorProviderLinux::StopPollingThread() { | 
| DCHECK(file_task_runner_); | 
| DCHECK(file_task_runner_->BelongsToCurrentThread()); | 
| - polling_thread_->Stop(); | 
| + if (polling_thread_ && polling_thread_->IsRunning()) | 
| + polling_thread_->Stop(); | 
| +} | 
| + | 
| +bool PlatformSensorProviderLinux::InitializeSenorDeviceManager() { | 
| + if (!sensor_device_manager_) | 
| + sensor_device_manager_.reset(new SensorDeviceManager()); | 
| + | 
| + if (!sensor_device_manager_started()) { | 
| + sensor_device_manager_started_ = file_task_runner_->PostTask( | 
| + FROM_HERE, | 
| + base::Bind(&SensorDeviceManager::Start, | 
| + base::Unretained(sensor_device_manager_.get()), this)); | 
| + } | 
| + return sensor_device_manager_started_; | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::Shutdown() { | 
| + DCHECK(CalledOnValidThread()); | 
| + const bool did_post_task = file_task_runner_->DeleteSoon( | 
| + FROM_HERE, sensor_device_manager_.release()); | 
| + DCHECK(did_post_task); | 
| + enumeration_ready_ = false; | 
| + sensor_device_manager_started_ = false; | 
| + sensor_devices_by_type_.clear(); | 
| +} | 
| + | 
| +SensorInfoLinux* PlatformSensorProviderLinux::GetSensorDevice( | 
| + mojom::SensorType type) { | 
| + DCHECK(CalledOnValidThread()); | 
| + SensorInfoLinux* device = nullptr; | 
| + if (base::ContainsKey(sensor_devices_by_type_, type)) | 
| + device = sensor_devices_by_type_[type].get(); | 
| + return device; | 
| 
 
Reilly Grant (use Gerrit)
2016/12/08 02:31:15
auto sensor = sensor_devices_by_type_.find(type);
 
maksims (do not use this acc)
2016/12/08 18:39:17
Done.
 
 | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::GetAllSensorDevices() { | 
| + DCHECK(CalledOnValidThread()); | 
| + // TODO(maksims): implement this method once we have discovery API. | 
| + NOTIMPLEMENTED(); | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::SetSensorDeviceManagerForTesting( | 
| + std::unique_ptr<SensorDeviceManager> sensor_device_manager) { | 
| + DCHECK(CalledOnValidThread()); | 
| + Shutdown(); | 
| + sensor_device_manager_ = std::move(sensor_device_manager); | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::SetFileTaskRunnerForTesting( | 
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | 
| + DCHECK(CalledOnValidThread()); | 
| + file_task_runner_ = task_runner; | 
| 
 
Reilly Grant (use Gerrit)
2016/12/08 02:31:15
std::move(task_runner)
 
maksims (do not use this acc)
2016/12/08 18:39:17
Done.
 
 | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::ProcessStoredRequests() { | 
| + DCHECK(CalledOnValidThread()); | 
| + std::vector<mojom::SensorType> request_types = GetRequestTypes(); | 
| + if (request_types.empty()) | 
| + return; | 
| + | 
| + for (auto const& type : request_types) { | 
| + SensorInfoLinux* device = nullptr; | 
| + auto device_entry = sensor_devices_by_type_.find(type); | 
| + if (device_entry != sensor_devices_by_type_.end()) | 
| + device = device_entry->second.get(); | 
| + CreateSensorAndNotify(type, device); | 
| + } | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::CreateSensorAndNotify( | 
| + mojom::SensorType type, | 
| + SensorInfoLinux* sensor_device) { | 
| + DCHECK(CalledOnValidThread()); | 
| + scoped_refptr<PlatformSensorLinux> sensor = nullptr; | 
| 
 
Reilly Grant (use Gerrit)
2016/12/08 02:31:15
No initialization necessary, scoped_refptr default
 
maksims (do not use this acc)
2016/12/08 18:39:17
Done.
 
 | 
| + mojo::ScopedSharedBufferMapping mapping = GetScopedSharedBufferMapping(type); | 
| + if (sensor_device && mapping && StartPollingThread()) { | 
| + sensor = | 
| + new PlatformSensorLinux(type, std::move(mapping), this, sensor_device, | 
| + polling_thread_->task_runner()); | 
| + } | 
| + NotifySensorCreated(type, sensor); | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::OnEnumerationReady() { | 
| + DCHECK(CalledOnValidThread()); | 
| + DCHECK(!enumeration_ready()); | 
| + enumeration_ready_ = true; | 
| + ProcessStoredRequests(); | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::OnDeviceAdded( | 
| + mojom::SensorType type, | 
| + std::unique_ptr<SensorInfoLinux> sensor_device) { | 
| + DCHECK(CalledOnValidThread()); | 
| + // At the moment, we support only one device per type. | 
| + if (base::ContainsKey(sensor_devices_by_type_, type)) | 
| + return; | 
| + sensor_devices_by_type_[type] = std::move(sensor_device); | 
| +} | 
| + | 
| +void PlatformSensorProviderLinux::OnDeviceRemoved( | 
| + mojom::SensorType type, | 
| + const std::string& device_node) { | 
| + DCHECK(CalledOnValidThread()); | 
| + auto it = sensor_devices_by_type_.find(type); | 
| + if (it == sensor_devices_by_type_.end()) | 
| + return; | 
| + if (it->second->device_node == device_node) | 
| + sensor_devices_by_type_.erase(it); | 
| } | 
| } // namespace device |