blob: a0d9707a05f14dd9942704f4b2f9d8460c9cacea [file] [log] [blame]
// Copyright (c) 2013 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 "services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/sequenced_task_runner.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
namespace device {
PowerMonitorBroadcastSource::PowerMonitorBroadcastSource(
scoped_refptr<base::SequencedTaskRunner> task_runner)
: PowerMonitorBroadcastSource(std::make_unique<Client>(),
task_runner) {}
PowerMonitorBroadcastSource::PowerMonitorBroadcastSource(
std::unique_ptr<Client> client,
scoped_refptr<base::SequencedTaskRunner> task_runner)
: client_(std::move(client)), task_runner_(task_runner) {}
PowerMonitorBroadcastSource::~PowerMonitorBroadcastSource() {
task_runner_->DeleteSoon(FROM_HERE, client_.release());
}
void PowerMonitorBroadcastSource::Init(service_manager::Connector* connector) {
if (connector) {
task_runner_->PostTask(
FROM_HERE, base::BindOnce(&PowerMonitorBroadcastSource::Client::Init,
base::Unretained(client_.get()),
base::Passed(connector->Clone())));
}
}
void PowerMonitorBroadcastSource::Shutdown() {
// When power monitor and source are destroyed, the IO thread could still be
// receiving mojo messages that access the monitor and source in
// |ProcessPowerEvent|, thus causing a data race. Calling Shutdown() on the
// client tells it to ignore future mojo messages; by making this call
// *before* the power monitor and source destruction proceed, we prevent the
// data race.
client_->Shutdown();
}
bool PowerMonitorBroadcastSource::IsOnBatteryPowerImpl() {
return client_->last_reported_on_battery_power_state();
}
PowerMonitorBroadcastSource::Client::Client() : binding_(this) {}
PowerMonitorBroadcastSource::Client::~Client() {}
void PowerMonitorBroadcastSource::Client::Init(
std::unique_ptr<service_manager::Connector> connector) {
base::AutoLock auto_lock(is_shutdown_lock_);
if (is_shutdown_)
return;
connector_ = std::move(connector);
device::mojom::PowerMonitorPtr power_monitor;
connector_->BindInterface(device::mojom::kServiceName,
mojo::MakeRequest(&power_monitor));
device::mojom::PowerMonitorClientPtr client;
binding_.Bind(mojo::MakeRequest(&client));
power_monitor->AddClient(std::move(client));
}
void PowerMonitorBroadcastSource::Client::Shutdown() {
base::AutoLock auto_lock(is_shutdown_lock_);
DCHECK(!is_shutdown_);
is_shutdown_ = true;
}
void PowerMonitorBroadcastSource::Client::PowerStateChange(
bool on_battery_power) {
base::AutoLock auto_lock(is_shutdown_lock_);
if (is_shutdown_)
return;
last_reported_on_battery_power_state_ = on_battery_power;
ProcessPowerEvent(PowerMonitorSource::POWER_STATE_EVENT);
}
void PowerMonitorBroadcastSource::Client::Suspend() {
base::AutoLock auto_lock(is_shutdown_lock_);
if (is_shutdown_)
return;
ProcessPowerEvent(PowerMonitorSource::SUSPEND_EVENT);
}
void PowerMonitorBroadcastSource::Client::Resume() {
base::AutoLock auto_lock(is_shutdown_lock_);
if (is_shutdown_)
return;
ProcessPowerEvent(PowerMonitorSource::RESUME_EVENT);
}
} // namespace device