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.cc b/cellular.cc
index 2115e3e..94ad672 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -336,8 +336,21 @@
   DBusPropertiesMap properties;
   capability_->SetupConnectProperties(&properties);
   service_->SetState(Service::kStateAssociating);
-  // TODO(ers): use null callback until Connect is made fully asynchronous
-  capability_->Connect(properties, error, ResultCallback());
+  // TODO(njw): Should a weak pointer be used here instead?
+  // Would require something like a WeakPtrFactory on the class,
+  // and the Classic and Universal subclasses already have one.
+  ResultCallback cb = Bind(&Cellular::OnConnectReply, this);
+  capability_->Connect(properties, error, cb);
+}
+
+// Note that there's no ResultCallback argument to this,
+// since Connect() isn't yet passed one.
+void Cellular::OnConnectReply(const Error &error) {
+  VLOG(2) << __func__ << "(" << error << ")";
+  if (error.IsSuccess())
+    OnConnected();
+  else
+    OnConnectFailed(error);
 }
 
 void Cellular::OnConnected() {
@@ -362,8 +375,19 @@
         error, Error::kNotConnected, "Not connected; request ignored.");
     return;
   }
-  // TODO(ers): use null callback until Disconnect is made fully asynchronous
-  capability_->Disconnect(error, ResultCallback());
+  // TODO(njw): See Connect() about possible weak ptr for 'this'.
+  ResultCallback cb = Bind(&Cellular::OnDisconnectReply, this);
+  capability_->Disconnect(error, cb);
+}
+
+// Note that there's no ResultCallback argument to this,
+// since Disconnect() isn't yet passed one.
+void Cellular::OnDisconnectReply(const Error &error) {
+  VLOG(2) << __func__ << "(" << error << ")";
+  if (error.IsSuccess())
+    OnDisconnected();
+  else
+    OnDisconnectFailed();
 }
 
 void Cellular::OnDisconnected() {