Chromium Code Reviews| Index: content/browser/battery_status/battery_status_service.cc |
| diff --git a/content/browser/battery_status/battery_status_service.cc b/content/browser/battery_status/battery_status_service.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0cc4439bd6260320c01fdbef745b7282808f4880 |
| --- /dev/null |
| +++ b/content/browser/battery_status/battery_status_service.cc |
| @@ -0,0 +1,125 @@ |
| +// Copyright 2014 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 "content/browser/battery_status/battery_status_service.h" |
| + |
| +#include "base/bind.h" |
| +#include "content/browser/battery_status/battery_status_manager.h" |
| +#include "content/public/browser/browser_thread.h" |
| + |
| +namespace content { |
| + |
| +static void AddCallbackIfNecessary( |
| + std::vector<BatteryStatusUpdateCallback>& callbacks, |
| + const BatteryStatusUpdateCallback& callback) { |
| + for (size_t i = 0; i < callbacks.size(); ++i) { |
| + if (callbacks[i].Equals(callback)) |
| + return; |
| + } |
| + callbacks.push_back(callback); |
| +} |
| + |
| +static void RemoveCallbackIfNecessary( |
| + std::vector<BatteryStatusUpdateCallback>& callbacks, |
| + const BatteryStatusUpdateCallback& callback) { |
| + for (size_t i = 0; i < callbacks.size(); ++i) { |
| + if (callbacks[i].Equals(callback)) { |
| + callbacks[i] = callbacks.back(); |
| + callbacks.pop_back(); |
| + return; |
| + } |
| + } |
| +} |
| + |
| +BatteryStatusService::BatteryStatusService() |
| + : status_updated_(false), |
| + is_shutdown_(false) { |
| + update_callback_ = base::Bind(&BatteryStatusService::UpdateBatteryStatus, |
| + base::Unretained(this)); |
| +} |
| + |
| +BatteryStatusService::~BatteryStatusService() { |
| +} |
| + |
| +BatteryStatusService* BatteryStatusService::GetInstance() { |
| + return Singleton<BatteryStatusService, |
| + LeakySingletonTraits<BatteryStatusService> >::get(); |
| +} |
| + |
| +void BatteryStatusService::AddCallback( |
| + const BatteryStatusUpdateCallback& callback) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + DCHECK(!is_shutdown_); |
| + |
| + if (!battery_fetcher_) |
| + battery_fetcher_.reset(new BatteryStatusManager(update_callback_)); |
| + |
| + if (callbacks_.empty()) |
| + battery_fetcher_->StartListeningBatteryChange(); |
| + |
| + if (status_updated_) { |
| + // Send recent status to the new callback if already available. |
| + callback.Run(status_); |
| + } |
| + |
| + AddCallbackIfNecessary(callbacks_, callback); |
|
jochen (gone - plz use gerrit)
2014/05/19 13:14:22
can this actually happen that the same callback is
timvolodine
2014/05/22 10:02:33
actually no, the message filter keeps track of whe
|
| +} |
| + |
| +void BatteryStatusService::RemoveCallback( |
| + const BatteryStatusUpdateCallback& callback) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + DCHECK(!is_shutdown_); |
| + |
| + RemoveCallbackIfNecessary(callbacks_, callback); |
| + |
| + if (callbacks_.empty()) { |
| + battery_fetcher_->StopListeningBatteryChange(); |
| + status_updated_ = false; |
| + } |
| +} |
| + |
| +const BatteryStatusUpdateCallback& |
| +BatteryStatusService::update_callback() const { |
| + return update_callback_; |
| +} |
| + |
| +void BatteryStatusService::UpdateBatteryStatus( |
| + const blink::WebBatteryStatus& status) { |
| + DCHECK(!is_shutdown_); |
| + BrowserThread::PostTask(BrowserThread::IO, |
|
Michael van Ouwerkerk
2014/05/19 11:19:22
I think you can turn BatteryStatusMessageFilter in
timvolodine
2014/05/22 10:02:33
The idea is to keep non-UI things away from the UI
|
| + FROM_HERE, |
| + base::Bind(&BatteryStatusService::NotifyConsumers, |
| + base::Unretained(this), status)); |
| +} |
| + |
| +void BatteryStatusService::NotifyConsumers( |
| + const blink::WebBatteryStatus& status) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + |
| + if (callbacks_.empty()) |
| + return; |
| + |
| + status_ = status; |
| + status_updated_ = true; |
| + std::vector<BatteryStatusUpdateCallback>::const_iterator it = |
| + callbacks_.begin(); |
| + for (; it != callbacks_.end(); ++it) |
| + (*it).Run(status_); |
| +} |
| + |
| +void BatteryStatusService::Shutdown() { |
| + battery_fetcher_.reset(); |
| + is_shutdown_ = true; |
| +} |
| + |
| +void BatteryStatusService::SetBatteryManagerForTests( |
| + BatteryStatusManagerInterface* test_battery_manager) { |
| + battery_fetcher_.reset(test_battery_manager); |
| + blink::WebBatteryStatus status; |
| + status_ = status; |
| + status_updated_ = false; |
| + callbacks_.clear(); |
| +} |
| + |
| +} // namespace content |