shill: reduce some copy-paste in dbus proxies

When making asynchronous D-Bus calls, we have to take
care not to leak Callback objects. This code occurs
in many places, but differs only in types.

Factor this code out into a template, to remove code
duplication.

CQ-DEPEND=CL:195761
BUG=chromium:365390
TEST=unit tests

Change-Id: Ica63045a00b9bbd70b3e12cb0939f0d7f1af0e1d
Reviewed-on: https://chromium-review.googlesource.com/195762
Tested-by: mukesh agrawal <quiche@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Queue: mukesh agrawal <quiche@chromium.org>
diff --git a/mm1_modem_proxy.cc b/mm1_modem_proxy.cc
index d9772bd..017781d 100644
--- a/mm1_modem_proxy.cc
+++ b/mm1_modem_proxy.cc
@@ -7,6 +7,7 @@
 #include <ModemManager/ModemManager.h>
 
 #include "shill/cellular_error.h"
+#include "shill/dbus_async_call_helper.h"
 #include "shill/logging.h"
 
 using std::string;
@@ -14,6 +15,15 @@
 namespace shill {
 namespace mm1 {
 
+template<typename TraceMsgT, typename CallT, typename CallbackT,
+         typename... ArgTypes>
+void ModemProxy::BeginCall(
+    const TraceMsgT &trace_msg, const CallT &call, CallbackT &callback,
+    Error *error, int timeout, ArgTypes... rest) {
+  BeginAsyncDBusCall(trace_msg, proxy_, call, callback, error,
+                     &CellularError::FromMM1DBusError, timeout, rest...);
+}
+
 ModemProxy::ModemProxy(DBus::Connection *connection,
                        const string &path,
                        const string &service)
@@ -31,15 +41,8 @@
                         const ResultCallback &callback,
                         int timeout) {
   SLOG(Modem, 2) << __func__ << "(" << enable << ", " << timeout << ")";
-  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.Enable(enable, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::EnableAsync, callback, error, timeout,
+            enable);
 }
 
 void ModemProxy::CreateBearer(
@@ -47,74 +50,38 @@
     Error *error,
     const DBusPathCallback &callback,
     int timeout) {
-  scoped_ptr<DBusPathCallback> cb(new DBusPathCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.CreateBearer(properties, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::CreateBearerAsync, callback, error, timeout,
+            properties);
 }
 
 void ModemProxy::DeleteBearer(const ::DBus::Path &bearer,
                               Error *error,
                               const ResultCallback &callback,
                               int timeout) {
-  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.DeleteBearer(bearer, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::DeleteBearerAsync, callback, error, timeout,
+            bearer);
 }
 
 void ModemProxy::Reset(Error *error,
                        const ResultCallback &callback,
                        int timeout) {
-  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.Reset(cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::ResetAsync, callback, error, timeout);
 }
 
 void ModemProxy::FactoryReset(const std::string &code,
                               Error *error,
                               const ResultCallback &callback,
                               int timeout) {
-  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.FactoryReset(code, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::FactoryResetAsync, callback, error, timeout,
+            code);
 }
 
 void ModemProxy::SetCurrentCapabilities(const uint32_t &capabilities,
                                         Error *error,
                                         const ResultCallback &callback,
                                         int timeout) {
-  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.SetCurrentCapabilities(capabilities, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::SetCurrentCapabilitiesAsync, callback, error,
+            timeout, capabilities);
 }
 
 void ModemProxy::SetCurrentModes(
@@ -122,30 +89,16 @@
     Error *error,
     const ResultCallback &callback,
     int timeout) {
-  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.SetCurrentModes(modes, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::SetCurrentModesAsync, callback, error, timeout,
+            modes);
 }
 
 void ModemProxy::SetCurrentBands(const std::vector<uint32_t> &bands,
                                  Error *error,
                                  const ResultCallback &callback,
                                  int timeout) {
-  scoped_ptr<ResultCallback> cb(new ResultCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.SetCurrentBands(bands, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::SetCurrentBandsAsync, callback, error, timeout,
+            bands);
 }
 
 void ModemProxy::Command(const std::string &cmd,
@@ -153,30 +106,16 @@
                          Error *error,
                          const StringCallback &callback,
                          int timeout) {
-  scoped_ptr<StringCallback> cb(new StringCallback(callback));
-  try {
-    SLOG(DBus, 2) << __func__;
-    proxy_.Command(cmd, user_timeout, cb.get(), timeout);
-    cb.release();
-  } catch (const DBus::Error &e) {
-    if (error)
-      CellularError::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::CommandAsync, callback, error, timeout,
+            cmd, user_timeout);
 }
 
 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::FromMM1DBusError(e, error);
-  }
+  BeginCall(__func__, &Proxy::SetPowerStateAsync, callback, error, timeout,
+            power_state);
 }
 
 ModemProxy::Proxy::Proxy(DBus::Connection *connection,