| // 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 |