blob: 7fc82aea23793daa1110384dead43dca1c5d3d48 [file] [log] [blame]
// Copyright 2015 The Chromium OS 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 "thermald/thermal_zone_controller.h"
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "thermald/key_value_publisher.h"
#include "thermald/thermal_zone.h"
using std::string;
using std::vector;
namespace thermald {
ThermalZoneController::ThermalZoneController(
const ThermalZone *zone, KeyValuePublisher *outputs,
vector<TemperatureMonitorInterface *> temperature_monitors)
: zone_(zone),
temperature_monitors_(temperature_monitors),
is_running_(false),
thermal_state_engine_(zone),
cur_thermal_state_(&thermal_state_engine_.current_state()),
outputs_(outputs),
weak_ptr_factory_(this) {
DCHECK(zone);
DVLOG(3) << "[" << zone_->name << "] Constructor";
}
ThermalZoneController::~ThermalZoneController() {
DVLOG(3) << "[" << zone_->name << "] Destructor";
if (is_running_) {
Stop();
}
}
bool ThermalZoneController::Start() {
if (is_running_) {
LOG(WARNING) << "[" << zone_->name << "] Is already running";
return false;
}
DVLOG(1) << "[" << zone_->name << "] Starting";
for (auto tm : temperature_monitors_) {
subscriptions_.push_back(tm->Subscribe(
base::Bind(&ThermalZoneController::ProcessTemperatureUpdate,
weak_ptr_factory_.GetWeakPtr(), tm->name())));
}
is_running_ = true;
return true;
}
bool ThermalZoneController::Stop() {
if (!is_running_) {
DLOG(WARNING) << "[" << zone_->name << "] Is not running";
return false;
}
DVLOG(1) << "[" << zone_->name << "] Stopping";
subscriptions_.clear();
is_running_ = false;
return true;
}
void ThermalZoneController::ProcessTemperatureUpdate(const string &sensor,
int temperature) {
if (!thermal_state_engine_.ProcessTemperatureUpdate(
sensor, temperature)) {
LOG(ERROR) << "[" << zone_->name
<< "] Failed to process temperature update";
return;
}
// The state object is guaranteed to be valid during the lifetime of the
// ThermalStateEngine.
const ThermalState &state = thermal_state_engine_.current_state();
if (cur_thermal_state_->id != state.id) {
// New thermal state entered => set outputs.
DLOG(INFO) << "[" << zone_->name
<< "] Setting outputs for state " << state.id;
outputs_->Publish("thermal_zone." + zone_->name + ".state", state.id);
for (auto &o : state.outputs) {
outputs_->Publish(o.key, o.value);
}
cur_thermal_state_ = &state;
}
}
} // namespace thermald