shill: Add support for device metrics.

Also add first device metrics, TimeToInitialize, which is the time
between when the kernel notifies shill about a link to when a Device
object is created for that link.

BUG=chromium-os:38086
TEST=New unit test and checking chrome://histograms for new metrics

Change-Id: If42081a42eb39b1782e0d7603e5d79116645ebad
Reviewed-on: https://gerrit.chromium.org/gerrit/41794
Reviewed-by: Thieu Le <thieule@chromium.org>
Tested-by: Thieu Le <thieule@chromium.org>
Commit-Queue: Thieu Le <thieule@chromium.org>
diff --git a/metrics.h b/metrics.h
index ec40c2e..1cad04a 100644
--- a/metrics.h
+++ b/metrics.h
@@ -176,6 +176,10 @@
   static const char kMetricTimeToDropSeconds[];
   static const int kMetricTimeToDropSecondsMax;
   static const int kMetricTimeToDropSecondsMin;
+  static const char kMetricTimeToInitializeMilliseconds[];
+  static const int kMetricTimeToInitializeMillisecondsMin;
+  static const int kMetricTimeToInitializeMillisecondsMax;
+  static const int kMetricTimeToInitializeMillisecondsNumBuckets;
   static const char kMetricTimeToJoinMilliseconds[];
   static const char kMetricTimeToOnlineMilliseconds[];
   static const char kMetricTimeToPortalMilliseconds[];
@@ -305,6 +309,18 @@
   void Notify80211Disconnect(WiFiDisconnectByWhom by_whom,
                              IEEE_80211::WiFiReasonCode reason);
 
+  // Registers a device with this object so the device can use the timers to
+  // track state transition metrics.
+  void RegisterDevice(int interface_index,
+                      Technology::Identifier technology);
+
+  // Deregisters the device from this class.  All state transition timers
+  // will be removed.
+  void DeregisterDevice(int interface_index);
+
+  // Notifies this object that a device has been initialized.
+  void NotifyDeviceInitialized(int interface_index);
+
   // Sends linear histogram data to UMA.
   virtual bool SendEnumToUMA(const std::string &name, int sample, int max);
 
@@ -343,6 +359,13 @@
   typedef std::map<const Service *, std::tr1::shared_ptr<ServiceMetrics> >
       ServiceMetricsLookupMap;
 
+  struct DeviceMetrics {
+    DeviceMetrics() {}
+    scoped_ptr<chromeos_metrics::TimerReporter> initialization_timer;
+  };
+  typedef std::map<const int, std::tr1::shared_ptr<DeviceMetrics> >
+      DeviceMetricsLookupMap;
+
   static const uint16 kWiFiBandwidth5MHz;
   static const uint16 kWiFiBandwidth20MHz;
   static const uint16 kWiFiFrequency2412;
@@ -392,6 +415,7 @@
   scoped_ptr<chromeos_metrics::Timer> time_resume_to_ready_timer_;
   scoped_ptr<chromeos_metrics::Timer> time_termination_actions_timer;
   bool collect_bootstats_;
+  DeviceMetricsLookupMap devices_metrics_;
 
   DISALLOW_COPY_AND_ASSIGN(Metrics);
 };