| Index: device/sensor/sensor_service.cc
|
| diff --git a/device/sensor/sensor_service.cc b/device/sensor/sensor_service.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..98c2d134564836c42acdca5bf3d12131996d9738
|
| --- /dev/null
|
| +++ b/device/sensor/sensor_service.cc
|
| @@ -0,0 +1,93 @@
|
| +// 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/sensor/sensor_service.h"
|
| +
|
| +#include <utility>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/single_thread_task_runner.h"
|
| +#include "device/sensor/sensor_impl.h"
|
| +#include "device/sensor/sensor_manager.h"
|
| +
|
| +namespace device {
|
| +
|
| +SensorService::SensorService()
|
| + : main_thread_task_runner_(base::MessageLoop::current()->task_runner()),
|
| + update_callback_(
|
| + base::Bind(&SensorService::NotifyConsumers, base::Unretained(this))),
|
| + reading_updated_(false),
|
| + is_shutdown_(false) {
|
| + callback_list_.set_removal_callback(
|
| + base::Bind(&SensorService::ConsumersChanged, base::Unretained(this)));
|
| +}
|
| +
|
| +SensorService::~SensorService() {}
|
| +
|
| +SensorService* SensorService::GetInstance() {
|
| + return base::Singleton<SensorService,
|
| + base::LeakySingletonTraits<SensorService>>::get();
|
| +}
|
| +
|
| +std::unique_ptr<SensorService::SensorUpdateSubscription>
|
| +SensorService::AddCallback(const SensorUpdateCallback& callback) {
|
| + DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
|
| + DCHECK(!is_shutdown_);
|
| +
|
| + if (!sensor_fetcher_)
|
| + sensor_fetcher_ = SensorManager::Create(update_callback_);
|
| +
|
| + if (callback_list_.empty()) {
|
| + bool success = sensor_fetcher_->StartListeningSensorChange();
|
| + // On failure pass the default values back.
|
| + if (!success)
|
| + callback.Run(AmbientLightSensorReading());
|
| + }
|
| +
|
| + if (reading_updated_) {
|
| + // Send recent reading to the new callback if already available.
|
| + callback.Run(reading_);
|
| + }
|
| +
|
| + return callback_list_.Add(callback);
|
| +}
|
| +
|
| +void SensorService::ConsumersChanged() {
|
| + if (is_shutdown_)
|
| + return;
|
| +
|
| + if (callback_list_.empty()) {
|
| + sensor_fetcher_->StopListeningSensorChange();
|
| + reading_updated_ = false;
|
| + }
|
| +}
|
| +
|
| +void SensorService::NotifyConsumers(const AmbientLightSensorReading& reading) {
|
| + DCHECK(!is_shutdown_);
|
| +
|
| + main_thread_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&SensorService::NotifyConsumersOnMainThread,
|
| + base::Unretained(this), reading));
|
| +}
|
| +
|
| +void SensorService::NotifyConsumersOnMainThread(
|
| + const AmbientLightSensorReading& reading) {
|
| + DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
|
| + if (callback_list_.empty())
|
| + return;
|
| +
|
| + reading_ = reading;
|
| + reading_updated_ = true;
|
| + callback_list_.Notify(reading_);
|
| +}
|
| +
|
| +void SensorService::Shutdown() {
|
| + if (!callback_list_.empty())
|
| + sensor_fetcher_->StopListeningSensorChange();
|
| + sensor_fetcher_.reset();
|
| + is_shutdown_ = true;
|
| +}
|
| +
|
| +} // namespace device
|
|
|