shill: cellular: Disconnect service on suspend.

Also, suppress auto-connect as soon as the SuspendDelay signal is
received. Schedule a timeout to detect failed or interrupted suspend
and re-enable auto-connect.

BUG=chromium-os:30587,chromium-os:33412
TEST=unit tests, tested on device through inspecting logs

Change-Id: If40f8217e4d9b222a698532054287ae9b4fcb4d6
Reviewed-on: https://gerrit.chromium.org/gerrit/34342
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/hook_table_unittest.cc b/hook_table_unittest.cc
index 74fc621..ca815d0 100644
--- a/hook_table_unittest.cc
+++ b/hook_table_unittest.cc
@@ -38,6 +38,10 @@
   HookTableTest()
       : hook_table_(&event_dispatcher_) {}
 
+  base::Callback<void(const Error &)> *GetDoneCallback() {
+    return &hook_table_.done_cb_;
+  }
+
   EventDispatcher event_dispatcher_;
   HookTable hook_table_;
 };
@@ -101,8 +105,9 @@
 
   // Cause the event dispatcher to exit after kTimeout + 1 ms.
   event_dispatcher_.PostDelayedTask(MessageLoop::QuitClosure(),
-                                    kTimeout * + 1);
+                                    kTimeout + 1);
   event_dispatcher_.DispatchForever();
+  EXPECT_TRUE(GetDoneCallback()->is_null());
 }
 
 TEST_F(HookTableTest, MultipleActionsAllSucceed) {
@@ -196,6 +201,14 @@
   hook_table_.Remove(kName);
 }
 
+TEST_F(HookTableTest, IsEmpty) {
+  EXPECT_TRUE(hook_table_.IsEmpty());
+  hook_table_.Add(kName, Closure());
+  EXPECT_FALSE(hook_table_.IsEmpty());
+  hook_table_.Remove(kName);
+  EXPECT_TRUE(hook_table_.IsEmpty());
+}
+
 class SomeClass : public base::RefCounted<SomeClass> {
  public:
   SomeClass() {}