components: Introduce AlarmTimer class and use it for GCM heartbeat

This adds the AlarmTimer class to components, which is capable of waking
up the system from suspend on platforms that support this operation
(currently only Chrome OS with linux version 3.11 or higher).  On all
other platforms, the AlarmTimer behaves exactly the same as a regular
Timer.

BUG=crosbug.com/p/32272

Review URL: https://codereview.chromium.org/641943002

Cr-Commit-Position: refs/heads/master@{#301175}
diff --git a/components/gcm_driver/DEPS b/components/gcm_driver/DEPS
index e7bf510..cad5eddf 100644
--- a/components/gcm_driver/DEPS
+++ b/components/gcm_driver/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   "+components/os_crypt",
   "+components/pref_registry",
+  "+components/timers",  # Only used for Chrome OS builds.
   # TODO(johnme): Fix this layering violation.
   "!content/public/android/java",
   "+google_apis/gaia",
diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc
index fa968a0..db4504b 100644
--- a/components/gcm_driver/gcm_client_impl.cc
+++ b/components/gcm_driver/gcm_client_impl.cc
@@ -16,6 +16,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/time/default_clock.h"
 #include "components/gcm_driver/gcm_backoff_policy.h"
+#include "components/timers/alarm_timer.h"
 #include "google_apis/gcm/base/encryptor.h"
 #include "google_apis/gcm/base/mcs_message.h"
 #include "google_apis/gcm/base/mcs_util.h"
@@ -192,12 +193,17 @@
     ConnectionFactory* connection_factory,
     GCMStore* gcm_store,
     GCMStatsRecorder* recorder) {
-  return make_scoped_ptr<MCSClient>(
-      new MCSClient(version,
-                    clock,
-                    connection_factory,
-                    gcm_store,
-                    recorder));
+#if defined(OS_CHROMEOS)
+  return scoped_ptr<MCSClient>(new MCSClient(
+      version, clock, connection_factory, gcm_store, recorder,
+      make_scoped_ptr(new timers::AlarmTimer(true, /* retain user task */
+                                             false /* non-repeating */))));
+#else
+  return scoped_ptr<MCSClient>(new MCSClient(
+      version, clock, connection_factory, gcm_store, recorder,
+      make_scoped_ptr(new base::Timer(true, /* retain user task */
+                                      false /* non-repeating */))));
+#endif  // defined(OS_CHROMEOS)
 }
 
 scoped_ptr<ConnectionFactory> GCMInternalsBuilder::BuildConnectionFactory(
diff --git a/components/gcm_driver/gcm_client_impl_unittest.cc b/components/gcm_driver/gcm_client_impl_unittest.cc
index 270641b..8257f1cf 100644
--- a/components/gcm_driver/gcm_client_impl_unittest.cc
+++ b/components/gcm_driver/gcm_client_impl_unittest.cc
@@ -6,10 +6,12 @@
 
 #include "base/command_line.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/clock.h"
+#include "base/timer/timer.h"
 #include "google_apis/gcm/base/fake_encryptor.h"
 #include "google_apis/gcm/base/mcs_message.h"
 #include "google_apis/gcm/base/mcs_util.h"
@@ -114,7 +116,8 @@
                              ConnectionFactory* connection_factory,
                              GCMStore* gcm_store,
                              GCMStatsRecorder* recorder)
-    : MCSClient("", clock, connection_factory, gcm_store, recorder),
+    : MCSClient("", clock, connection_factory, gcm_store, recorder,
+                make_scoped_ptr(new base::Timer(true, false))),
       last_android_id_(0u),
       last_security_token_(0u),
       last_message_tag_(kNumProtoTypes) {