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> 233f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/type_name_undecorate.h> 24d6deb1d0357f47d5525bfaeffa6c201b19abd3e7Alex Deymo#include <shill/dbus-constants.h> 25d6deb1d0357f47d5525bfaeffa6c201b19abd3e7Alex Deymo#include <shill/dbus-proxies.h> 26b8803bbfe96abce0ae792a93bc975d478d98d16aAlex Deymo 27255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiangusing chromeos_update_engine::connection_utils::ParseConnectionType; 28305345001d85ca2282112c2a30fe75c7a4773491Alex Deymousing org::chromium::flimflam::ManagerProxyInterface; 29305345001d85ca2282112c2a30fe75c7a4773491Alex Deymousing org::chromium::flimflam::ServiceProxyInterface; 305ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnoldusing std::string; 315ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 3263784a578dd26880454d70797519358a2326291bAlex Deymonamespace chromeos_update_manager { 3355f39b7043fae6b7c27188d0cd797946098b42efGilad Arnold 3442c30c376cb7b0b459ff0cbf3ac23fe87ea64f4dAlex Deymobool RealShillProvider::Init() { 35305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo ManagerProxyInterface* manager_proxy = shill_proxy_->GetManagerProxy(); 36305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!manager_proxy) 375ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold return false; 385ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 39beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold // Subscribe to the manager's PropertyChanged signal. 40305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo manager_proxy->RegisterPropertyChangedSignalHandler( 41305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Bind(&RealShillProvider::OnManagerPropertyChanged, 42305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Unretained(this)), 43305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Bind(&RealShillProvider::OnSignalConnected, 44305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo base::Unretained(this))); 455ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 46ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold // Attempt to read initial connection status. Even if this fails because shill 47ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold // is not responding (e.g. it is down) we'll be notified via "PropertyChanged" 48ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold // signal as soon as it comes up, so this is not a critical step. 493f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::VariantDictionary properties; 503f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::ErrorPtr error; 51305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!manager_proxy->GetProperties(&properties, &error)) 52305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return true; 53305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo 54305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_default_service = 55305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo properties.find(shill::kDefaultServiceProperty); 56305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_default_service != properties.end()) { 57305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo OnManagerPropertyChanged(prop_default_service->first, 58305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo prop_default_service->second); 595ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold } 605ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 61ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return true; 625ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold} 635ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 64305345001d85ca2282112c2a30fe75c7a4773491Alex Deymovoid RealShillProvider::OnManagerPropertyChanged(const string& name, 653f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko const brillo::Any& value) { 66758dd53cf503adbcb049909f25f54603d411be09Alex Deymo if (name == shill::kDefaultServiceProperty) { 67758dd53cf503adbcb049909f25f54603d411be09Alex Deymo dbus::ObjectPath service_path = value.TryGet<dbus::ObjectPath>(); 68758dd53cf503adbcb049909f25f54603d411be09Alex Deymo if (!service_path.IsValid()) { 69758dd53cf503adbcb049909f25f54603d411be09Alex Deymo LOG(WARNING) << "Got an invalid DefaultService path. The property value " 70758dd53cf503adbcb049909f25f54603d411be09Alex Deymo "contains a " 71df6d9f499db5e3c3dc68926586704d6a5f908496Alex Vakulenko << value.GetUndecoratedTypeName() 72758dd53cf503adbcb049909f25f54603d411be09Alex Deymo << ", read as the object path: '" << service_path.value() 73758dd53cf503adbcb049909f25f54603d411be09Alex Deymo << "'"; 74758dd53cf503adbcb049909f25f54603d411be09Alex Deymo } 75758dd53cf503adbcb049909f25f54603d411be09Alex Deymo ProcessDefaultService(service_path); 76758dd53cf503adbcb049909f25f54603d411be09Alex Deymo } 775ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold} 785ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 79305345001d85ca2282112c2a30fe75c7a4773491Alex Deymovoid RealShillProvider::OnSignalConnected(const string& interface_name, 80305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const string& signal_name, 81305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo bool successful) { 82305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!successful) { 83305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo LOG(ERROR) << "Couldn't connect to the signal " << interface_name << "." 84305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo << signal_name; 855ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold } 865ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold} 875ef9c48aa07b14d6e0a2171fee4f295f6b3d2895Gilad Arnold 88305345001d85ca2282112c2a30fe75c7a4773491Alex Deymobool RealShillProvider::ProcessDefaultService( 89758dd53cf503adbcb049909f25f54603d411be09Alex Deymo const dbus::ObjectPath& default_service_path) { 90305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // We assume that if the service path didn't change, then the connection 91305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // type and the tethering status of it also didn't change. 92305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (default_service_path_ == default_service_path) 93ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold return true; 94ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 95d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold // Update the connection status. 96305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo default_service_path_ = default_service_path; 97758dd53cf503adbcb049909f25f54603d411be09Alex Deymo bool is_connected = (default_service_path_.IsValid() && 98758dd53cf503adbcb049909f25f54603d411be09Alex Deymo default_service_path_.value() != "/"); 99d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_is_connected_.SetValue(is_connected); 100d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_conn_last_changed_.SetValue(clock_->GetWallclockTime()); 101ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 102305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!is_connected) { 103305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.UnsetValue(); 104305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_tethering_.UnsetValue(); 105305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return true; 106305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 107ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 108305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // We create and dispose the ServiceProxyInterface on every request. 109305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo std::unique_ptr<ServiceProxyInterface> service = 110305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo shill_proxy_->GetServiceForPath(default_service_path_); 111ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold 112305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Get the connection properties synchronously. 1133f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::VariantDictionary properties; 1143f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::ErrorPtr error; 115305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (!service->GetProperties(&properties, &error)) { 116d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_conn_type_.UnsetValue(); 117d3df25fb62011b3f76d33545467c71de3aca771dGilad Arnold var_conn_tethering_.UnsetValue(); 118305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return false; 119ef120fac0ff6364aaa8c6d05339065f118be25acGilad Arnold } 120df3dd2438aef108ac66dc42a4eabae8c79ee88a3Gilad Arnold 121305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Get the connection tethering mode. 122305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_tethering = properties.find(shill::kTetheringProperty); 123305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_tethering == properties.end()) { 124305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Remove the value if not present on the service. This most likely means an 125305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // error in shill and the policy will handle it, but we will print a log 126305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // message as well for accessing an unused variable. 127305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_tethering_.UnsetValue(); 128758dd53cf503adbcb049909f25f54603d411be09Alex Deymo LOG(ERROR) << "Could not find connection type (service: " 129758dd53cf503adbcb049909f25f54603d411be09Alex Deymo << default_service_path_.value() << ")"; 130305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 131305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // If the property doesn't contain a string value, the empty string will 132305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // become kUnknown. 133305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_tethering_.SetValue( 134255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang chromeos_update_engine::connection_utils::ParseConnectionTethering( 135255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang prop_tethering->second.TryGet<string>())); 136305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 137beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 138305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo // Get the connection type. 139305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_type = properties.find(shill::kTypeProperty); 140305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_type == properties.end()) { 141305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.UnsetValue(); 142758dd53cf503adbcb049909f25f54603d411be09Alex Deymo LOG(ERROR) << "Could not find connection tethering mode (service: " 143758dd53cf503adbcb049909f25f54603d411be09Alex Deymo << default_service_path_.value() << ")"; 144305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 145305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo string type_str = prop_type->second.TryGet<string>(); 146305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (type_str == shill::kTypeVPN) { 147305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo const auto& prop_physical = 148305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo properties.find(shill::kPhysicalTechnologyProperty); 149305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo if (prop_physical == properties.end()) { 150305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo LOG(ERROR) << "No PhysicalTechnology property found for a VPN" 151758dd53cf503adbcb049909f25f54603d411be09Alex Deymo << " connection (service: " << default_service_path_.value() 152305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo << "). Using default kUnknown value."; 153255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang var_conn_type_.SetValue( 154255e22b82af3a52218eaea66acc734ec25cfeab6Sen Jiang chromeos_update_engine::ConnectionType::kUnknown); 155305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 156305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.SetValue( 157305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo ParseConnectionType(prop_physical->second.TryGet<string>())); 158305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 159305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } else { 160305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo var_conn_type_.SetValue(ParseConnectionType(type_str)); 161305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 162305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo } 163beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 164305345001d85ca2282112c2a30fe75c7a4773491Alex Deymo return true; 165beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold} 166beb39e9e5fcfae13f2c97b4ee7214484de2d3728Gilad Arnold 16763784a578dd26880454d70797519358a2326291bAlex Deymo} // namespace chromeos_update_manager 168