real_shill_provider.cc revision b8803bbfe96abce0ae792a93bc975d478d98d16a
1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2014 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 1655f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold 1763784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/real_shill_provider.h" 1855f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold 195ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include <string> 205ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 215ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include <base/logging.h> 2275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/stringprintf.h> 235ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold#include <chromeos/dbus/service_constants.h> 245ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 25b8803bbfe96abce0ae792a93bc975d478d98d16aAlex Deymo#include "shill/dbus-proxies.h" 26b8803bbfe96abce0ae792a93bc975d478d98d16aAlex Deymo 27305345001d85ca2282112c2a30fe75c7a4773491Alex Deymousing org::chromium::flimflam::ManagerProxyInterface; 28305345001d85ca2282112c2a30fe75c7a4773491Alex Deymousing org::chromium::flimflam::ServiceProxyInterface; 295ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldusing std::string; 305ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 3163784a578dd26880454d70797519358a2326291bAlex Deymonamespace chromeos_update_manager { 3255f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold 33305345001d85ca2282112c2a30fe75c7a4773491Alex DeymoConnectionType RealShillProvider::ParseConnectionType(const string& type_str) { 34305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (type_str == shill::kTypeEthernet) { 35ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionType::kEthernet; 36305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else if (type_str == shill::kTypeWifi) { 37ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionType::kWifi; 38305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else if (type_str == shill::kTypeWimax) { 39ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionType::kWimax; 40305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else if (type_str == shill::kTypeBluetooth) { 41ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionType::kBluetooth; 42305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else if (type_str == shill::kTypeCellular) { 43ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionType::kCellular; 44305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 45ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionType::kUnknown; 46ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold} 47ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 48ef120fac0ff6364aaa8c6d05339065f118be25acGilad ArnoldConnectionTethering RealShillProvider::ParseConnectionTethering( 49305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const string& tethering_str) { 50305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (tethering_str == shill::kTetheringNotDetectedState) { 51ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionTethering::kNotDetected; 52305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else if (tethering_str == shill::kTetheringSuspectedState) { 53ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionTethering::kSuspected; 54305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else if (tethering_str == shill::kTetheringConfirmedState) { 55ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionTethering::kConfirmed; 56305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 57ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return ConnectionTethering::kUnknown; 58ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold} 59beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 6042c30c376cb7b0b459ff0cbf3ac23fe87ea64f4dAlex Deymobool RealShillProvider::Init() { 61305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo ManagerProxyInterface* manager_proxy = shill_proxy_->GetManagerProxy(); 62305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!manager_proxy) 635ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold return false; 645ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 65beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold // Subscribe to the manager's PropertyChanged signal. 66305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo manager_proxy->RegisterPropertyChangedSignalHandler( 67305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Bind(&RealShillProvider::OnManagerPropertyChanged, 68305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Unretained(this)), 69305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Bind(&RealShillProvider::OnSignalConnected, 70305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Unretained(this))); 715ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 72ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold // Attempt to read initial connection status. Even if this fails because shill 73ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold // is not responding (e.g. it is down) we'll be notified via "PropertyChanged" 74ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold // signal as soon as it comes up, so this is not a critical step. 75305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo chromeos::VariantDictionary properties; 76305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo chromeos::ErrorPtr error; 77305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!manager_proxy->GetProperties(&properties, &error)) 78305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return true; 79305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo 80305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_default_service = 81305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo properties.find(shill::kDefaultServiceProperty); 82305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_default_service != properties.end()) { 83305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo OnManagerPropertyChanged(prop_default_service->first, 84305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo prop_default_service->second); 855ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold } 865ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 87ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return true; 885ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold} 895ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 90305345001d85ca2282112c2a30fe75c7a4773491Alex Deymovoid RealShillProvider::OnManagerPropertyChanged(const string& name, 91305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const chromeos::Any& value) { 92305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (name == shill::kDefaultServiceProperty) 93305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo ProcessDefaultService(value.TryGet<dbus::ObjectPath>().value()); 945ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold} 955ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 96305345001d85ca2282112c2a30fe75c7a4773491Alex Deymovoid RealShillProvider::OnSignalConnected(const string& interface_name, 97305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const string& signal_name, 98305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo bool successful) { 99305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!successful) { 100305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo LOG(ERROR) << "Couldn't connect to the signal " << interface_name << "." 101305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo << signal_name; 1025ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold } 1035ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold} 1045ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 105305345001d85ca2282112c2a30fe75c7a4773491Alex Deymobool RealShillProvider::ProcessDefaultService( 106305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const string& default_service_path) { 107305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // We assume that if the service path didn't change, then the connection 108305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // type and the tethering status of it also didn't change. 109305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (default_service_path_ == default_service_path) 110ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return true; 111ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 112d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold // Update the connection status. 113305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo default_service_path_ = default_service_path; 114d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold bool is_connected = (default_service_path_ != "/"); 115d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_is_connected_.SetValue(is_connected); 116d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_conn_last_changed_.SetValue(clock_->GetWallclockTime()); 117ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 118305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!is_connected) { 119305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.UnsetValue(); 120305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_tethering_.UnsetValue(); 121305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return true; 122305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 123ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 124305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // We create and dispose the ServiceProxyInterface on every request. 125305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo std::unique_ptr<ServiceProxyInterface> service = 126305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo shill_proxy_->GetServiceForPath(default_service_path_); 127ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 128305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Get the connection properties synchronously. 129305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo chromeos::VariantDictionary properties; 130305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo chromeos::ErrorPtr error; 131305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!service->GetProperties(&properties, &error)) { 132d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_conn_type_.UnsetValue(); 133d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_conn_tethering_.UnsetValue(); 134305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return false; 135ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold } 136df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold 137305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Get the connection tethering mode. 138305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_tethering = properties.find(shill::kTetheringProperty); 139305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_tethering == properties.end()) { 140305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Remove the value if not present on the service. This most likely means an 141305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // error in shill and the policy will handle it, but we will print a log 142305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // message as well for accessing an unused variable. 143305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_tethering_.UnsetValue(); 144305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo LOG(ERROR) << "Could not find connection type (" << default_service_path_ 145305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo << ")"; 146305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 147305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // If the property doesn't contain a string value, the empty string will 148305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // become kUnknown. 149305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_tethering_.SetValue( 150305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo ParseConnectionTethering(prop_tethering->second.TryGet<string>())); 151305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 152beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 153305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Get the connection type. 154305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_type = properties.find(shill::kTypeProperty); 155305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_type == properties.end()) { 156305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.UnsetValue(); 157305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo LOG(ERROR) << "Could not find connection tethering mode (" 158305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo << default_service_path_ << ")"; 159305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 160305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo string type_str = prop_type->second.TryGet<string>(); 161305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (type_str == shill::kTypeVPN) { 162305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_physical = 163305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo properties.find(shill::kPhysicalTechnologyProperty); 164305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_physical == properties.end()) { 165305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo LOG(ERROR) << "No PhysicalTechnology property found for a VPN" 166305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo << " connection (service: " << default_service_path 167305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo << "). Using default kUnknown value."; 168305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.SetValue(ConnectionType::kUnknown); 169305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 170305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.SetValue( 171305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo ParseConnectionType(prop_physical->second.TryGet<string>())); 172305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 173305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 174305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.SetValue(ParseConnectionType(type_str)); 175305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 176305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 177beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 178305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return true; 179beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold} 180beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 18163784a578dd26880454d70797519358a2326291bAlex Deymo} // namespace chromeos_update_manager 182