shill: Reporting of device's connection status

Report device's connection status to UMA stats periodically. Possible status
are offline (not connected to an AP), connected (connected to an AP), and
online (connected to an AP with internet connectivity). When the device is
in online state, it will report both connected and online to UMA stats.

This data will allow us to determine the percentage of time when the device
have internet connectivity, also the percentage of time when the device is
connected to an AP but without internet connectivity.

While at it, update the old IsOnline function in manager.cc to IsConnected
to be more semantically correct, since that function return true if there is a
service that's in connected or above state. And Add a new IsOnline function
which will return true only if there is a service that's in online state.

BUG=chromium:392990
TEST=unit tests, manual
Manual Test:
1. Boot up a chrome device without any network connectivity.
2. Wait for 3 minutes, and browse to "chrome://histograms", veriyf
   there is a histogram for "Network.Shill.DeviceConnectionStatus"
   with a hit for bucket 0 (offline).
3. Connect the chrome device to an AP without internet connectivity.
4. Wait for 3 minutes, and browse to "chrome://histograms", verify
   there is a hit for bucket 1 (connected) for histogram
   "Network.Shill.DeviceConnectionStatus".
5. Connect the chrome device to an AP with internet connectivity.
6. Wait for 3 minutes, and browse to "chrome://histograms", verify
   there sia hit for bucket 1 (connected) and 2 (online) for
   histogram "Network.Shill.DeviceConnectionStatus".

Change-Id: I1a949b17398214d745ca1d5a37e35202e087181a
Reviewed-on: https://chromium-review.googlesource.com/207960
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Peter Qiu <zqiu@chromium.org>
Tested-by: Peter Qiu <zqiu@chromium.org>
diff --git a/manager.h b/manager.h
index 4f22939..b5aaf44 100644
--- a/manager.h
+++ b/manager.h
@@ -251,6 +251,9 @@
 
   // Returns true if at least one connection exists, and false if there's no
   // connected service.
+  virtual bool IsConnected() const;
+  // Returns true if at least one connection exists that have Internet
+  // connectivity, and false if there's no such service.
   virtual bool IsOnline() const;
   std::string CalculateState(Error *error);
 
@@ -427,6 +430,7 @@
   FRIEND_TEST(ManagerTest, SortServicesWithConnection);
   FRIEND_TEST(ManagerTest, StartupPortalList);
   FRIEND_TEST(ManagerTest, IsWifiIdle);
+  FRIEND_TEST(ManagerTest, ConnectionStatusCheck);
 
   static const char kErrorNoDevice[];
   static const char kErrorTypeRequired[];
@@ -436,6 +440,7 @@
   static const int kTerminationActionsTimeoutMilliseconds;
 
   static const char kPowerManagerKey[];
+  static const int kConnectionStatusCheckIntervalMilliseconds;
 
   void AutoConnect();
   std::vector<std::string> AvailableTechnologies(Error *error);
@@ -501,6 +506,7 @@
 
   void SortServices();
   void SortServicesTask();
+  void ConnectionStatusCheckTask();
   bool MatchProfileWithService(const ServiceRefPtr &service);
 
   // Sets the profile of |service| to |profile|, without notifying its
@@ -613,6 +619,9 @@
 
   base::CancelableClosure sort_services_task_;
 
+  // Task for periodically checking connection status.
+  base::CancelableClosure connection_status_check_task_;
+
   // TODO(petkov): Currently this handles both terminate and suspend
   // actions. Rename all relevant identifiers to capture this.
   HookTable termination_actions_;