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 "shill/dbus/chromeos_modem_manager_proxy.h"
18
19 #include "shill/cellular/modem_manager.h"
20 #include "shill/event_dispatcher.h"
21 #include "shill/logging.h"
22
23 using std::string;
24 using std::vector;
25
26 namespace shill {
27
28 namespace Logging {
29 static auto kModuleLogScope = ScopeLogger::kDBus;
ObjectID(const dbus::ObjectPath * p)30 static string ObjectID(const dbus::ObjectPath* p) { return p->value(); }
31 } // namespace Logging
32
ChromeosModemManagerProxy(EventDispatcher * dispatcher,const scoped_refptr<dbus::Bus> & bus,ModemManagerClassic * manager,const std::string & path,const std::string & service,const base::Closure & service_appeared_callback,const base::Closure & service_vanished_callback)33 ChromeosModemManagerProxy::ChromeosModemManagerProxy(
34 EventDispatcher* dispatcher,
35 const scoped_refptr<dbus::Bus>& bus,
36 ModemManagerClassic* manager,
37 const std::string& path,
38 const std::string& service,
39 const base::Closure& service_appeared_callback,
40 const base::Closure& service_vanished_callback)
41 : proxy_(
42 new org::freedesktop::ModemManagerProxy(
43 bus, service, dbus::ObjectPath(path))),
44 dispatcher_(dispatcher),
45 manager_(manager),
46 service_appeared_callback_(service_appeared_callback),
47 service_vanished_callback_(service_vanished_callback),
48 service_available_(false) {
49 // Register signal handlers.
50 proxy_->RegisterDeviceAddedSignalHandler(
51 base::Bind(&ChromeosModemManagerProxy::DeviceAdded,
52 weak_factory_.GetWeakPtr()),
53 base::Bind(&ChromeosModemManagerProxy::OnSignalConnected,
54 weak_factory_.GetWeakPtr()));
55 proxy_->RegisterDeviceRemovedSignalHandler(
56 base::Bind(&ChromeosModemManagerProxy::DeviceRemoved,
57 weak_factory_.GetWeakPtr()),
58 base::Bind(&ChromeosModemManagerProxy::OnSignalConnected,
59 weak_factory_.GetWeakPtr()));
60
61 // Monitor service owner changes. This callback lives for the lifetime of
62 // the ObjectProxy.
63 proxy_->GetObjectProxy()->SetNameOwnerChangedCallback(
64 base::Bind(&ChromeosModemManagerProxy::OnServiceOwnerChanged,
65 weak_factory_.GetWeakPtr()));
66
67 // One time callback when service becomes available.
68 proxy_->GetObjectProxy()->WaitForServiceToBeAvailable(
69 base::Bind(&ChromeosModemManagerProxy::OnServiceAvailable,
70 weak_factory_.GetWeakPtr()));
71 }
72
~ChromeosModemManagerProxy()73 ChromeosModemManagerProxy::~ChromeosModemManagerProxy() {}
74
EnumerateDevices()75 vector<string> ChromeosModemManagerProxy::EnumerateDevices() {
76 SLOG(&proxy_->GetObjectPath(), 2) << __func__;
77 if (!service_available_) {
78 LOG(ERROR) << "Service not available";
79 return vector<string>();
80 }
81
82 vector<dbus::ObjectPath> device_paths;
83 brillo::ErrorPtr error;
84 if (!proxy_->EnumerateDevices(&device_paths, &error)) {
85 LOG(ERROR) << "Failed to enumerate devices: " << error->GetCode()
86 << " " << error->GetMessage();
87 return vector<string>();
88 }
89 vector<string> device_rpcids;
90 KeyValueStore::ConvertPathsToRpcIdentifiers(device_paths, &device_rpcids);
91 return device_rpcids;
92 }
93
DeviceAdded(const dbus::ObjectPath & device)94 void ChromeosModemManagerProxy::DeviceAdded(const dbus::ObjectPath& device) {
95 SLOG(&proxy_->GetObjectPath(), 2) << __func__;
96 manager_->OnDeviceAdded(device.value());
97 }
98
DeviceRemoved(const dbus::ObjectPath & device)99 void ChromeosModemManagerProxy::DeviceRemoved(const dbus::ObjectPath& device) {
100 SLOG(&proxy_->GetObjectPath(), 2) << __func__;
101 manager_->OnDeviceRemoved(device.value());
102 }
103
OnServiceAvailable(bool available)104 void ChromeosModemManagerProxy::OnServiceAvailable(bool available) {
105 LOG(INFO) << __func__ << ": " << available;
106
107 // The callback might invoke calls to the ObjectProxy, so defer the callback
108 // to event loop.
109 if (available && !service_appeared_callback_.is_null()) {
110 dispatcher_->PostTask(service_appeared_callback_);
111 } else if (!available && !service_vanished_callback_.is_null()) {
112 dispatcher_->PostTask(service_vanished_callback_);
113 }
114 service_available_ = available;
115 }
116
OnServiceOwnerChanged(const string & old_owner,const string & new_owner)117 void ChromeosModemManagerProxy::OnServiceOwnerChanged(
118 const string& old_owner, const string& new_owner) {
119 LOG(INFO) << __func__ << " old: " << old_owner << " new: " << new_owner;
120 if (new_owner.empty()) {
121 OnServiceAvailable(false);
122 } else {
123 OnServiceAvailable(true);
124 }
125 }
126
OnSignalConnected(const string & interface_name,const string & signal_name,bool success)127 void ChromeosModemManagerProxy::OnSignalConnected(
128 const string& interface_name, const string& signal_name, bool success) {
129 SLOG(&proxy_->GetObjectPath(), 2) << __func__
130 << "interface: " << interface_name
131 << " signal: " << signal_name << "success: " << success;
132 if (!success) {
133 LOG(ERROR) << "Failed to connect signal " << signal_name
134 << " to interface " << interface_name;
135 }
136 }
137
138 } // namespace shill
139