device_status_collector.h revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_STATUS_COLLECTOR_H_
6#define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_STATUS_COLLECTOR_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/callback_forward.h"
12#include "base/compiler_specific.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/weak_ptr.h"
15#include "base/time/time.h"
16#include "base/timer/timer.h"
17#include "chrome/browser/chromeos/version_loader.h"
18#include "chrome/browser/idle.h"
19#include "chrome/browser/policy/cloud/cloud_policy_client.h"
20#include "chrome/common/cancelable_task_tracker.h"
21#include "content/public/browser/geolocation_provider.h"
22#include "content/public/browser/notification_observer.h"
23#include "content/public/common/geoposition.h"
24
25namespace chromeos {
26class CrosSettings;
27namespace system {
28class StatisticsProvider;
29}
30}
31
32namespace content {
33class NotificationDetails;
34class NotificationSource;
35}
36
37namespace enterprise_management {
38class DeviceStatusReportRequest;
39}
40
41class PrefService;
42class PrefRegistrySimple;
43
44namespace policy {
45
46// Collects and summarizes the status of an enterprised-managed ChromeOS device.
47class DeviceStatusCollector : public CloudPolicyClient::StatusProvider,
48                              public content::NotificationObserver {
49 public:
50  // TODO(bartfab): Remove this once crbug.com/125931 is addressed and a proper
51  // way to mock geolocation exists.
52  typedef base::Callback<void(
53      const content::GeolocationProvider::LocationUpdateCallback& callback)>
54          LocationUpdateRequester;
55
56  DeviceStatusCollector(
57      PrefService* local_state,
58      chromeos::system::StatisticsProvider* provider,
59      LocationUpdateRequester* location_update_requester);
60  virtual ~DeviceStatusCollector();
61
62  void GetStatus(enterprise_management::DeviceStatusReportRequest* request);
63
64  // CloudPolicyClient::StatusProvider:
65  virtual bool GetDeviceStatus(
66      enterprise_management::DeviceStatusReportRequest* status) OVERRIDE;
67  virtual bool GetSessionStatus(
68      enterprise_management::SessionStatusReportRequest* status) OVERRIDE;
69  virtual void OnSubmittedSuccessfully() OVERRIDE;
70
71  static void RegisterPrefs(PrefRegistrySimple* registry);
72
73  // How often, in seconds, to poll to see if the user is idle.
74  static const unsigned int kIdlePollIntervalSeconds = 30;
75
76 protected:
77  // Check whether the user has been idle for a certain period of time.
78  virtual void CheckIdleState();
79
80  // Used instead of base::Time::Now(), to make testing possible.
81  virtual base::Time GetCurrentTime();
82
83  // Callback which receives the results of the idle state check.
84  void IdleStateCallback(IdleState state);
85
86  // The number of days in the past to store device activity.
87  // This is kept in case device status uploads fail for a number of days.
88  unsigned int max_stored_past_activity_days_;
89
90  // The number of days in the future to store device activity.
91  // When changing the system time and/or timezones, it's possible to record
92  // activity time that is slightly in the future.
93  unsigned int max_stored_future_activity_days_;
94
95 private:
96  // A helper class to manage receiving geolocation notifications on the IO
97  // thread.
98  class Context : public base::RefCountedThreadSafe<Context> {
99   public:
100    Context();
101
102    void GetLocationUpdate(
103        const content::GeolocationProvider::LocationUpdateCallback& callback);
104
105   private:
106    friend class base::RefCountedThreadSafe<Context>;
107
108    ~Context();
109
110    void GetLocationUpdateInternal();
111    void OnLocationUpdate(const content::Geoposition& geoposition);
112    void CallCollector(const content::Geoposition& geoposition);
113
114    // The callback which this class registers with
115    // content::GeolocationProvider.
116    content::GeolocationProvider::LocationUpdateCallback our_callback_;
117
118    // The callback passed in to GetLocationUpdate.
119    content::GeolocationProvider::LocationUpdateCallback owner_callback_;
120  };
121
122  // Prevents the local store of activity periods from growing too large by
123  // removing entries that are outside the reporting window.
124  void PruneStoredActivityPeriods(base::Time base_time);
125
126  // Trims the store activity periods to only retain data within the
127  // [|min_day_key|, |max_day_key|). The record for |min_day_key| will be
128  // adjusted by subtracting |min_day_trim_duration|.
129  void TrimStoredActivityPeriods(int64 min_day_key,
130                                 int min_day_trim_duration,
131                                 int64 max_day_key);
132
133  void AddActivePeriod(base::Time start, base::Time end);
134
135  // Callbacks from chromeos::VersionLoader.
136  void OnOSVersion(const std::string& version);
137  void OnOSFirmware(const std::string& version);
138
139  // Helpers for the various portions of the status.
140  void GetActivityTimes(
141      enterprise_management::DeviceStatusReportRequest* request);
142  void GetVersionInfo(
143      enterprise_management::DeviceStatusReportRequest* request);
144  void GetBootMode(
145      enterprise_management::DeviceStatusReportRequest* request);
146  void GetLocation(
147      enterprise_management::DeviceStatusReportRequest* request);
148
149  // Update the cached values of the reporting settings.
150  void UpdateReportingSettings();
151
152  // content::NotificationObserver interface.
153  virtual void Observe(
154      int type,
155      const content::NotificationSource& source,
156      const content::NotificationDetails& details) OVERRIDE;
157
158  void ScheduleGeolocationUpdateRequest();
159
160  // content::GeolocationUpdateCallback implementation.
161  void ReceiveGeolocationUpdate(const content::Geoposition&);
162
163  // How often to poll to see if the user is idle.
164  int poll_interval_seconds_;
165
166  PrefService* local_state_;
167
168  // The last time an idle state check was performed.
169  base::Time last_idle_check_;
170
171  // The maximum key that went into the last report generated by
172  // GetDeviceStatus(), and the duration for it. This is used to trim the
173  // stored data in OnSubmittedSuccessfully(). Trimming is delayed so
174  // unsuccessful uploads don't result in dropped data.
175  int64 last_reported_day_;
176  int duration_for_last_reported_day_;
177
178  // Whether a geolocation update is currently in progress.
179  bool geolocation_update_in_progress_;
180
181  base::RepeatingTimer<DeviceStatusCollector> idle_poll_timer_;
182  base::OneShotTimer<DeviceStatusCollector> geolocation_update_timer_;
183
184  chromeos::VersionLoader version_loader_;
185  CancelableTaskTracker tracker_;
186
187  std::string os_version_;
188  std::string firmware_version_;
189
190  content::Geoposition position_;
191
192  chromeos::system::StatisticsProvider* statistics_provider_;
193
194  chromeos::CrosSettings* cros_settings_;
195
196  base::WeakPtrFactory<DeviceStatusCollector> weak_factory_;
197
198  // TODO(bartfab): Remove this once crbug.com/125931 is addressed and a proper
199  // way to mock geolocation exists.
200  LocationUpdateRequester location_update_requester_;
201
202  // Cached values of the reporting settings from the device policy.
203  bool report_version_info_;
204  bool report_activity_times_;
205  bool report_boot_mode_;
206  bool report_location_;
207
208  scoped_refptr<Context> context_;
209
210  DISALLOW_COPY_AND_ASSIGN(DeviceStatusCollector);
211};
212
213}  // namespace policy
214
215#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_STATUS_COLLECTOR_H_
216