shill: implement Service.Disconnect (for WiFiService only)

BUG=chromium-os:23774,chromium-os:23662
TEST=new unit tests, some autotests

autotests run:
- PASS network_WiFiSecMat.031CheckHidden_WPA
- PASS network_WiFiSecMat.032CheckHidden_RSN

Change-Id: I0c2dc8c9888caca793f0dfe5a55c0df2a4b10c79
Reviewed-on: https://gerrit.chromium.org/gerrit/12498
Commit-Ready: mukesh agrawal <quiche@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: mukesh agrawal <quiche@chromium.org>
diff --git a/wifi_service.cc b/wifi_service.cc
index 3874a06..38c0e0b 100644
--- a/wifi_service.cc
+++ b/wifi_service.cc
@@ -110,15 +110,18 @@
 
 void WiFiService::Connect(Error */*error*/) {
   LOG(INFO) << __func__;
-
-  // NB(quiche) defer handling, since dbus-c++ does not permit us to
-  // send an outbound request while processing an inbound one.
+  // Defer handling, since dbus-c++ does not permit us to send an
+  // outbound request while processing an inbound one.
   dispatcher()->PostTask(
       task_factory_.NewRunnableMethod(&WiFiService::ConnectTask));
 }
 
-void WiFiService::Disconnect() {
-  // TODO(quiche) RemoveNetwork from supplicant
+void WiFiService::Disconnect(Error */*error*/) {
+  LOG(INFO) << __func__;
+  // Defer handling, since dbus-c++ does not permit us to send an
+  // outbound request while processing an inbound one.
+  dispatcher()->PostTask(
+      task_factory_.NewRunnableMethod(&WiFiService::DisconnectTask));
 }
 
 bool WiFiService::TechnologyIs(const Technology::Identifier type) const {
@@ -301,6 +304,10 @@
   wifi_->ConnectTo(this, params);
 }
 
+void WiFiService::DisconnectTask() {
+  wifi_->DisconnectFrom(this);
+}
+
 string WiFiService::GetDeviceRpcId(Error */*error*/) {
   return wifi_->GetRpcIdentifier();
 }