shill: Disconnect modem before attempting to activate

When we're asked to activate a modem, assume that Chrome knows what it
is doing and disconnect the modem first.  This lets Chrome not have
complicate the activation process by waiting for an asyncronous
disconnect first.

BUG=chromium-os:36301
TEST=Modems still activate as before.  This shouldn't be surprising
because Chrome is still doing lots of work to disconnect a service
before trying to activate.  The real magic will happen when we take
those parts out of Chrome.

Change-Id: Ic41fa7f4ec759d6ec5c650708792ab6aa083dde5
Reviewed-on: https://gerrit.chromium.org/gerrit/38060
Commit-Ready: Christopher Wiley <wiley@chromium.org>
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Tested-by: Christopher Wiley <wiley@chromium.org>
diff --git a/cellular.cc b/cellular.cc
index ace05cd..1e70021 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -467,7 +467,8 @@
     service_->SetFailure(Service::kFailureUnknown);
 }
 
-void Cellular::Disconnect(Error *error) {
+void Cellular::DisconnectWithCallback(const ResultCallback &callback,
+                                      Error *error) {
   SLOG(Cellular, 2) << __func__;
   if (state_ != kStateConnected && state_ != kStateLinked) {
     Error::PopulateAndLog(
@@ -475,13 +476,17 @@
     return;
   }
   ResultCallback cb = Bind(&Cellular::OnDisconnectReply,
-                           weak_ptr_factory_.GetWeakPtr());
+                           weak_ptr_factory_.GetWeakPtr(),
+                           callback);
   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) {
+void Cellular::Disconnect(Error *error) {
+  DisconnectWithCallback(ResultCallback(), error);
+}
+
+void Cellular::OnDisconnectReply(const ResultCallback &callback,
+                                 const Error &error) {
   SLOG(Cellular, 2) << __func__ << "(" << error << ")";
   if (error.IsSuccess())
     OnDisconnected();
@@ -489,6 +494,9 @@
     OnDisconnectFailed();
   manager()->TerminationActionComplete(FriendlyName());
   manager()->RemoveTerminationAction(FriendlyName());
+  if (!callback.is_null()) {
+    callback.Run(error);
+  }
 }
 
 void Cellular::OnDisconnected() {