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