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