1// 2// Copyright (C) 2015 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "apmanager/dbus/shill_dbus_proxy.h" 18 19#include <base/bind.h> 20#include <brillo/errors/error.h> 21 22#if !defined(__ANDROID__) 23#include <chromeos/dbus/service_constants.h> 24#else 25#include <dbus/apmanager/dbus-constants.h> 26#endif // __ANDROID__ 27 28#include "apmanager/event_dispatcher.h" 29 30using std::string; 31 32namespace apmanager { 33 34ShillDBusProxy::ShillDBusProxy( 35 const scoped_refptr<dbus::Bus>& bus, 36 const base::Closure& service_appeared_callback, 37 const base::Closure& service_vanished_callback) 38 : manager_proxy_(new org::chromium::flimflam::ManagerProxy(bus)), 39 dispatcher_(EventDispatcher::GetInstance()), 40 service_appeared_callback_(service_appeared_callback), 41 service_vanished_callback_(service_vanished_callback), 42 service_available_(false) { 43 // Monitor service owner changes. This callback lives for the lifetime of 44 // the ObjectProxy. 45 manager_proxy_->GetObjectProxy()->SetNameOwnerChangedCallback( 46 base::Bind(&ShillDBusProxy::OnServiceOwnerChanged, 47 weak_factory_.GetWeakPtr())); 48 49 // One time callback when service becomes available. 50 manager_proxy_->GetObjectProxy()->WaitForServiceToBeAvailable( 51 base::Bind(&ShillDBusProxy::OnServiceAvailable, 52 weak_factory_.GetWeakPtr())); 53} 54 55ShillDBusProxy::~ShillDBusProxy() {} 56 57bool ShillDBusProxy::ClaimInterface(const string& interface_name) { 58 if (!service_available_) { 59 LOG(ERROR) << "ClaimInterface failed: service not available"; 60 return false; 61 } 62 brillo::ErrorPtr error; 63 if (!manager_proxy_->ClaimInterface(kServiceName, interface_name, &error)) { 64 LOG(ERROR) << "Failed to claim interface from shill: " 65 << error->GetCode() << " " << error->GetMessage(); 66 return false; 67 } 68 return true; 69} 70 71bool ShillDBusProxy::ReleaseInterface(const string& interface_name) { 72 if (!service_available_) { 73 LOG(ERROR) << "ReleaseInterface failed: service not available"; 74 return false; 75 } 76 brillo::ErrorPtr error; 77 if (!manager_proxy_->ReleaseInterface(kServiceName, interface_name, &error)) { 78 LOG(ERROR) << "Failed to release interface from shill: " 79 << error->GetCode() << " " << error->GetMessage(); 80 return false; 81 } 82 return true; 83} 84 85#if defined(__BRILLO__) 86bool ShillDBusProxy::SetupApModeInterface(string* interface_name) { 87 if (!service_available_) { 88 LOG(ERROR) << "SetupApModeInterface failed: service not available"; 89 return false; 90 } 91 brillo::ErrorPtr error; 92 if (!manager_proxy_->SetupApModeInterface(interface_name, &error)) { 93 LOG(ERROR) << "Failed to setup AP mode interface from shill: " 94 << error->GetCode() << " " << error->GetMessage(); 95 return false; 96 } 97 return true; 98} 99 100bool ShillDBusProxy::SetupStationModeInterface(string* interface_name) { 101 if (!service_available_) { 102 LOG(ERROR) << "SetupStationModeInterface failed: service not available"; 103 return false; 104 } 105 brillo::ErrorPtr error; 106 if (!manager_proxy_->SetupStationModeInterface(interface_name, &error)) { 107 LOG(ERROR) << "Failed to setup station mode interface from shill: " 108 << error->GetCode() << " " << error->GetMessage(); 109 return false; 110 } 111 return true; 112} 113#endif // __BRILLO__ 114 115void ShillDBusProxy::OnServiceAvailable(bool available) { 116 LOG(INFO) << __func__ << ": " << available; 117 // Nothing to be done if proxy service not available. 118 // The callback might invoke calls to the ObjectProxy, so defer the callback 119 // to event loop. 120 if (available && !service_appeared_callback_.is_null()) { 121 dispatcher_->PostTask(service_appeared_callback_); 122 } else if (!available && !service_vanished_callback_.is_null()) { 123 dispatcher_->PostTask(service_vanished_callback_); 124 } 125 service_available_ = available; 126} 127 128void ShillDBusProxy::OnServiceOwnerChanged(const string& old_owner, 129 const string& new_owner) { 130 LOG(INFO) << __func__ << " old: " << old_owner << " new: " << new_owner; 131 if (new_owner.empty()) { 132 OnServiceAvailable(false); 133 } else { 134 OnServiceAvailable(true); 135 } 136} 137 138} // namespace apmanager 139