Listen for SuspendDone D-Bus signal from powerd.

Use SuspendDone instead of the old, poorly-defined
PowerStateChanged signal.

BUG=chromium:359619
TEST=manual: tail /var/log/net.log while running
     powerd_dbus_suspend and and waking the system; verify
     that suspend and resume are reported

Change-Id: I2eb27d2e4a53497116e8610f5ab77813d3a313d8
Reviewed-on: https://chromium-review.googlesource.com/194950
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Queue: Daniel Erat <derat@chromium.org>
Tested-by: Daniel Erat <derat@chromium.org>
diff --git a/dbus_bindings/org.chromium.PowerManager.xml b/dbus_bindings/org.chromium.PowerManager.xml
index 541aee7..f5a4b74 100644
--- a/dbus_bindings/org.chromium.PowerManager.xml
+++ b/dbus_bindings/org.chromium.PowerManager.xml
@@ -19,8 +19,8 @@
     <signal name="SuspendImminent">
       <arg name="serialized_proto" type="ay"/>
     </signal>
-    <signal name="PowerStateChanged">
-      <arg name="new_power_state" type="s" />
+    <signal name="SuspendDone">
+      <arg name="serialized_proto" type="ay" />
     </signal>
   </interface>
 </node>
diff --git a/power_manager.cc b/power_manager.cc
index 945c853..5f2a0fc 100644
--- a/power_manager.cc
+++ b/power_manager.cc
@@ -21,8 +21,6 @@
 
 const uint32 kDefaultSuspendDelayInMilliSeconds = 5000;  // 5s
 const uint32 kSuspendTimeoutInSeconds = 15;  // 15s
-const char kPowerStateMem[] = "mem";
-const char kPowerStateOn[] = "on";
 const char kSuspendDelayDescription[] = "wimax-manager";
 
 // Serializes |protobuf| to |out| and returns true on success.
@@ -79,12 +77,6 @@
   UnregisterSuspendDelay();
 }
 
-void PowerManager::ResumeOnSuspendTimedOut() {
-  LOG(WARNING) << "Timed out waiting for power state change signal from "
-               << "power manager. Assume suspend is canceled.";
-  OnPowerStateChanged(kPowerStateOn);
-}
-
 void PowerManager::RegisterSuspendDelay(base::TimeDelta timeout,
                                         const string &description) {
   if (!dbus_proxy())
@@ -154,7 +146,7 @@
     suspended_ = true;
   }
   SendHandleSuspendReadiness(proto.suspend_id());
-  // If the power manager does not emit a PowerStateChanged "mem" signal within
+  // If the power manager does not emit a SuspendDone signal within
   // |kSuspendTimeoutInSeconds|, assume suspend is canceled. Schedule a callback
   // to resume.
   suspend_timeout_timer_.Start(
@@ -164,22 +156,15 @@
       &PowerManager::ResumeOnSuspendTimedOut);
 }
 
-void PowerManager::OnPowerStateChanged(const string &new_power_state) {
-  LOG(INFO) << "Power state changed to '" << new_power_state << "'.";
-
-  // Cancel any pending suspend timeout regardless of the new power state
-  // to avoid resuming unexpectedly.
-  suspend_timeout_timer_.Stop();
-
-  if (new_power_state == kPowerStateMem) {
-    suspended_ = true;
+void PowerManager::OnSuspendDone(const vector<uint8> &serialized_proto) {
+  power_manager::SuspendDone proto;
+  if (!DeserializeProtocolBuffer(serialized_proto, &proto)) {
+    LOG(ERROR) << "Failed to parse SuspendDone signal.";
     return;
   }
 
-  if (suspended_ && new_power_state == kPowerStateOn) {
-    wimax_manager_->Resume();
-    suspended_ = false;
-  }
+  LOG(INFO) << "Received SuspendDone (" << proto.suspend_id() << ").";
+  HandleResume();
 }
 
 void PowerManager::SendHandleSuspendReadiness(int suspend_id) {
@@ -198,4 +183,18 @@
   }
 }
 
+void PowerManager::ResumeOnSuspendTimedOut() {
+  LOG(WARNING) << "Timed out waiting for SuspendDone signal from "
+               << "power manager. Assuming suspend was canceled.";
+  HandleResume();
+}
+
+void PowerManager::HandleResume() {
+  suspend_timeout_timer_.Stop();
+  if (suspended_) {
+    wimax_manager_->Resume();
+    suspended_ = false;
+  }
+}
+
 }  // namespace wimax_manager
diff --git a/power_manager.h b/power_manager.h
index 56fdc9b..cd800c9 100644
--- a/power_manager.h
+++ b/power_manager.h
@@ -26,8 +26,6 @@
   void Initialize();
   void Finalize();
 
-  void ResumeOnSuspendTimedOut();
-
   // Synchronously registers a suspend delay with the power manager, assigning
   // the delay's ID to |suspend_delay_id_| and setting
   // |suspend_delay_registered_| to true on success.  |timeout| is the maximum
@@ -40,17 +38,28 @@
   // Unregisters |suspend_delay_id_|.
   void UnregisterSuspendDelay();
 
-  // Invoked when the power manager is about to suspend the system.  Prepares
-  // the manager for suspend and calls SendHandleSuspendReadiness().
+  // Invoked when the power manager is about to attempt to suspend the system.
+  // Prepares the manager for suspend and calls SendHandleSuspendReadiness().
   void OnSuspendImminent(const std::vector<uint8> &serialized_proto);
 
-  void OnPowerStateChanged(const std::string &new_power_state);
+  // Invoked when the power manager has completed a suspend attempt (possibly
+  // without actually suspending and resuming if the attempt was canceled by the
+  // user).
+  void OnSuspendDone(const std::vector<uint8> &serialized_proto);
 
  private:
   // Calls the power manager's HandleSuspendReadiness method to report readiness
   // for suspend attempt |suspend_id|.
   void SendHandleSuspendReadiness(int suspend_id);
 
+  // Invoked by |suspend_timeout_timer_| if the power manager doesn't emit a
+  // SuspendDone signal quickly enough after announcing a suspend attempt.
+  void ResumeOnSuspendTimedOut();
+
+  // Called by OnSuspendDone() and ResumeOnSuspendTimedOut() to handle the
+  // completion of a suspend attempt.
+  void HandleResume();
+
   // Is a suspend delay currently registered?
   bool suspend_delay_registered_;
 
diff --git a/power_manager_dbus_proxy.cc b/power_manager_dbus_proxy.cc
index 4d517de..bc266cf 100644
--- a/power_manager_dbus_proxy.cc
+++ b/power_manager_dbus_proxy.cc
@@ -33,8 +33,9 @@
   power_manager_->OnSuspendImminent(serialized_proto);
 }
 
-void PowerManagerDBusProxy::PowerStateChanged(const string &new_power_state) {
-  power_manager_->OnPowerStateChanged(new_power_state);
+void PowerManagerDBusProxy::SuspendDone(
+    const vector<uint8> &serialized_proto) {
+  power_manager_->OnSuspendDone(serialized_proto);
 }
 
 }  // namespace wimax_manager
diff --git a/power_manager_dbus_proxy.h b/power_manager_dbus_proxy.h
index bf82086..964c820 100644
--- a/power_manager_dbus_proxy.h
+++ b/power_manager_dbus_proxy.h
@@ -24,7 +24,7 @@
   virtual ~PowerManagerDBusProxy();
 
   virtual void SuspendImminent(const std::vector<uint8> &serialized_proto);
-  virtual void PowerStateChanged(const std::string &new_power_state);
+  virtual void SuspendDone(const std::vector<uint8> &serialized_proto);
 
  private:
   PowerManager *power_manager_;