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_STATUS_COLLECTOR_DEVICE_STATUS_COLLECTOR_H_
6 #define CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_DEVICE_STATUS_COLLECTOR_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
16 #include "base/callback_forward.h"
17 #include "base/callback_list.h"
18 #include "base/compiler_specific.h"
19 #include "base/containers/circular_deque.h"
20 #include "base/time/default_clock.h"
21 #include "base/macros.h"
22 #include "base/memory/ref_counted.h"
23 #include "base/memory/weak_ptr.h"
24 #include "base/sequenced_task_runner.h"
25 #include "base/task/cancelable_task_tracker.h"
26 #include "base/time/time.h"
27 #include "base/timer/timer.h"
28 #include "chrome/browser/chromeos/policy/status_collector/app_info_generator.h"
29 #include "chrome/browser/chromeos/policy/status_collector/status_collector.h"
30 #include "chrome/browser/chromeos/settings/cros_settings.h"
31 #include "chromeos/dbus/cryptohome/cryptohome_client.h"
32 #include "chromeos/dbus/power/power_manager_client.h"
33 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
34 #include "components/policy/proto/device_management_backend.pb.h"
35 #include "components/prefs/pref_member.h"
36 #include "ui/base/idle/idle.h"
37 
38 namespace chromeos {
39 class CrosSettings;
40 namespace system {
41 class StatisticsProvider;
42 }
43 }  // namespace chromeos
44 
45 namespace cryptohome {
46 struct TpmStatusInfo;
47 }
48 
49 namespace power_manager {
50 class PowerSupplyProperties;
51 }
52 
53 namespace user_manager {
54 class User;
55 }
56 
57 class PrefChangeRegistrar;
58 class PrefRegistrySimple;
59 class PrefService;
60 class Profile;
61 
62 namespace policy {
63 
64 class EnterpriseActivityStorage;
65 struct DeviceLocalAccount;
66 class DeviceStatusCollectorState;
67 
68 // Enum used to define which data the CrosHealthdDataFetcher should collect.
69 enum class CrosHealthdCollectionMode { kFull, kBattery };
70 
71 // Holds TPM status info.  Cf. TpmStatusInfo in device_management_backend.proto.
72 struct TpmStatusInfo {
73   TpmStatusInfo();
74   TpmStatusInfo(const TpmStatusInfo&);
75   TpmStatusInfo(bool enabled,
76                 bool owned,
77                 bool initialized,
78                 bool attestation_prepared,
79                 bool attestation_enrolled,
80                 int32_t dictionary_attack_counter,
81                 int32_t dictionary_attack_threshold,
82                 bool dictionary_attack_lockout_in_effect,
83                 int32_t dictionary_attack_lockout_seconds_remaining,
84                 bool boot_lockbox_finalized);
85   ~TpmStatusInfo();
86 
87   bool enabled = false;
88   bool owned = false;
89   bool initialized = false;
90   bool attestation_prepared = false;
91   bool attestation_enrolled = false;
92   int32_t dictionary_attack_counter = 0;
93   int32_t dictionary_attack_threshold = 0;
94   bool dictionary_attack_lockout_in_effect = false;
95   int32_t dictionary_attack_lockout_seconds_remaining = 0;
96   bool boot_lockbox_finalized = false;
97 };
98 
99 // Sampled hardware measurement data for single time point.
100 class SampledData {
101  public:
102   SampledData();
103   ~SampledData();
104 
105   // Sampling timestamp.
106   base::Time timestamp;
107   // Battery samples for each battery.
108   std::map<std::string, enterprise_management::BatterySample> battery_samples;
109   // Thermal samples for each thermal point.
110   std::map<std::string, enterprise_management::ThermalSample> thermal_samples;
111   // CPU thermal samples.
112   std::map<std::string, enterprise_management::CPUTempInfo> cpu_samples;
113 
114   DISALLOW_COPY_AND_ASSIGN(SampledData);
115 };
116 
117 // Collects and summarizes the status of an enterprise-managed ChromeOS device.
118 class DeviceStatusCollector : public StatusCollector,
119                               public chromeos::PowerManagerClient::Observer {
120  public:
121   using VolumeInfoFetcher =
122       base::Callback<std::vector<enterprise_management::VolumeInfo>(
123           const std::vector<std::string>& mount_points)>;
124 
125   // Reads the first CPU line from /proc/stat. Returns an empty string if
126   // the cpu data could not be read. Broken out into a callback to enable
127   // mocking for tests.
128   //
129   // The format of this line from /proc/stat is:
130   //   cpu  user_time nice_time system_time idle_time
131   using CPUStatisticsFetcher = base::Callback<std::string(void)>;
132 
133   // Reads CPU temperatures from /sys/class/hwmon/hwmon*/temp*_input and
134   // appropriate labels from /sys/class/hwmon/hwmon*/temp*_label.
135   using CPUTempFetcher =
136       base::Callback<std::vector<enterprise_management::CPUTempInfo>()>;
137 
138   // Format of the function that asynchronously receives TpmStatusInfo.
139   using TpmStatusReceiver = base::OnceCallback<void(const TpmStatusInfo&)>;
140   // Gets the TpmStatusInfo and passes it to TpmStatusReceiver.
141   using TpmStatusFetcher = base::RepeatingCallback<void(TpmStatusReceiver)>;
142 
143   // Format of the function that asynchronously receives data from cros_healthd.
144   using CrosHealthdDataReceiver = base::OnceCallback<void(
145       chromeos::cros_healthd::mojom::TelemetryInfoPtr,
146       const base::circular_deque<std::unique_ptr<SampledData>>&)>;
147   // Gets the data from cros_healthd and passes it to CrosHealthdDataReceiver.
148   using CrosHealthdDataFetcher =
149       base::RepeatingCallback<void(CrosHealthdCollectionMode,
150                                    CrosHealthdDataReceiver)>;
151 
152   // Asynchronously receives the graphics status.
153   using GraphicsStatusReceiver =
154       base::OnceCallback<void(const enterprise_management::GraphicsStatus&)>;
155 
156   // Gets the display and graphics adapter information reported to the browser
157   // by the GPU process.
158   using GraphicsStatusFetcher =
159       base::RepeatingCallback<void(GraphicsStatusReceiver)>;
160 
161   // Format of the function that asynchronously receives CrashReportInfo.
162   using CrashReportInfoReceiver = base::OnceCallback<void(
163       const std::vector<enterprise_management::CrashReportInfo>&)>;
164 
165   // Gets the crash report information stored on the local device.
166   using CrashReportInfoFetcher =
167       base::RepeatingCallback<void(CrashReportInfoReceiver)>;
168 
169   // Reads EMMC usage lifetime from /var/log/storage_info.txt
170   using EMMCLifetimeFetcher =
171       base::RepeatingCallback<enterprise_management::DiskLifetimeEstimation(
172           void)>;
173   // Reads the stateful partition info from /home/.shadow
174   using StatefulPartitionInfoFetcher =
175       base::Callback<enterprise_management::StatefulPartitionInfo()>;
176 
177   // Constructor. Callers can inject their own *Fetcher callbacks, e.g. for unit
178   // testing. A null callback can be passed for any *Fetcher parameter, to use
179   // the default implementation. These callbacks are always executed on Blocking
180   // Pool. Caller is responsible for passing already initialized |pref_service|.
181   DeviceStatusCollector(
182       PrefService* pref_service,
183       chromeos::system::StatisticsProvider* provider,
184       const VolumeInfoFetcher& volume_info_fetcher,
185       const CPUStatisticsFetcher& cpu_statistics_fetcher,
186       const CPUTempFetcher& cpu_temp_fetcher,
187       const AndroidStatusFetcher& android_status_fetcher,
188       const TpmStatusFetcher& tpm_status_fetcher,
189       const EMMCLifetimeFetcher& emmc_lifetime_fetcher,
190       const StatefulPartitionInfoFetcher& stateful_partition_info_fetcher,
191       const CrosHealthdDataFetcher& cros_healthd_data_fetcher,
192       const GraphicsStatusFetcher& graphics_status_fetcher,
193       const CrashReportInfoFetcher& crash_report_info_fetcher,
194       base::Clock* clock = base::DefaultClock::GetInstance());
195 
196   // Constructor with default callbacks. These callbacks are always executed on
197   // Blocking Pool. Caller is responsible for passing already initialized
198   // |pref_service|.
199   DeviceStatusCollector(PrefService* pref_service,
200                         chromeos::system::StatisticsProvider* provider);
201 
202   ~DeviceStatusCollector() override;
203 
204   // StatusCollector:
205   void GetStatusAsync(const StatusCollectorCallback& response) override;
206   void OnSubmittedSuccessfully() override;
207   bool ShouldReportActivityTimes() const override;
208   bool ShouldReportNetworkInterfaces() const override;
209   bool ShouldReportUsers() const override;
210   bool ShouldReportHardwareStatus() const override;
211   bool ShouldReportCrashReportInfo() const override;
212   bool ShouldReportAppInfoAndActivity() const override;
213 
214   static void RegisterPrefs(PrefRegistrySimple* registry);
215 
GetAffiliatedSessionServiceForTesting()216   AffiliatedSessionService* GetAffiliatedSessionServiceForTesting() {
217     return &affiliated_session_service_;
218   }
219 
220   // How often to poll to see if the user is idle.
221   static constexpr base::TimeDelta kIdlePollInterval =
222       base::TimeDelta::FromSeconds(30);
223 
224   // The total number of hardware resource usage samples cached internally.
225   static const unsigned int kMaxResourceUsageSamples = 10;
226 
227  protected:
228   using PowerStatusCallback = base::OnceCallback<void(
229       const power_manager::PowerSupplyProperties& prop)>;
230 
231   // Check whether the user has been idle for a certain period of time.
232   virtual void CheckIdleState();
233 
234   // Handles the results of the idle state check.
235   void ProcessIdleState(ui::IdleState state);
236 
237   // Gets the version of the passed app. Virtual to allow mocking.
238   virtual std::string GetAppVersion(const std::string& app_id);
239 
240   // Samples the current hardware resource usage to be sent up with the
241   // next device status update.
242   void SampleResourceUsage();
243 
244   // power_manager::PowerManagerClient::Observer:
245   void PowerChanged(const power_manager::PowerSupplyProperties& prop) override;
246 
247  private:
248   // Callbacks used during sampling data collection, that allows to pass
249   // additional data using partial function application.
250   using SamplingProbeResultCallback =
251       base::OnceCallback<void(chromeos::cros_healthd::mojom::TelemetryInfoPtr)>;
252   using SamplingCallback = base::OnceCallback<void()>;
253 
254   // Clears the cached hardware resource usage.
255   void ClearCachedResourceUsage();
256 
257   // Callbacks from chromeos::VersionLoader.
258   void OnOSVersion(const std::string& version);
259   void OnOSFirmware(std::pair<const std::string&, const std::string&> version);
260   void OnTpmVersion(
261       const chromeos::CryptohomeClient::TpmVersionInfo& tpm_version_info);
262 
263   void GetDeviceStatus(scoped_refptr<DeviceStatusCollectorState> state);
264   void GetSessionStatus(scoped_refptr<DeviceStatusCollectorState> state);
265 
266   bool GetSessionStatusForUser(
267       scoped_refptr<DeviceStatusCollectorState> state,
268       enterprise_management::SessionStatusReportRequest* status,
269       const user_manager::User* user);
270   // Helpers for the various portions of DEVICE STATUS. Return true if they
271   // actually report any status. Functions that queue async queries take
272   // a |DeviceStatusCollectorState| instance.
273   bool GetActivityTimes(
274       enterprise_management::DeviceStatusReportRequest* status);
275   bool GetVersionInfo(enterprise_management::DeviceStatusReportRequest* status);
276   bool GetWriteProtectSwitch(
277       enterprise_management::DeviceStatusReportRequest* status);
278   bool GetNetworkInterfaces(
279       enterprise_management::DeviceStatusReportRequest* status);
280   bool GetUsers(enterprise_management::DeviceStatusReportRequest* status);
281   bool GetHardwareStatus(scoped_refptr<DeviceStatusCollectorState>
282                              state);  // Queues async queries!
283   bool GetOsUpdateStatus(
284       enterprise_management::DeviceStatusReportRequest* status);
285   bool GetRunningKioskApp(
286       enterprise_management::DeviceStatusReportRequest* status);
287   bool GetGraphicsStatus(scoped_refptr<DeviceStatusCollectorState>
288                              state);  // Queues async queries!
289   bool GetCrashReportInfo(scoped_refptr<DeviceStatusCollectorState>
290                               state);  // Queues async queries!
291 
292   // Helpers for the various portions of SESSION STATUS. Return true if they
293   // actually report any status. Functions that queue async queries take
294   // a |DeviceStatusCollectorState| instance.
295   bool GetKioskSessionStatus(
296       enterprise_management::SessionStatusReportRequest* status);
297   bool GetAndroidStatus(
298       enterprise_management::SessionStatusReportRequest* status,
299       const scoped_refptr<DeviceStatusCollectorState>&
300           state);  // Queues async queries!
301   bool GetCrostiniUsage(
302       enterprise_management::SessionStatusReportRequest* status,
303       Profile* profile);
304 
305   // Update the cached values of the reporting settings.
306   void UpdateReportingSettings();
307 
308   // Callback invoked to update our cpu usage information.
309   void ReceiveCPUStatistics(const std::string& statistics);
310 
311   // Callback for CrosHealthd that samples probe live data. |callback| will
312   // be called once all sampling is finished.
313   void SampleProbeData(std::unique_ptr<SampledData> sample,
314                        SamplingProbeResultCallback callback,
315                        chromeos::cros_healthd::mojom::TelemetryInfoPtr result);
316 
317   // Callback triggered from PowerManagedClient that samples battery discharge
318   // rate. |callback| will be called once all sampling is finished.
319   void SampleDischargeRate(std::unique_ptr<SampledData> sample,
320                            SamplingCallback callback,
321                            const power_manager::PowerSupplyProperties& prop);
322 
323   // Callback invoked to update our cpu temperature information.
324   void ReceiveCPUTemperature(std::unique_ptr<SampledData> sample,
325                              SamplingCallback callback,
326                              std::vector<enterprise_management::CPUTempInfo>);
327 
328   // Final sampling step that records data sample, invokes |callback|.
329   void AddDataSample(std::unique_ptr<SampledData> sample,
330                      SamplingCallback callback);
331 
332   // CrosHealthdDataReceiver interface implementation, fetches data from
333   // cros_healthd and passes it to |callback|. The data collected depends on the
334   // collection |mode|.
335   void FetchCrosHealthdData(CrosHealthdCollectionMode mode,
336                             CrosHealthdDataReceiver callback);
337 
338   // Callback for CrosHealthd that performs final sampling and
339   // actually invokes |callback|.
340   void OnProbeDataFetched(
341       CrosHealthdDataReceiver callback,
342       chromeos::cros_healthd::mojom::TelemetryInfoPtr reply);
343 
344   // Returns true if data (e.g. CPU info, power status, etc.) should be fetched
345   // from cros_healthd.
346   bool ShouldFetchCrosHealthdData() const;
347 
348   // Callback invoked when reporting users pref is changed.
349   void ReportingUsersChanged();
350 
351   // Returns user's email if it should be included in the activity reports or
352   // empty string otherwise. Primary user is used as unique identifier of a
353   // single session, even for multi-user sessions.
354   std::string GetUserForActivityReporting() const;
355 
356   // Returns whether users' email addresses should be included in activity
357   // reports.
358   bool IncludeEmailsInActivityReports() const;
359 
360   // Pref service that is mainly used to store activity periods for reporting.
361   PrefService* const pref_service_;
362 
363   // The last time an idle state check was performed.
364   base::Time last_idle_check_;
365 
366   // End timestamp of the latest activity that went into the last report
367   // generated by GetStatusAsync(). Used to trim the stored data in
368   // OnSubmittedSuccessfully(). Trimming is delayed so unsuccessful uploads
369   // don't result in dropped data.
370   int64_t last_reported_end_timestamp_ = 0;
371 
372   // Time when GetStatusAsync() is called. Used to close open app
373   // activity just prior to reporting so the report can include the most
374   // up-to-date activity.
375   base::Time last_requested_;
376 
377   base::RepeatingTimer idle_poll_timer_;
378   base::RepeatingTimer resource_usage_sampling_timer_;
379 
380   std::string os_version_;
381   std::string firmware_version_;
382   std::string firmware_fetch_error_;
383   chromeos::CryptohomeClient::TpmVersionInfo tpm_version_info_;
384 
385   struct ResourceUsage {
386     // Sample of percentage-of-CPU-used.
387     int cpu_usage_percent;
388 
389     // Amount of free RAM (measures raw memory used by processes, not internal
390     // memory waiting to be reclaimed by GC).
391     int64_t bytes_of_ram_free;
392 
393     // Sampling timestamp.
394     base::Time timestamp;
395   };
396 
397   // Samples of resource usage (contains multiple samples taken
398   // periodically every kHardwareStatusSampleIntervalSeconds).
399   base::circular_deque<ResourceUsage> resource_usage_;
400 
401   // Samples of probe data (contains multiple samples taken
402   // periodically every kHardwareStatusSampleIntervalSeconds)
403   base::circular_deque<std::unique_ptr<SampledData>> sampled_data_;
404 
405   // Callback invoked to fetch information about the mounted disk volumes.
406   VolumeInfoFetcher volume_info_fetcher_;
407 
408   // Callback invoked to fetch information about cpu usage.
409   CPUStatisticsFetcher cpu_statistics_fetcher_;
410 
411   // Callback invoked to fetch information about cpu temperature.
412   CPUTempFetcher cpu_temp_fetcher_;
413 
414   AndroidStatusFetcher android_status_fetcher_;
415 
416   TpmStatusFetcher tpm_status_fetcher_;
417 
418   EMMCLifetimeFetcher emmc_lifetime_fetcher_;
419 
420   StatefulPartitionInfoFetcher stateful_partition_info_fetcher_;
421 
422   CrosHealthdDataFetcher cros_healthd_data_fetcher_;
423 
424   GraphicsStatusFetcher graphics_status_fetcher_;
425 
426   CrashReportInfoFetcher crash_report_info_fetcher_;
427 
428   PowerStatusCallback power_status_callback_;
429 
430   // Power manager client. Used to listen to power changed events.
431   chromeos::PowerManagerClient* const power_manager_;
432 
433   // The most recent CPU readings.
434   uint64_t last_cpu_active_ = 0;
435   uint64_t last_cpu_idle_ = 0;
436 
437   // Cached values of the reporting settings. These are enterprise only. There
438   // are common ones in StatusCollector interface.
439   bool report_network_interfaces_ = false;
440   bool report_users_ = false;
441   bool report_hardware_status_ = false;
442   bool report_kiosk_session_status_ = false;
443   bool report_os_update_status_ = false;
444   bool report_running_kiosk_app_ = false;
445   bool report_power_status_ = false;
446   bool report_storage_status_ = false;
447   bool report_board_status_ = false;
448   bool report_cpu_info_ = false;
449   bool report_graphics_status_ = false;
450   bool report_timezone_info_ = false;
451   bool report_memory_info_ = false;
452   bool report_backlight_info_ = false;
453   bool report_crash_report_info_ = false;
454   bool report_bluetooth_info_ = false;
455   bool report_fan_info_ = false;
456   bool report_vpd_info_ = false;
457   bool report_app_info_ = false;
458   bool report_system_info_ = false;
459   bool stat_reporting_pref_ = false;
460 
461   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
462       activity_times_subscription_;
463   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
464       network_interfaces_subscription_;
465   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
466       users_subscription_;
467   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
468       hardware_status_subscription_;
469   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
470       session_status_subscription_;
471   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
472       os_update_status_subscription_;
473   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
474       running_kiosk_app_subscription_;
475   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
476       power_status_subscription_;
477   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
478       storage_status_subscription_;
479   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
480       board_status_subscription_;
481   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
482       cpu_info_subscription_;
483   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
484       graphics_status_subscription_;
485   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
486       timezone_info_subscription_;
487   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
488       memory_info_subscription_;
489   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
490       backlight_info_subscription_;
491   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
492       crash_report_info_subscription_;
493   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
494       bluetooth_info_subscription_;
495   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
496       fan_info_subscription_;
497   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
498       vpd_info_subscription_;
499   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
500       system_info_subscription_;
501   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
502       app_info_subscription_;
503   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
504       stats_reporting_pref_subscription_;
505 
506   AffiliatedSessionService affiliated_session_service_;
507 
508   AppInfoGenerator app_info_generator_;
509 
510   std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
511 
512   // Stores and filters activity periods used for reporting.
513   std::unique_ptr<EnterpriseActivityStorage> activity_storage_;
514 
515   base::WeakPtrFactory<DeviceStatusCollector> weak_factory_{this};
516 
517   DISALLOW_COPY_AND_ASSIGN(DeviceStatusCollector);
518 };
519 
520 }  // namespace policy
521 
522 #endif  // CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_DEVICE_STATUS_COLLECTOR_H_
523