shill: Implement Connect() and Disconnect() for CellularCapabilityUniversal

Refactor such that Cellular::Connect() passes down a callback that can
call On{Connected,Disconnected}{,Failed}(), rather than having
subclasses know about it. This requires overriding
CellularCapabilityClassic::Connect() in
CellularCapabilityGSM so that it can put its APN-handling callback on
the chain; this in turn requires exposing simple_proxy_ to that class.

TEST=Connect and disconnect from UI
BUG=None

Change-Id: I0b504e106ea6f880d40fa452149db34bc60b4f5b
Reviewed-on: https://gerrit.chromium.org/gerrit/20584
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
Commit-Ready: Nathan J. Williams <njw@chromium.org>
Tested-by: Nathan J. Williams <njw@chromium.org>
Reviewed-by: Eric Shienbrood <ers@chromium.org>
diff --git a/cellular_capability_universal.cc b/cellular_capability_universal.cc
index cd38d34..e8485d8 100644
--- a/cellular_capability_universal.cc
+++ b/cellular_capability_universal.cc
@@ -279,12 +279,20 @@
 void CellularCapabilityUniversal::Connect(const DBusPropertiesMap &properties,
                                           Error *error,
                                           const ResultCallback &callback) {
-  OnUnsupportedOperation(__func__, error);
+  VLOG(2) << __func__;
+  DBusPathCallback cb = Bind(&CellularCapabilityUniversal::OnConnectReply,
+                             weak_ptr_factory_.GetWeakPtr(),
+                             callback);
+  modem_simple_proxy_->Connect(properties, error, cb, kTimeoutConnect);
 }
 
 void CellularCapabilityUniversal::Disconnect(Error *error,
                                              const ResultCallback &callback) {
-  OnUnsupportedOperation(__func__, error);
+  VLOG(2) << __func__;
+  modem_simple_proxy_->Disconnect(bearer_path_,
+                                  error,
+                                  callback,
+                                  kTimeoutDefault);
 }
 
 void CellularCapabilityUniversal::Activate(const string &carrier,
@@ -376,7 +384,10 @@
 }
 
 void CellularCapabilityUniversal::OnConnectReply(const ResultCallback &callback,
-                                           const Error &error) {
+                                                 const DBus::Path &path,
+                                                 const Error &error) {
+  VLOG(2) << __func__ << "(" << error << ")";
+
   if (error.IsFailure()) {
     cellular()->service()->ClearLastGoodApn();
     // The APN that was just tried (and failed) is still at the
@@ -393,13 +404,12 @@
       Connect(props, &error, callback);
       return;
     }
-    cellular()->OnConnectFailed(error);
   } else {
     if (!apn_try_list_.empty()) {
       cellular()->service()->SetLastGoodApn(apn_try_list_.front());
       apn_try_list_.clear();
     }
-    cellular()->OnConnected();
+    bearer_path_ = path;
   }
 
   if (!callback.is_null())