shill: Remove suspend timeout action from PowerManager client object.

shill currently posts a timeout when it receives a SuspendImminent message from
power manager. If it doesn't receive a matching SuspendDone within the given
time, it fakes a SuspendDone message.

The original reason for this timeout was that powerd did not guarantee the
SuspendDone message, in case the suspend request was canceled. This is no longer
the case.

This behaviour is a problem because we may incorrectly resume shill due to time
spent in dark resume. This CL removes the timeout.

BUG=chromium:407786
TEST=(1) Run shill unittests.
     (2) Verify suspend-resume re-enables wifi.
     (3) Verify shill resumes after a canceled suspend. To simulate:
         $ powerd_dbus_suspend -delay 2 -wakeup_timeout 15 &
         $ sleep 2.5
         $ killall -9 powerd

Change-Id: I2a127f20e90a193a5f1e1f2fdcbb8d3bb7237371
Reviewed-on: https://chromium-review.googlesource.com/214590
Tested-by: Prathmesh Prabhu <pprabhu@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Queue: Prathmesh Prabhu <pprabhu@chromium.org>
diff --git a/power_manager.cc b/power_manager.cc
index 1966aa5..67c620d 100644
--- a/power_manager.cc
+++ b/power_manager.cc
@@ -26,6 +26,7 @@
 namespace shill {
 
 // static
+const int PowerManager::kInvalidSuspendId = -1;
 const char PowerManager::kSuspendDelayDescription[] = "shill";
 const int PowerManager::kSuspendTimeoutMilliseconds = 15 * 1000;
 
@@ -81,25 +82,20 @@
   LOG(INFO) << __func__ << "(" << suspend_id << ")";
   current_suspend_id_ = suspend_id;
 
-  // Schedule a suspend timeout in case the suspend attempt failed or got
-  // interrupted, and there's no proper notification from the power manager.
-  suspend_timeout_.Reset(base::Bind(&PowerManager::OnSuspendTimeout,
-                         Unretained(this)));
-  dispatcher_->PostDelayedTask(suspend_timeout_.callback(),
-                               kSuspendTimeoutMilliseconds);
-
-
   // If we're already suspending, don't call the |suspend_imminent_callback_|
   // again.
   if (!suspending_) {
     // Change the power state to suspending as soon as this signal is received
     // so that the manager can suppress auto-connect, for example.
+    // Also, we must set this before running the callback below, because the
+    // callback may synchronously report suspend readiness.
     suspending_ = true;
     suspend_imminent_callback_.Run();
   }
 }
 
 void PowerManager::OnSuspendDone(int suspend_id) {
+  // NB: |suspend_id| could be -1. See OnPowerManagerVanished.
   LOG(INFO) << __func__ << "(" << suspend_id << ")";
   if (!suspending_) {
     LOG(WARNING) << "Recieved unexpected SuspendDone ("
@@ -107,16 +103,10 @@
     return;
   }
 
-  suspend_timeout_.Cancel();
   suspending_ = false;
   suspend_done_callback_.Run();
 }
 
-void PowerManager::OnSuspendTimeout() {
-  LOG(ERROR) << "Suspend timed out -- assuming power-on state.";
-  OnSuspendDone(current_suspend_id_);
-}
-
 void PowerManager::OnPowerManagerAppeared(const string &/*name*/,
                                           const string &/*owner*/) {
   LOG(INFO) << __func__;
@@ -129,6 +119,9 @@
 
 void PowerManager::OnPowerManagerVanished(const string &/*name*/) {
   LOG(INFO) << __func__;
+  // If powerd vanished during a suspend, we need to wake ourselves up.
+  if (suspending_)
+    OnSuspendDone(kInvalidSuspendId);
   suspend_delay_registered_ = false;
 }