blob: 346f73c2faac26fc8a8dbe22b9c2ba5e777d2285 [file] [log] [blame]
// Copyright 2018 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 "power_manager/powerd/policy/user_proximity_handler.h"
#include <memory>
#include <utility>
#include <base/logging.h>
#include "power_manager/powerd/policy/wifi_controller.h"
#include "power_manager/powerd/system/user_proximity_watcher_interface.h"
namespace power_manager {
namespace policy {
UserProximityHandler::UserProximityHandler() = default;
UserProximityHandler::~UserProximityHandler() {
if (user_proximity_watcher_)
user_proximity_watcher_->RemoveObserver(this);
}
bool UserProximityHandler::Init(
system::UserProximityWatcherInterface* user_prox_watcher,
Delegate* wifi_delegate,
Delegate* lte_delegate) {
DCHECK(user_prox_watcher);
wifi_delegate_ = wifi_delegate;
lte_delegate_ = lte_delegate;
user_proximity_watcher_ = user_prox_watcher;
user_proximity_watcher_->AddObserver(this);
return true;
}
void UserProximityHandler::OnNewSensor(int id, uint32_t roles) {
// It is in general not possible to figure out the initial proximity state
// in all cases (e.g. the sensor may have never fired an interrupt thus far).
// We take a cautious stance here and decide that - until a FAR value is
// returned to us via IIO event - the proximity for a new sensor is NEAR.
constexpr UserProximity default_initial_proximity = UserProximity::NEAR;
const bool includes_wifi =
(roles & system::UserProximityObserver::SensorRole::SENSOR_ROLE_WIFI) !=
0;
const bool includes_lte =
(roles & system::UserProximityObserver::SensorRole::SENSOR_ROLE_LTE) != 0;
LOG(INFO) << "New proximity sensor with id " << id << ": "
<< (includes_wifi ? " wifi" : "") << (includes_lte ? " lte" : "");
if (includes_wifi && wifi_delegate_) {
wifi_proximity_voting_.Vote(id, default_initial_proximity);
wifi_delegate_->ProximitySensorDetected(default_initial_proximity);
}
if (includes_lte && lte_delegate_) {
lte_proximity_voting_.Vote(id, default_initial_proximity);
lte_delegate_->ProximitySensorDetected(default_initial_proximity);
}
if (includes_wifi || includes_lte) {
sensor_roles_.emplace(id, roles);
} else {
LOG(WARNING) << "Detected a sensor that does not act upon any subsystem";
}
}
void UserProximityHandler::OnProximityEvent(int id, UserProximity value) {
auto iter = sensor_roles_.find(id);
if (iter == sensor_roles_.end()) {
// This sensor is not handling any subsystem of interest. Ignore.
return;
}
const bool includes_wifi =
(iter->second &
system::UserProximityObserver::SensorRole::SENSOR_ROLE_WIFI) != 0;
const bool includes_lte =
(iter->second &
system::UserProximityObserver::SensorRole::SENSOR_ROLE_LTE) != 0;
const bool did_wifi_change =
includes_wifi ? wifi_proximity_voting_.Vote(id, value) : false;
const bool did_lte_change =
includes_lte ? lte_proximity_voting_.Vote(id, value) : false;
if (did_wifi_change && wifi_delegate_) {
UserProximity wifi_proximity = wifi_proximity_voting_.GetVote();
wifi_delegate_->HandleProximityChange(wifi_proximity);
}
if (did_lte_change && lte_delegate_) {
UserProximity lte_proximity = lte_proximity_voting_.GetVote();
lte_delegate_->HandleProximityChange(lte_proximity);
}
}
} // namespace policy
} // namespace power_manager