Replace GLib timeouts with base::{OneShotTimer,RepeatingTimer}.

BUG=chromium:350336
TEST=Tested the following:
1. Build and run unit tests.
2. Run network_WiMaxPresent and network_WiMaxSmoke.
3. Verify that WiMAX manager stops scanning for a WiMAX module after
   about 15s on a DUT without a WiMAX module.
4. Test adjusting network scan and status update interval via:

    dbus-send --system --dest=org.chromium.WiMaxManager \
        /org/chromium/WiMaxManager/Device/wm0 \
        org.freedesktop.DBus.Properties.Set \
        string:org.chromium.WiMaxManager.Device \
        string:NetworkScanInterval \
        variant:uint32:5

    dbus-send --system --dest=org.chromium.WiMaxManager \
        /org/chromium/WiMaxManager/Device/wm0 \
        org.freedesktop.DBus.Properties.Set \
        string:org.chromium.WiMaxManager.Device \
        string:StatusUpdateInterval \
        variant:uint32:5

Change-Id: I7e42c3857ba1ce78afb638790c08b25ec6a3b2fa
Reviewed-on: https://chromium-review.googlesource.com/189211
Tested-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Ben Chan <benchan@chromium.org>
diff --git a/gdm_device.cc b/gdm_device.cc
index 58eb9d8..4e13b03 100644
--- a/gdm_device.cc
+++ b/gdm_device.cc
@@ -38,6 +38,7 @@
 // Default time interval, in seconds, between status updates when the device
 // is connecting to a network.
 const int kStatusUpdateIntervalDuringConnectInSeconds = 1;
+const int kShortDelayInSeconds = 1;
 
 const char kRealmTag[] = "@${realm}";
 
@@ -91,60 +92,6 @@
   return (value && value[0]) ? "<***>" : "";
 }
 
-gboolean OnInitialNetworkScan(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<GdmDevice *>(data)->InitialScanNetworks();
-
-  // Return FALSE as this is a one-shot update.
-  return FALSE;
-}
-
-gboolean OnNetworkScan(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<GdmDevice *>(data)->ScanNetworks();
-
-  // Return TRUE to keep calling this function repeatedly.
-  return TRUE;
-}
-
-gboolean OnStatusUpdate(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<GdmDevice *>(data)->UpdateStatus();
-
-  // Return TRUE to keep calling this function repeatedly.
-  return TRUE;
-}
-
-gboolean OnDeferredStatusUpdate(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<GdmDevice *>(data)->dbus_adaptor()->UpdateStatus();
-
-  // Return FALSE as this is a one-shot update.
-  return FALSE;
-}
-
-gboolean OnConnectTimeout(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<GdmDevice *>(data)->CancelConnectOnTimeout();
-
-  // Return FALSE as this is a one-shot update.
-  return FALSE;
-}
-
-gboolean OnDeferredRestoreStatusUpdateInterval(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<GdmDevice *>(data)->RestoreStatusUpdateInterval();
-
-  // Return FALSE as this is a one-shot update.
-  return FALSE;
-}
-
 }  // namespace
 
 GdmDevice::GdmDevice(Manager *manager, uint8 index, const string &name,
@@ -153,11 +100,6 @@
       driver_(driver),
       open_(false),
       connection_progress_(WIMAX_API_DEVICE_CONNECTION_PROGRESS_Ranging),
-      connect_timeout_id_(0),
-      initial_network_scan_timeout_id_(0),
-      network_scan_timeout_id_(0),
-      status_update_timeout_id_(0),
-      restore_status_update_interval_timeout_id_(0),
       restore_status_update_interval_(false),
       current_network_identifier_(Network::kInvalidIdentifier) {
 }
@@ -225,28 +167,28 @@
   }
 
   // Schedule an initial network scan shortly after the device is enabled.
-  if (initial_network_scan_timeout_id_ != 0) {
-    g_source_remove(initial_network_scan_timeout_id_);
-  }
-  initial_network_scan_timeout_id_ = g_timeout_add_seconds(
-      kInitialNetworkScanIntervalInSeconds, OnInitialNetworkScan, this);
+  initial_network_scan_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(kInitialNetworkScanIntervalInSeconds),
+      this,
+      &GdmDevice::OnNetworkScan);
 
   // Set OnNetworkScan() to be called repeatedly at |network_scan_interval_|
   // intervals to scan and update the list of networks via ScanNetworks().
   //
   // TODO(benchan): Refactor common functionalities like periodic network scan
   // to the Device base class.
-  if (network_scan_timeout_id_ != 0) {
-    g_source_remove(network_scan_timeout_id_);
-  }
-  network_scan_timeout_id_ =
-      g_timeout_add_seconds(network_scan_interval(), OnNetworkScan, this);
+  network_scan_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(network_scan_interval()),
+      this,
+      &GdmDevice::OnNetworkScan);
 
-  if (status_update_timeout_id_ != 0) {
-    g_source_remove(status_update_timeout_id_);
-  }
-  status_update_timeout_id_ =
-      g_timeout_add_seconds(status_update_interval(), OnStatusUpdate, this);
+  status_update_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(status_update_interval()),
+      this,
+      &GdmDevice::OnStatusUpdate);
 
   if (!driver_->GetDeviceStatus(this)) {
     LOG(ERROR) << "Failed to get status of device '" << name() << "'";
@@ -261,30 +203,19 @@
 
   ClearCurrentConnectionProfile();
 
-  CancelRestoreStatusUpdateIntervalTimeout();
+  restore_status_update_interval_timer_.Stop();
   RestoreStatusUpdateInterval();
 
   // Cancel any pending connect timeout.
-  if (connect_timeout_id_ != 0) {
-    g_source_remove(connect_timeout_id_);
-    connect_timeout_id_ = 0;
-  }
+  connect_timeout_timer_.Stop();
 
-  // Cancel the periodic calls to OnNetworkScan().
-  if (initial_network_scan_timeout_id_ != 0) {
-    g_source_remove(initial_network_scan_timeout_id_);
-    initial_network_scan_timeout_id_ = 0;
-  }
-  if (network_scan_timeout_id_ != 0) {
-    g_source_remove(network_scan_timeout_id_);
-    network_scan_timeout_id_ = 0;
-  }
+  // Cancel any scheduled network scan.
+  initial_network_scan_timer_.Stop();
+  network_scan_timer_.Stop();
 
-  // Cancel the periodic calls to OnStatusUpdate().
-  if (status_update_timeout_id_ != 0) {
-    g_source_remove(status_update_timeout_id_);
-    status_update_timeout_id_ = 0;
-  }
+  // Cancel any scheduled status update.
+  dbus_adaptor_status_update_timer_.Stop();
+  status_update_timer_.Stop();
 
   NetworkMap *networks = mutable_networks();
   if (!networks->empty()) {
@@ -304,11 +235,6 @@
   return true;
 }
 
-bool GdmDevice::InitialScanNetworks() {
-  initial_network_scan_timeout_id_ = 0;
-  return ScanNetworks();
-}
-
 bool GdmDevice::ScanNetworks() {
   if (!Open())
     return false;
@@ -351,6 +277,10 @@
   return true;
 }
 
+void GdmDevice::OnNetworkScan() {
+  ScanNetworks();
+}
+
 bool GdmDevice::UpdateStatus() {
   if (!driver_->GetDeviceStatus(this)) {
     LOG(ERROR) << "Failed to get status of device '" << name() << "'";
@@ -359,16 +289,16 @@
 
   // Cancel the timeout for connect and restore status update interval
   // if the device is no longer in the 'connecting' state.
-  if (connect_timeout_id_ != 0 && status() != kDeviceStatusConnecting) {
+  if (connect_timeout_timer_.IsRunning() &&
+      status() != kDeviceStatusConnecting) {
     LOG(INFO) << "Disable connect timeout.";
-    g_source_remove(connect_timeout_id_);
-    connect_timeout_id_ = 0;
+    connect_timeout_timer_.Stop();
 
-    CancelRestoreStatusUpdateIntervalTimeout();
-    if (restore_status_update_interval_) {
-      restore_status_update_interval_timeout_id_ =
-          g_timeout_add_seconds(1, OnDeferredRestoreStatusUpdateInterval, this);
-    }
+    restore_status_update_interval_timer_.Start(
+        FROM_HERE,
+        base::TimeDelta::FromSeconds(kShortDelayInSeconds),
+        this,
+        &GdmDevice::RestoreStatusUpdateInterval);
   }
 
   if (!driver_->GetDeviceRFInfo(this)) {
@@ -378,13 +308,23 @@
   return true;
 }
 
+void GdmDevice::OnStatusUpdate() {
+  UpdateStatus();
+}
+
+void GdmDevice::OnDBusAdaptorStatusUpdate() {
+  dbus_adaptor()->UpdateStatus();
+}
+
 void GdmDevice::UpdateNetworkScanInterval(uint32 network_scan_interval) {
-  if (network_scan_timeout_id_ != 0) {
+  if (network_scan_timer_.IsRunning()) {
     LOG(INFO) << "Update network scan interval to " << network_scan_interval
               << "s.";
-    g_source_remove(network_scan_timeout_id_);
-    network_scan_timeout_id_ =
-        g_timeout_add_seconds(network_scan_interval, OnNetworkScan, this);
+    network_scan_timer_.Start(
+        FROM_HERE,
+        base::TimeDelta::FromSeconds(network_scan_interval),
+        this,
+        &GdmDevice::OnNetworkScan);
 
     if (!driver_->SetScanInterval(this, network_scan_interval)) {
       LOG(WARNING) << "Failed to set internal network scan by SDK.";
@@ -393,12 +333,14 @@
 }
 
 void GdmDevice::UpdateStatusUpdateInterval(uint32 status_update_interval) {
-  if (status_update_timeout_id_ != 0) {
+  if (status_update_timer_.IsRunning()) {
     LOG(INFO) << "Update status update interval to " << status_update_interval
               << "s.";
-    g_source_remove(status_update_timeout_id_);
-    status_update_timeout_id_ =
-        g_timeout_add_seconds(status_update_interval, OnStatusUpdate, this);
+    status_update_timer_.Start(
+        FROM_HERE,
+        base::TimeDelta::FromSeconds(status_update_interval),
+        this,
+        &GdmDevice::OnStatusUpdate);
   }
 }
 
@@ -408,7 +350,6 @@
 
   UpdateStatusUpdateInterval(status_update_interval());
   restore_status_update_interval_ = false;
-  restore_status_update_interval_timeout_id_ = 0;
 
   // Restarts the network scan timeout source to be aligned with the status
   // update timeout source, which helps increase the idle time of the device
@@ -445,7 +386,11 @@
       // The device status may remain unchanged, schedule a deferred call to
       // DeviceDBusAdaptor::UpdateStatus() to explicitly notify the connection
       // manager about the current device status.
-      g_timeout_add_seconds(1, OnDeferredStatusUpdate, this);
+      dbus_adaptor_status_update_timer_.Start(
+          FROM_HERE,
+          base::TimeDelta::FromSeconds(kShortDelayInSeconds),
+          this,
+          &GdmDevice::OnDBusAdaptorStatusUpdate);
       return true;
     }
 
@@ -488,7 +433,7 @@
     return false;
   }
 
-  CancelRestoreStatusUpdateIntervalTimeout();
+  restore_status_update_interval_timer_.Stop();
   UpdateStatusUpdateInterval(kStatusUpdateIntervalDuringConnectInSeconds);
   restore_status_update_interval_ = true;
 
@@ -497,8 +442,11 @@
 
   // Schedule a timeout to abort the connection attempt in case the device
   // is stuck at the 'connecting' state.
-  connect_timeout_id_ =
-      g_timeout_add_seconds(kConnectTimeoutInSeconds, OnConnectTimeout, this);
+  connect_timeout_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(kConnectTimeoutInSeconds),
+      this,
+      &GdmDevice::CancelConnectOnTimeout);
 
   if (!driver_->GetDeviceStatus(this)) {
     LOG(ERROR) << "Failed to get status of device '" << name() << "'";
@@ -518,7 +466,7 @@
 
   ClearCurrentConnectionProfile();
 
-  CancelRestoreStatusUpdateIntervalTimeout();
+  restore_status_update_interval_timer_.Stop();
   RestoreStatusUpdateInterval();
 
   if (!driver_->GetDeviceStatus(this)) {
@@ -530,17 +478,9 @@
 
 void GdmDevice::CancelConnectOnTimeout() {
   LOG(WARNING) << "Timed out connecting to the network.";
-  connect_timeout_id_ = 0;
   Disconnect();
 }
 
-void GdmDevice::CancelRestoreStatusUpdateIntervalTimeout() {
-  if (restore_status_update_interval_timeout_id_ != 0) {
-    g_source_remove(restore_status_update_interval_timeout_id_);
-    restore_status_update_interval_timeout_id_ = 0;
-  }
-}
-
 void GdmDevice::ClearCurrentConnectionProfile() {
   current_network_identifier_ = Network::kInvalidIdentifier;
   current_user_identity_.clear();
diff --git a/gdm_device.h b/gdm_device.h
index ed43efe..fde0ebc 100644
--- a/gdm_device.h
+++ b/gdm_device.h
@@ -9,12 +9,11 @@
 #include <gct/gctapi.h>
 }  // extern "C"
 
-#include <glib.h>
-
 #include <string>
 
 #include <base/basictypes.h>
 #include <base/memory/weak_ptr.h>
+#include <base/timer.h>
 #include <gtest/gtest_prod.h>
 
 #include "wimax_manager/device.h"
@@ -32,12 +31,15 @@
 
   virtual bool Enable();
   virtual bool Disable();
-  bool InitialScanNetworks();
   virtual bool ScanNetworks();
   virtual bool UpdateStatus();
   virtual bool Connect(const Network &network,
                        const base::DictionaryValue &parameters);
   virtual bool Disconnect();
+
+  void OnNetworkScan();
+  void OnStatusUpdate();
+  void OnDBusAdaptorStatusUpdate();
   void CancelConnectOnTimeout();
   void RestoreStatusUpdateInterval();
 
@@ -56,7 +58,6 @@
 
   bool Open();
   bool Close();
-  void CancelRestoreStatusUpdateIntervalTimeout();
   void ClearCurrentConnectionProfile();
 
   static bool ConstructEAPParameters(
@@ -74,11 +75,12 @@
   base::WeakPtr<GdmDriver> driver_;
   bool open_;
   WIMAX_API_CONNECTION_PROGRESS_INFO connection_progress_;
-  guint connect_timeout_id_;
-  guint initial_network_scan_timeout_id_;
-  guint network_scan_timeout_id_;
-  guint status_update_timeout_id_;
-  guint restore_status_update_interval_timeout_id_;
+  base::OneShotTimer<GdmDevice> connect_timeout_timer_;
+  base::OneShotTimer<GdmDevice> initial_network_scan_timer_;
+  base::RepeatingTimer<GdmDevice> network_scan_timer_;
+  base::RepeatingTimer<GdmDevice> status_update_timer_;
+  base::OneShotTimer<GdmDevice> dbus_adaptor_status_update_timer_;
+  base::OneShotTimer<GdmDevice> restore_status_update_interval_timer_;
   bool restore_status_update_interval_;
   Network::Identifier current_network_identifier_;
   std::string current_user_identity_;
diff --git a/manager.cc b/manager.cc
index f943766..76f2218 100644
--- a/manager.cc
+++ b/manager.cc
@@ -31,21 +31,11 @@
 const int kDeviceScanDelayAfterResumeInSeconds = 3;
 const char kDefaultConfigFile[] = "/usr/share/wimax-manager/default.conf";
 
-gboolean OnDeviceScanNeeded(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<Manager *>(data)->ScanDevices();
-  // ScanDevices decides if a rescan is needed later, so return FALSE
-  // to prevent this function from being called repeatedly.
-  return FALSE;
-}
-
 }  // namespace
 
 Manager::Manager(EventDispatcher *dispatcher)
     : dispatcher_(dispatcher),
       num_device_scans_(0),
-      device_scan_timeout_id_(0),
       dbus_service_(this) {
 }
 
@@ -103,7 +93,7 @@
 }
 
 bool Manager::ScanDevices() {
-  device_scan_timeout_id_ = 0;
+  device_scan_timer_.Stop();
 
   if (!devices_.empty())
     return true;
@@ -125,18 +115,22 @@
   // indefinitely, stop the device scan after a number of attempts.
   if (++num_device_scans_ < kMaxNumberOfDeviceScans) {
     VLOG(1) << "No WiMAX devices detected. Rescan later.";
-    device_scan_timeout_id_ = g_timeout_add_seconds(
-        kDefaultDeviceScanIntervalInSeconds, OnDeviceScanNeeded, this);
+    device_scan_timer_.Start(
+        FROM_HERE,
+        base::TimeDelta::FromSeconds(kDefaultDeviceScanIntervalInSeconds),
+        this,
+        &Manager::OnDeviceScan);
   }
   return true;
 }
 
+void Manager::OnDeviceScan() {
+  ScanDevices();
+}
+
 void Manager::CancelDeviceScan() {
   // Cancel any pending device scan.
-  if (device_scan_timeout_id_ != 0) {
-    g_source_remove(device_scan_timeout_id_);
-    device_scan_timeout_id_ = 0;
-  }
+  device_scan_timer_.Stop();
   num_device_scans_ = 0;
 }
 
@@ -149,8 +143,11 @@
 void Manager::Resume() {
   // After resuming from suspend, the old device may not have been cleaned up.
   // Delay the device scan to avoid getting the old device.
-  g_timeout_add_seconds(kDeviceScanDelayAfterResumeInSeconds,
-                        OnDeviceScanNeeded, this);
+  device_scan_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(kDeviceScanDelayAfterResumeInSeconds),
+      this,
+      &Manager::OnDeviceScan);
 }
 
 bool Manager::LoadConfig(const base::FilePath &file_path) {
diff --git a/manager.h b/manager.h
index 59c4584..08464c9 100644
--- a/manager.h
+++ b/manager.h
@@ -5,14 +5,13 @@
 #ifndef WIMAX_MANAGER_MANAGER_H_
 #define WIMAX_MANAGER_MANAGER_H_
 
-#include <glib.h>
-
 #include <vector>
 
 #include <base/basictypes.h>
 #include <base/file_path.h>
 #include <base/memory/scoped_ptr.h>
 #include <base/memory/scoped_vector.h>
+#include <base/timer.h>
 #include <gtest/gtest_prod.h>
 
 #include "wimax_manager/dbus_adaptable.h"
@@ -36,6 +35,7 @@
   bool Initialize();
   bool Finalize();
   bool ScanDevices();
+  void OnDeviceScan();
   void CancelDeviceScan();
 
   void Suspend();
@@ -64,7 +64,7 @@
   ScopedVector<Device> devices_;
 
   int num_device_scans_;
-  guint device_scan_timeout_id_;
+  base::OneShotTimer<Manager> device_scan_timer_;
   DBusService dbus_service_;
 
   DISALLOW_COPY_AND_ASSIGN(Manager);
diff --git a/power_manager.cc b/power_manager.cc
index ba0cf54..945c853 100644
--- a/power_manager.cc
+++ b/power_manager.cc
@@ -25,14 +25,6 @@
 const char kPowerStateOn[] = "on";
 const char kSuspendDelayDescription[] = "wimax-manager";
 
-gboolean OnSuspendTimedOut(gpointer data) {
-  CHECK(data);
-
-  reinterpret_cast<PowerManager *>(data)->ResumeOnSuspendTimedOut();
-
-  return FALSE;
-}
-
 // Serializes |protobuf| to |out| and returns true on success.
 bool SerializeProtocolBuffer(const google::protobuf::MessageLite &protobuf,
                              vector<uint8> *out) {
@@ -66,7 +58,6 @@
     : suspend_delay_registered_(false),
       suspend_delay_id_(0),
       suspended_(false),
-      suspend_timeout_id_(0),
       wimax_manager_(wimax_manager) {
   CHECK(wimax_manager_);
 }
@@ -84,14 +75,13 @@
 }
 
 void PowerManager::Finalize() {
-  CancelSuspendTimeout();
+  suspend_timeout_timer_.Stop();
   UnregisterSuspendDelay();
 }
 
 void PowerManager::ResumeOnSuspendTimedOut() {
   LOG(WARNING) << "Timed out waiting for power state change signal from "
                << "power manager. Assume suspend is canceled.";
-  suspend_timeout_id_ = 0;
   OnPowerStateChanged(kPowerStateOn);
 }
 
@@ -167,8 +157,11 @@
   // If the power manager does not emit a PowerStateChanged "mem" signal within
   // |kSuspendTimeoutInSeconds|, assume suspend is canceled. Schedule a callback
   // to resume.
-  suspend_timeout_id_ = g_timeout_add_seconds(
-      kSuspendTimeoutInSeconds, OnSuspendTimedOut, this);
+  suspend_timeout_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(kSuspendTimeoutInSeconds),
+      this,
+      &PowerManager::ResumeOnSuspendTimedOut);
 }
 
 void PowerManager::OnPowerStateChanged(const string &new_power_state) {
@@ -176,7 +169,7 @@
 
   // Cancel any pending suspend timeout regardless of the new power state
   // to avoid resuming unexpectedly.
-  CancelSuspendTimeout();
+  suspend_timeout_timer_.Stop();
 
   if (new_power_state == kPowerStateMem) {
     suspended_ = true;
@@ -189,13 +182,6 @@
   }
 }
 
-void PowerManager::CancelSuspendTimeout() {
-  if (suspend_timeout_id_) {
-    g_source_remove(suspend_timeout_id_);
-    suspend_timeout_id_ = 0;
-  }
-}
-
 void PowerManager::SendHandleSuspendReadiness(int suspend_id) {
   LOG(INFO) << "Calling HandleSuspendReadiness (" << suspend_id << ").";
   power_manager::SuspendReadinessInfo proto;
diff --git a/power_manager.h b/power_manager.h
index 37cd543..d05ea2a 100644
--- a/power_manager.h
+++ b/power_manager.h
@@ -5,12 +5,10 @@
 #ifndef WIMAX_MANAGER_POWER_MANAGER_H_
 #define WIMAX_MANAGER_POWER_MANAGER_H_
 
-#include <glib.h>
-
 #include <string>
 
 #include <base/basictypes.h>
-#include <base/time.h>
+#include <base/timer.h>
 
 #include "wimax_manager/dbus_proxiable.h"
 
@@ -48,8 +46,6 @@
   void OnPowerStateChanged(const std::string &new_power_state);
 
  private:
-  void CancelSuspendTimeout();
-
   // Calls the power manager's HandleSuspendReadiness method to report readiness
   // for suspend attempt |suspend_id|.
   void SendHandleSuspendReadiness(int suspend_id);
@@ -62,7 +58,7 @@
   int suspend_delay_id_;
 
   bool suspended_;
-  guint suspend_timeout_id_;
+  base::OneShotTimer<PowerManager> suspend_timeout_timer_;
   Manager *wimax_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(PowerManager);