platform_sensor_provider_linux.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/device/generic_sensor/platform_sensor_provider_linux.h"
  5. #include <utility>
  6. #include <vector>
  7. #include "base/bind.h"
  8. #include "base/compiler_specific.h"
  9. #include "base/containers/contains.h"
  10. #include "base/memory/scoped_refptr.h"
  11. #include "base/task/task_runner_util.h"
  12. #include "base/task/thread_pool.h"
  13. #include "services/device/generic_sensor/linux/sensor_data_linux.h"
  14. #include "services/device/generic_sensor/platform_sensor_linux.h"
  15. #include "services/device/generic_sensor/platform_sensor_reader_linux.h"
  16. namespace device {
  17. namespace {
  18. constexpr base::TaskTraits kBlockingTaskRunnerTraits = {
  19. base::MayBlock(), base::TaskPriority::USER_VISIBLE,
  20. base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};
  21. } // namespace
  22. PlatformSensorProviderLinux::PlatformSensorProviderLinux()
  23. : blocking_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
  24. kBlockingTaskRunnerTraits)),
  25. sensor_device_manager_(nullptr,
  26. base::OnTaskRunnerDeleter(blocking_task_runner_)) {
  27. sensor_device_manager_.reset(
  28. new SensorDeviceManager(weak_ptr_factory_.GetWeakPtr()));
  29. }
  30. PlatformSensorProviderLinux::~PlatformSensorProviderLinux() = default;
  31. void PlatformSensorProviderLinux::CreateSensorInternal(
  32. mojom::SensorType type,
  33. SensorReadingSharedBuffer* reading_buffer,
  34. CreateSensorCallback callback) {
  35. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  36. switch (enumeration_status_) {
  37. case SensorEnumerationState::kNotEnumerated: {
  38. // Unretained() is safe because the deletion of |sensor_device_manager_|
  39. // is scheduled on |blocking_task_runner_| when
  40. // PlatformSensorProviderLinux is deleted.
  41. const bool will_run = blocking_task_runner_->PostTask(
  42. FROM_HERE,
  43. base::BindOnce(&SensorDeviceManager::Start,
  44. base::Unretained(sensor_device_manager_.get())));
  45. if (will_run)
  46. enumeration_status_ = SensorEnumerationState::kEnumerationStarted;
  47. [[fallthrough]];
  48. }
  49. case SensorEnumerationState::kEnumerationStarted:
  50. return;
  51. case SensorEnumerationState::kEnumerationFinished:
  52. if (IsFusionSensorType(type)) {
  53. CreateFusionSensor(type, reading_buffer, std::move(callback));
  54. return;
  55. }
  56. SensorInfoLinux* sensor_device = GetSensorDevice(type);
  57. if (!sensor_device) {
  58. std::move(callback).Run(nullptr);
  59. return;
  60. }
  61. std::move(callback).Run(base::MakeRefCounted<PlatformSensorLinux>(
  62. type, reading_buffer, this, sensor_device));
  63. break;
  64. }
  65. }
  66. void PlatformSensorProviderLinux::FreeResources() {
  67. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  68. }
  69. bool PlatformSensorProviderLinux::IsSensorTypeAvailable(
  70. mojom::SensorType type) const {
  71. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  72. return GetSensorDevice(type);
  73. }
  74. SensorInfoLinux* PlatformSensorProviderLinux::GetSensorDevice(
  75. mojom::SensorType type) const {
  76. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  77. const auto sensor = sensor_devices_by_type_.find(type);
  78. if (sensor == sensor_devices_by_type_.end())
  79. return nullptr;
  80. return sensor->second.get();
  81. }
  82. void PlatformSensorProviderLinux::SetSensorDeviceManagerForTesting(
  83. std::unique_ptr<SensorDeviceManager> sensor_device_manager) {
  84. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  85. sensor_device_manager_.reset(sensor_device_manager.release());
  86. }
  87. void PlatformSensorProviderLinux::ProcessStoredRequests() {
  88. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  89. std::vector<mojom::SensorType> request_types = GetPendingRequestTypes();
  90. if (request_types.empty())
  91. return;
  92. for (auto const& type : request_types) {
  93. if (IsFusionSensorType(type)) {
  94. SensorReadingSharedBuffer* reading_buffer =
  95. GetSensorReadingSharedBufferForType(type);
  96. CreateFusionSensor(
  97. type, reading_buffer,
  98. base::BindOnce(&PlatformSensorProviderLinux::NotifySensorCreated,
  99. base::Unretained(this), type));
  100. continue;
  101. }
  102. SensorInfoLinux* device = nullptr;
  103. auto device_entry = sensor_devices_by_type_.find(type);
  104. if (device_entry != sensor_devices_by_type_.end())
  105. device = device_entry->second.get();
  106. CreateSensorAndNotify(type, device);
  107. }
  108. }
  109. void PlatformSensorProviderLinux::CreateSensorAndNotify(
  110. mojom::SensorType type,
  111. SensorInfoLinux* sensor_device) {
  112. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  113. scoped_refptr<PlatformSensorLinux> sensor;
  114. SensorReadingSharedBuffer* reading_buffer =
  115. GetSensorReadingSharedBufferForType(type);
  116. if (sensor_device && reading_buffer) {
  117. sensor = new PlatformSensorLinux(type, reading_buffer, this, sensor_device);
  118. }
  119. NotifySensorCreated(type, sensor);
  120. }
  121. void PlatformSensorProviderLinux::OnSensorNodesEnumerated() {
  122. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  123. DCHECK_EQ(enumeration_status_, SensorEnumerationState::kEnumerationStarted);
  124. enumeration_status_ = SensorEnumerationState::kEnumerationFinished;
  125. ProcessStoredRequests();
  126. }
  127. void PlatformSensorProviderLinux::OnDeviceAdded(
  128. mojom::SensorType type,
  129. std::unique_ptr<SensorInfoLinux> sensor_device) {
  130. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  131. // At the moment, we support only one device per type.
  132. if (base::Contains(sensor_devices_by_type_, type)) {
  133. DVLOG(1) << "Sensor ignored. Type " << type
  134. << ". Node: " << sensor_device->device_node;
  135. return;
  136. }
  137. sensor_devices_by_type_[type] = std::move(sensor_device);
  138. }
  139. void PlatformSensorProviderLinux::OnDeviceRemoved(
  140. mojom::SensorType type,
  141. const std::string& device_node) {
  142. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  143. auto it = sensor_devices_by_type_.find(type);
  144. if (it != sensor_devices_by_type_.end() &&
  145. it->second->device_node == device_node) {
  146. sensor_devices_by_type_.erase(it);
  147. }
  148. }
  149. } // namespace device