shill: cellular: call SetPowerState after disabling modem.

Since ModemManager no longer powers down the modem when the modem is
disabled, CellularCapabilityUniversal now calls the new SetPowerState
method on org.freedesktop.ModemManager1.Modem to put the modem into a
low power state after disabling it.

In the event that the call to SetPowerState fails, the error is ignored
and the overall disable operation is treated as success.

BUG=chromium-os:38864
TEST=1. Build and run unit tests.
     2. Enable and disable cellular through the UI. On a modem that
        supports the explicit switch to a low-power state,
        ModemManager's PowerState property should be set to low after a
        successful disable.

Change-Id: I631d8df118ed6e300ec0b197ec87e744bd2502bd
Reviewed-on: https://gerrit.chromium.org/gerrit/43241
Reviewed-by: Thieu Le <thieule@chromium.org>
Commit-Queue: Arman Uguray <armansito@chromium.org>
Tested-by: Arman Uguray <armansito@chromium.org>
diff --git a/mm1_modem_proxy.cc b/mm1_modem_proxy.cc
index 7649487..58736d5 100644
--- a/mm1_modem_proxy.cc
+++ b/mm1_modem_proxy.cc
@@ -161,6 +161,21 @@
   }
 }
 
+void ModemProxy::SetPowerState(const uint32_t &power_state,
+                               Error *error,
+                               const ResultCallback &callback,
+                               int timeout) {
+  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
+  try {
+    SLOG(DBus, 2) << __func__;
+    proxy_.SetPowerState(power_state, cb.get(), timeout);
+    cb.release();
+  } catch (const DBus::Error &e) {
+    if (error)
+      CellularError::FromDBusError(e, error);
+  }
+}
+
 // Inherited properties from ModemProxyInterface.
 const ::DBus::Path ModemProxy::Sim() {
   SLOG(DBus, 2) << __func__;
@@ -378,6 +393,15 @@
     return std::vector<uint32_t>();  // Make the compiler happy.
   }
 }
+uint32_t ModemProxy::PowerState() {
+  SLOG(DBus, 2) << __func__;
+  try {
+    return proxy_.PowerState();
+  } catch (const DBus::Error &e) {
+    LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what();
+    return 0;  // Make the compiler happy.
+  }
+}
 
 ModemProxy::Proxy::Proxy(DBus::Connection *connection,
                          const std::string &path,
@@ -489,5 +513,14 @@
   callback->Run(error);
 }
 
+void ModemProxy::Proxy::SetPowerStateCallback(const ::DBus::Error &dberror,
+                                              void *data) {
+  SLOG(DBus, 2) << __func__;
+  scoped_ptr<ResultCallback> callback(reinterpret_cast<ResultCallback *>(data));
+  Error error;
+  CellularError::FromDBusError(dberror, &error);
+  callback->Run(error);
+}
+
 }  // namespace mm1
 }  // namespace shill