| // Copyright 2020 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "vm_tools/cicerone/shill_client.h" | |
| #include <utility> | |
| #include <vector> | |
| #include <base/check.h> | |
| #include <base/functional/bind.h> | |
| #include <base/logging.h> | |
| #include <brillo/variant_dictionary.h> | |
| #include <chromeos/dbus/service_constants.h> | |
| using org::chromium::flimflam::ManagerProxy; | |
| namespace vm_tools::cicerone { | |
| ShillClient::ShillClient(scoped_refptr<dbus::Bus> bus) | |
| : bus_(bus), | |
| manager_proxy_(new org::chromium::flimflam::ManagerProxy(bus_)) { | |
| // The Manager must be watched for changes to the default Service. | |
| manager_proxy_->RegisterPropertyChangedSignalHandler( | |
| base::BindRepeating(&ShillClient::OnManagerPropertyChange, | |
| weak_factory_.GetWeakPtr()), | |
| base::BindOnce(&ShillClient::OnManagerPropertyChangeRegistration, | |
| weak_factory_.GetWeakPtr())); | |
| auto owner_changed_cb = base::BindRepeating( | |
| &ShillClient::OnShillServiceOwnerChange, weak_factory_.GetWeakPtr()); | |
| bus_->GetObjectProxy(shill::kFlimflamServiceName, dbus::ObjectPath{"/"}) | |
| ->SetNameOwnerChangedCallback(owner_changed_cb); | |
| } | |
| void ShillClient::OnShillServiceOwnerChange(const std::string& old_owner, | |
| const std::string& new_owner) { | |
| std::unique_ptr<ManagerProxy> manager_proxy(new ManagerProxy(bus_)); | |
| manager_proxy_->ReleaseObjectProxy(base::DoNothing()); | |
| manager_proxy->RegisterPropertyChangedSignalHandler( | |
| base::BindRepeating(&ShillClient::OnManagerPropertyChange, | |
| weak_factory_.GetWeakPtr()), | |
| base::BindOnce(&ShillClient::OnManagerPropertyChangeRegistration, | |
| weak_factory_.GetWeakPtr())); | |
| manager_proxy_ = std::move(manager_proxy); | |
| } | |
| void ShillClient::OnManagerPropertyChangeRegistration( | |
| const std::string& interface, | |
| const std::string& signal_name, | |
| bool success) { | |
| CHECK(success) << "Unable to register for Manager change events"; | |
| brillo::VariantDictionary properties; | |
| if (!manager_proxy_->GetProperties(&properties, nullptr)) { | |
| LOG(ERROR) << "Unable to get shill Manager properties"; | |
| return; | |
| } | |
| auto it = properties.find(shill::kDefaultServiceProperty); | |
| CHECK(it != properties.end()) | |
| << "Shill should always publish a default service."; | |
| OnManagerPropertyChange(shill::kDefaultServiceProperty, it->second); | |
| } | |
| void ShillClient::OnManagerPropertyChange(const std::string& property_name, | |
| const brillo::Any& property_value) { | |
| // Only handle changes to the default service. | |
| if (property_name != shill::kDefaultServiceProperty) { | |
| return; | |
| } | |
| if (!default_service_changed_callback_.is_null()) { | |
| default_service_changed_callback_.Run(); | |
| } | |
| } | |
| void ShillClient::RegisterDefaultServiceChangedHandler( | |
| base::RepeatingCallback<void()> callback) { | |
| default_service_changed_callback_ = std::move(callback); | |
| } | |
| } // namespace vm_tools::cicerone |