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