| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/policy/device_status_collector.h" | 5 #include "chrome/browser/chromeos/policy/device_status_collector.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <cstdio> | 11 #include <cstdio> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <memory> | 13 #include <memory> |
| 14 #include <sstream> | 14 #include <sstream> |
| 15 | 15 |
| 16 #include "base/bind.h" | 16 #include "base/bind.h" |
| 17 #include "base/bind_helpers.h" | 17 #include "base/bind_helpers.h" |
| 18 #include "base/files/file_enumerator.h" | 18 #include "base/files/file_enumerator.h" |
| 19 #include "base/files/file_util.h" | 19 #include "base/files/file_util.h" |
| 20 #include "base/format_macros.h" | 20 #include "base/format_macros.h" |
| 21 #include "base/location.h" | |
| 22 #include "base/logging.h" | 21 #include "base/logging.h" |
| 23 #include "base/macros.h" | 22 #include "base/macros.h" |
| 24 #include "base/memory/ptr_util.h" | 23 #include "base/memory/ptr_util.h" |
| 24 #include "base/memory/ref_counted.h" |
| 25 #include "base/posix/eintr_wrapper.h" | 25 #include "base/posix/eintr_wrapper.h" |
| 26 #include "base/strings/string_number_conversions.h" | 26 #include "base/strings/string_number_conversions.h" |
| 27 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
| 28 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
| 29 #include "base/sys_info.h" | 29 #include "base/sys_info.h" |
| 30 #include "base/task_runner_util.h" | 30 #include "base/task_runner_util.h" |
| 31 #include "base/threading/sequenced_task_runner_handle.h" |
| 31 #include "base/values.h" | 32 #include "base/values.h" |
| 32 #include "base/version.h" | 33 #include "base/version.h" |
| 33 #include "chrome/browser/browser_process.h" | 34 #include "chrome/browser/browser_process.h" |
| 34 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" | 35 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
| 35 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" | 36 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" |
| 36 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 37 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| 37 #include "chrome/browser/chromeos/policy/device_local_account.h" | 38 #include "chrome/browser/chromeos/policy/device_local_account.h" |
| 38 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 39 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 39 #include "chrome/browser/chromeos/settings/cros_settings.h" | 40 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 40 #include "chrome/common/pref_names.h" | 41 #include "chrome/common/pref_names.h" |
| 41 #include "chromeos/dbus/dbus_thread_manager.h" | 42 #include "chromeos/dbus/dbus_thread_manager.h" |
| 42 #include "chromeos/dbus/update_engine_client.h" | 43 #include "chromeos/dbus/update_engine_client.h" |
| 43 #include "chromeos/disks/disk_mount_manager.h" | 44 #include "chromeos/disks/disk_mount_manager.h" |
| 44 #include "chromeos/network/device_state.h" | 45 #include "chromeos/network/device_state.h" |
| 45 #include "chromeos/network/network_handler.h" | 46 #include "chromeos/network/network_handler.h" |
| 46 #include "chromeos/network/network_state.h" | 47 #include "chromeos/network/network_state.h" |
| 47 #include "chromeos/network/network_state_handler.h" | 48 #include "chromeos/network/network_state_handler.h" |
| 48 #include "chromeos/settings/cros_settings_names.h" | 49 #include "chromeos/settings/cros_settings_names.h" |
| 49 #include "chromeos/system/statistics_provider.h" | 50 #include "chromeos/system/statistics_provider.h" |
| 50 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 51 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
| 51 #include "components/policy/proto/device_management_backend.pb.h" | 52 #include "components/policy/proto/device_management_backend.pb.h" |
| 52 #include "components/prefs/pref_registry_simple.h" | 53 #include "components/prefs/pref_registry_simple.h" |
| 53 #include "components/prefs/pref_service.h" | 54 #include "components/prefs/pref_service.h" |
| 54 #include "components/prefs/scoped_user_pref_update.h" | 55 #include "components/prefs/scoped_user_pref_update.h" |
| 55 #include "components/user_manager/user.h" | 56 #include "components/user_manager/user.h" |
| 56 #include "components/user_manager/user_manager.h" | 57 #include "components/user_manager/user_manager.h" |
| 57 #include "components/user_manager/user_type.h" | 58 #include "components/user_manager/user_type.h" |
| 58 #include "components/version_info/version_info.h" | 59 #include "components/version_info/version_info.h" |
| 60 #include "content/public/browser/browser_thread.h" |
| 59 #include "extensions/browser/extension_registry.h" | 61 #include "extensions/browser/extension_registry.h" |
| 60 #include "extensions/common/extension.h" | 62 #include "extensions/common/extension.h" |
| 61 #include "storage/browser/fileapi/external_mount_points.h" | 63 #include "storage/browser/fileapi/external_mount_points.h" |
| 62 #include "third_party/cros_system_api/dbus/service_constants.h" | 64 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 63 | 65 |
| 64 using base::Time; | 66 using base::Time; |
| 65 using base::TimeDelta; | 67 using base::TimeDelta; |
| 66 | 68 |
| 67 namespace em = enterprise_management; | 69 namespace em = enterprise_management; |
| 68 | 70 |
| 69 namespace { | 71 namespace { |
| 70 // How many seconds of inactivity triggers the idle state. | 72 // How many seconds of inactivity triggers the idle state. |
| 71 const int kIdleStateThresholdSeconds = 300; | 73 const int kIdleStateThresholdSeconds = 300; |
| 72 | 74 |
| 73 // How many days in the past to store active periods for. | 75 // How many days in the past to store active periods for. |
| 74 const unsigned int kMaxStoredPastActivityDays = 30; | 76 const unsigned int kMaxStoredPastActivityDays = 30; |
| 75 | 77 |
| 76 // How many days in the future to store active periods for. | 78 // How many days in the future to store active periods for. |
| 77 const unsigned int kMaxStoredFutureActivityDays = 2; | 79 const unsigned int kMaxStoredFutureActivityDays = 2; |
| 78 | 80 |
| 79 // How often, in seconds, to update the device location. | 81 // How often, in seconds, to sample the hardware resource usage. |
| 80 const unsigned int kGeolocationPollIntervalSeconds = 30 * 60; | 82 const unsigned int kResourceUsageSampleIntervalSeconds = 120; |
| 81 | |
| 82 // How often, in seconds, to sample the hardware state. | |
| 83 const unsigned int kHardwareStatusSampleIntervalSeconds = 120; | |
| 84 | |
| 85 // Keys for the geolocation status dictionary in local state. | |
| 86 const char kLatitude[] = "latitude"; | |
| 87 const char kLongitude[] = "longitude"; | |
| 88 const char kAltitude[] = "altitude"; | |
| 89 const char kAccuracy[] = "accuracy"; | |
| 90 const char kAltitudeAccuracy[] = "altitude_accuracy"; | |
| 91 const char kHeading[] = "heading"; | |
| 92 const char kSpeed[] = "speed"; | |
| 93 const char kTimestamp[] = "timestamp"; | |
| 94 | 83 |
| 95 // The location we read our CPU statistics from. | 84 // The location we read our CPU statistics from. |
| 96 const char kProcStat[] = "/proc/stat"; | 85 const char kProcStat[] = "/proc/stat"; |
| 97 | 86 |
| 98 // The location we read our CPU temperature and channel label from. | 87 // The location we read our CPU temperature and channel label from. |
| 99 const char kHwmonDir[] = "/sys/class/hwmon/"; | 88 const char kHwmonDir[] = "/sys/class/hwmon/"; |
| 100 const char kDeviceDir[] = "device"; | 89 const char kDeviceDir[] = "device"; |
| 101 const char kHwmonDirectoryPattern[] = "hwmon*"; | 90 const char kHwmonDirectoryPattern[] = "hwmon*"; |
| 102 const char kCPUTempFilePattern[] = "temp*_input"; | 91 const char kCPUTempFilePattern[] = "temp*_input"; |
| 103 | 92 |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 // (crbug.com/463334). | 265 // (crbug.com/463334). |
| 277 DCHECK_GT(signal_strength, 0); | 266 DCHECK_GT(signal_strength, 0); |
| 278 DCHECK_LE(signal_strength, 100); | 267 DCHECK_LE(signal_strength, 100); |
| 279 return signal_strength - 120; | 268 return signal_strength - 120; |
| 280 } | 269 } |
| 281 | 270 |
| 282 } // namespace | 271 } // namespace |
| 283 | 272 |
| 284 namespace policy { | 273 namespace policy { |
| 285 | 274 |
| 275 // Helper class for state tracking of async status queries. Creates device and |
| 276 // session status blobs in the constructor and sends them to the the status |
| 277 // response callback in the destructor. |
| 278 // |
| 279 // Some methods like |SampleVolumeInfo| queue async queries to collect data. The |
| 280 // response callback of these queries, e.g. |OnVolumeInfoReceived|, holds a |
| 281 // reference to the instance of this class, so that the destructor will not be |
| 282 // invoked and the status response callback will not be fired until the original |
| 283 // owner of the instance releases its reference and all async queries finish. |
| 284 // |
| 285 // Therefore, if you create an instance of this class, make sure to release your |
| 286 // reference after quering all async queries (if any), e.g. by using a local |
| 287 // |scoped_refptr<GetStatusState>| and letting it go out of scope. |
| 288 class GetStatusState : public base::RefCountedThreadSafe<GetStatusState> { |
| 289 public: |
| 290 explicit GetStatusState( |
| 291 const scoped_refptr<base::SequencedTaskRunner> task_runner, |
| 292 const policy::DeviceStatusCollector::StatusCallback& response) |
| 293 : task_runner_(task_runner), response_(response) {} |
| 294 |
| 295 inline em::DeviceStatusReportRequest* device_status() { |
| 296 return device_status_.get(); |
| 297 } |
| 298 |
| 299 inline em::SessionStatusReportRequest* session_status() { |
| 300 return session_status_.get(); |
| 301 } |
| 302 |
| 303 inline void ResetDeviceStatus() { device_status_.reset(); } |
| 304 |
| 305 inline void ResetSessionStatus() { session_status_.reset(); } |
| 306 |
| 307 // Queues an async callback to query disk volume information. |
| 308 void SampleVolumeInfo(const policy::DeviceStatusCollector::VolumeInfoFetcher& |
| 309 volume_info_fetcher) { |
| 310 // Create list of mounted disk volumes to query status. |
| 311 std::vector<storage::MountPoints::MountPointInfo> external_mount_points; |
| 312 storage::ExternalMountPoints::GetSystemInstance()->AddMountPointInfosTo( |
| 313 &external_mount_points); |
| 314 |
| 315 std::vector<std::string> mount_points; |
| 316 for (const auto& info : external_mount_points) |
| 317 mount_points.push_back(info.path.value()); |
| 318 |
| 319 for (const auto& mount_info : |
| 320 chromeos::disks::DiskMountManager::GetInstance()->mount_points()) { |
| 321 // Extract a list of mount points to populate. |
| 322 mount_points.push_back(mount_info.first); |
| 323 } |
| 324 |
| 325 // Call out to the blocking pool to sample disk volume info. |
| 326 base::PostTaskAndReplyWithResult( |
| 327 content::BrowserThread::GetBlockingPool(), FROM_HERE, |
| 328 base::Bind(volume_info_fetcher, mount_points), |
| 329 base::Bind(&GetStatusState::OnVolumeInfoReceived, this)); |
| 330 } |
| 331 |
| 332 // Queues an async callback to query CPU temperature information. |
| 333 void SampleCPUTempInfo( |
| 334 const policy::DeviceStatusCollector::CPUTempFetcher& cpu_temp_fetcher) { |
| 335 // Call out to the blocking pool to sample CPU temp. |
| 336 base::PostTaskAndReplyWithResult( |
| 337 content::BrowserThread::GetBlockingPool(), FROM_HERE, cpu_temp_fetcher, |
| 338 base::Bind(&GetStatusState::OnCPUTempInfoReceived, this)); |
| 339 } |
| 340 |
| 341 private: |
| 342 friend class RefCountedThreadSafe<GetStatusState>; |
| 343 |
| 344 // Posts the response on the UI thread. As long as there is an outstanding |
| 345 // async query, the query holds a reference to us, so the destructor is |
| 346 // not called. |
| 347 ~GetStatusState() { |
| 348 task_runner_->PostTask(FROM_HERE, |
| 349 base::Bind(response_, base::Passed(&device_status_), |
| 350 base::Passed(&session_status_))); |
| 351 } |
| 352 |
| 353 void OnVolumeInfoReceived(const std::vector<em::VolumeInfo>& volume_info) { |
| 354 device_status_->clear_volume_info(); |
| 355 for (const em::VolumeInfo& info : volume_info) |
| 356 *device_status_->add_volume_info() = info; |
| 357 } |
| 358 |
| 359 void OnCPUTempInfoReceived( |
| 360 const std::vector<em::CPUTempInfo>& cpu_temp_info) { |
| 361 if (cpu_temp_info.empty()) |
| 362 DLOG(WARNING) << "Unable to read CPU temp information."; |
| 363 |
| 364 device_status_->clear_cpu_temp_info(); |
| 365 for (const em::CPUTempInfo& info : cpu_temp_info) |
| 366 *device_status_->add_cpu_temp_info() = info; |
| 367 } |
| 368 |
| 369 const scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 370 policy::DeviceStatusCollector::StatusCallback response_; |
| 371 std::unique_ptr<em::DeviceStatusReportRequest> device_status_ = |
| 372 base::MakeUnique<em::DeviceStatusReportRequest>(); |
| 373 std::unique_ptr<em::SessionStatusReportRequest> session_status_ = |
| 374 base::MakeUnique<em::SessionStatusReportRequest>(); |
| 375 }; |
| 376 |
| 286 DeviceStatusCollector::DeviceStatusCollector( | 377 DeviceStatusCollector::DeviceStatusCollector( |
| 287 PrefService* local_state, | 378 PrefService* local_state, |
| 288 chromeos::system::StatisticsProvider* provider, | 379 chromeos::system::StatisticsProvider* provider, |
| 289 const LocationUpdateRequester& location_update_requester, | |
| 290 const VolumeInfoFetcher& volume_info_fetcher, | 380 const VolumeInfoFetcher& volume_info_fetcher, |
| 291 const CPUStatisticsFetcher& cpu_statistics_fetcher, | 381 const CPUStatisticsFetcher& cpu_statistics_fetcher, |
| 292 const CPUTempFetcher& cpu_temp_fetcher) | 382 const CPUTempFetcher& cpu_temp_fetcher) |
| 293 : max_stored_past_activity_days_(kMaxStoredPastActivityDays), | 383 : max_stored_past_activity_days_(kMaxStoredPastActivityDays), |
| 294 max_stored_future_activity_days_(kMaxStoredFutureActivityDays), | 384 max_stored_future_activity_days_(kMaxStoredFutureActivityDays), |
| 295 local_state_(local_state), | 385 local_state_(local_state), |
| 296 last_idle_check_(Time()), | 386 last_idle_check_(Time()), |
| 297 volume_info_fetcher_(volume_info_fetcher), | 387 volume_info_fetcher_(volume_info_fetcher), |
| 298 cpu_statistics_fetcher_(cpu_statistics_fetcher), | 388 cpu_statistics_fetcher_(cpu_statistics_fetcher), |
| 299 cpu_temp_fetcher_(cpu_temp_fetcher), | 389 cpu_temp_fetcher_(cpu_temp_fetcher), |
| 300 statistics_provider_(provider), | 390 statistics_provider_(provider), |
| 301 cros_settings_(chromeos::CrosSettings::Get()), | 391 cros_settings_(chromeos::CrosSettings::Get()), |
| 302 location_update_requester_(location_update_requester), | 392 task_runner_(nullptr), |
| 303 weak_factory_(this) { | 393 weak_factory_(this) { |
| 304 CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&creation_thread_)); | 394 // Get the task runner of the current thread, so we can queue status responses |
| 395 // on this thread. |
| 396 CHECK(base::SequencedTaskRunnerHandle::IsSet()); |
| 397 task_runner_ = base::SequencedTaskRunnerHandle::Get(); |
| 305 | 398 |
| 306 if (volume_info_fetcher_.is_null()) | 399 if (volume_info_fetcher_.is_null()) |
| 307 volume_info_fetcher_ = base::Bind(&GetVolumeInfo); | 400 volume_info_fetcher_ = base::Bind(&GetVolumeInfo); |
| 308 | 401 |
| 309 if (cpu_statistics_fetcher_.is_null()) | 402 if (cpu_statistics_fetcher_.is_null()) |
| 310 cpu_statistics_fetcher_ = base::Bind(&ReadCPUStatistics); | 403 cpu_statistics_fetcher_ = base::Bind(&ReadCPUStatistics); |
| 311 | 404 |
| 312 if (cpu_temp_fetcher_.is_null()) | 405 if (cpu_temp_fetcher_.is_null()) |
| 313 cpu_temp_fetcher_ = base::Bind(&ReadCPUTempInfo); | 406 cpu_temp_fetcher_ = base::Bind(&ReadCPUTempInfo); |
| 314 | 407 |
| 315 idle_poll_timer_.Start(FROM_HERE, | 408 idle_poll_timer_.Start(FROM_HERE, |
| 316 TimeDelta::FromSeconds(kIdlePollIntervalSeconds), | 409 TimeDelta::FromSeconds(kIdlePollIntervalSeconds), |
| 317 this, &DeviceStatusCollector::CheckIdleState); | 410 this, &DeviceStatusCollector::CheckIdleState); |
| 318 hardware_status_sampling_timer_.Start( | 411 resource_usage_sampling_timer_.Start( |
| 319 FROM_HERE, | 412 FROM_HERE, TimeDelta::FromSeconds(kResourceUsageSampleIntervalSeconds), |
| 320 TimeDelta::FromSeconds(kHardwareStatusSampleIntervalSeconds), | 413 this, &DeviceStatusCollector::SampleResourceUsage); |
| 321 this, &DeviceStatusCollector::SampleHardwareStatus); | |
| 322 | 414 |
| 323 // Watch for changes to the individual policies that control what the status | 415 // Watch for changes to the individual policies that control what the status |
| 324 // reports contain. | 416 // reports contain. |
| 325 base::Closure callback = | 417 base::Closure callback = |
| 326 base::Bind(&DeviceStatusCollector::UpdateReportingSettings, | 418 base::Bind(&DeviceStatusCollector::UpdateReportingSettings, |
| 327 base::Unretained(this)); | 419 base::Unretained(this)); |
| 328 version_info_subscription_ = cros_settings_->AddSettingsObserver( | 420 version_info_subscription_ = cros_settings_->AddSettingsObserver( |
| 329 chromeos::kReportDeviceVersionInfo, callback); | 421 chromeos::kReportDeviceVersionInfo, callback); |
| 330 activity_times_subscription_ = cros_settings_->AddSettingsObserver( | 422 activity_times_subscription_ = cros_settings_->AddSettingsObserver( |
| 331 chromeos::kReportDeviceActivityTimes, callback); | 423 chromeos::kReportDeviceActivityTimes, callback); |
| 332 boot_mode_subscription_ = cros_settings_->AddSettingsObserver( | 424 boot_mode_subscription_ = cros_settings_->AddSettingsObserver( |
| 333 chromeos::kReportDeviceBootMode, callback); | 425 chromeos::kReportDeviceBootMode, callback); |
| 334 location_subscription_ = cros_settings_->AddSettingsObserver( | |
| 335 chromeos::kReportDeviceLocation, callback); | |
| 336 network_interfaces_subscription_ = cros_settings_->AddSettingsObserver( | 426 network_interfaces_subscription_ = cros_settings_->AddSettingsObserver( |
| 337 chromeos::kReportDeviceNetworkInterfaces, callback); | 427 chromeos::kReportDeviceNetworkInterfaces, callback); |
| 338 users_subscription_ = cros_settings_->AddSettingsObserver( | 428 users_subscription_ = cros_settings_->AddSettingsObserver( |
| 339 chromeos::kReportDeviceUsers, callback); | 429 chromeos::kReportDeviceUsers, callback); |
| 340 hardware_status_subscription_ = cros_settings_->AddSettingsObserver( | 430 hardware_status_subscription_ = cros_settings_->AddSettingsObserver( |
| 341 chromeos::kReportDeviceHardwareStatus, callback); | 431 chromeos::kReportDeviceHardwareStatus, callback); |
| 342 session_status_subscription_ = cros_settings_->AddSettingsObserver( | 432 session_status_subscription_ = cros_settings_->AddSettingsObserver( |
| 343 chromeos::kReportDeviceSessionStatus, callback); | 433 chromeos::kReportDeviceSessionStatus, callback); |
| 344 os_update_status_subscription_ = cros_settings_->AddSettingsObserver( | 434 os_update_status_subscription_ = cros_settings_->AddSettingsObserver( |
| 345 chromeos::kReportOsUpdateStatus, callback); | 435 chromeos::kReportOsUpdateStatus, callback); |
| 346 running_kiosk_app_subscription_ = cros_settings_->AddSettingsObserver( | 436 running_kiosk_app_subscription_ = cros_settings_->AddSettingsObserver( |
| 347 chromeos::kReportRunningKioskApp, callback); | 437 chromeos::kReportRunningKioskApp, callback); |
| 348 | 438 |
| 349 // The last known location is persisted in local state. This makes location | |
| 350 // information available immediately upon startup and avoids the need to | |
| 351 // reacquire the location on every user session change or browser crash. | |
| 352 device::Geoposition position; | |
| 353 std::string timestamp_str; | |
| 354 int64_t timestamp; | |
| 355 const base::DictionaryValue* location = | |
| 356 local_state_->GetDictionary(prefs::kDeviceLocation); | |
| 357 if (location->GetDouble(kLatitude, &position.latitude) && | |
| 358 location->GetDouble(kLongitude, &position.longitude) && | |
| 359 location->GetDouble(kAltitude, &position.altitude) && | |
| 360 location->GetDouble(kAccuracy, &position.accuracy) && | |
| 361 location->GetDouble(kAltitudeAccuracy, &position.altitude_accuracy) && | |
| 362 location->GetDouble(kHeading, &position.heading) && | |
| 363 location->GetDouble(kSpeed, &position.speed) && | |
| 364 location->GetString(kTimestamp, ×tamp_str) && | |
| 365 base::StringToInt64(timestamp_str, ×tamp)) { | |
| 366 position.timestamp = Time::FromInternalValue(timestamp); | |
| 367 position_ = position; | |
| 368 } | |
| 369 | |
| 370 // Fetch the current values of the policies. | 439 // Fetch the current values of the policies. |
| 371 UpdateReportingSettings(); | 440 UpdateReportingSettings(); |
| 372 | 441 |
| 373 // Get the the OS and firmware version info. | 442 // Get the the OS and firmware version info. |
| 374 base::PostTaskAndReplyWithResult( | 443 base::PostTaskAndReplyWithResult( |
| 375 content::BrowserThread::GetBlockingPool(), | 444 content::BrowserThread::GetBlockingPool(), |
| 376 FROM_HERE, | 445 FROM_HERE, |
| 377 base::Bind(&chromeos::version_loader::GetVersion, | 446 base::Bind(&chromeos::version_loader::GetVersion, |
| 378 chromeos::version_loader::VERSION_FULL), | 447 chromeos::version_loader::VERSION_FULL), |
| 379 base::Bind(&DeviceStatusCollector::OnOSVersion, | 448 base::Bind(&DeviceStatusCollector::OnOSVersion, |
| 380 weak_factory_.GetWeakPtr())); | 449 weak_factory_.GetWeakPtr())); |
| 381 base::PostTaskAndReplyWithResult( | 450 base::PostTaskAndReplyWithResult( |
| 382 content::BrowserThread::GetBlockingPool(), | 451 content::BrowserThread::GetBlockingPool(), |
| 383 FROM_HERE, | 452 FROM_HERE, |
| 384 base::Bind(&chromeos::version_loader::GetFirmware), | 453 base::Bind(&chromeos::version_loader::GetFirmware), |
| 385 base::Bind(&DeviceStatusCollector::OnOSFirmware, | 454 base::Bind(&DeviceStatusCollector::OnOSFirmware, |
| 386 weak_factory_.GetWeakPtr())); | 455 weak_factory_.GetWeakPtr())); |
| 387 } | 456 } |
| 388 | 457 |
| 389 DeviceStatusCollector::~DeviceStatusCollector() { | 458 DeviceStatusCollector::~DeviceStatusCollector() { |
| 390 } | 459 } |
| 391 | 460 |
| 392 // static | 461 // static |
| 393 void DeviceStatusCollector::RegisterPrefs(PrefRegistrySimple* registry) { | 462 void DeviceStatusCollector::RegisterPrefs(PrefRegistrySimple* registry) { |
| 394 registry->RegisterDictionaryPref(prefs::kDeviceActivityTimes, | 463 registry->RegisterDictionaryPref(prefs::kDeviceActivityTimes, |
| 395 new base::DictionaryValue); | 464 new base::DictionaryValue); |
| 396 registry->RegisterDictionaryPref(prefs::kDeviceLocation, | |
| 397 new base::DictionaryValue); | |
| 398 } | 465 } |
| 399 | 466 |
| 400 void DeviceStatusCollector::CheckIdleState() { | 467 void DeviceStatusCollector::CheckIdleState() { |
| 401 CalculateIdleState(kIdleStateThresholdSeconds, | 468 CalculateIdleState(kIdleStateThresholdSeconds, |
| 402 base::Bind(&DeviceStatusCollector::IdleStateCallback, | 469 base::Bind(&DeviceStatusCollector::IdleStateCallback, |
| 403 base::Unretained(this))); | 470 base::Unretained(this))); |
| 404 } | 471 } |
| 405 | 472 |
| 406 void DeviceStatusCollector::UpdateReportingSettings() { | 473 void DeviceStatusCollector::UpdateReportingSettings() { |
| 407 // Attempt to fetch the current value of the reporting settings. | 474 // Attempt to fetch the current value of the reporting settings. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 if (!cros_settings_->GetBoolean( | 508 if (!cros_settings_->GetBoolean( |
| 442 chromeos::kReportDeviceHardwareStatus, &report_hardware_status_)) { | 509 chromeos::kReportDeviceHardwareStatus, &report_hardware_status_)) { |
| 443 report_hardware_status_ = true; | 510 report_hardware_status_ = true; |
| 444 } | 511 } |
| 445 | 512 |
| 446 if (!cros_settings_->GetBoolean( | 513 if (!cros_settings_->GetBoolean( |
| 447 chromeos::kReportDeviceSessionStatus, &report_session_status_)) { | 514 chromeos::kReportDeviceSessionStatus, &report_session_status_)) { |
| 448 report_session_status_ = true; | 515 report_session_status_ = true; |
| 449 } | 516 } |
| 450 | 517 |
| 451 // Device location reporting is disabled by default because it is | |
| 452 // not launched yet. | |
| 453 if (!cros_settings_->GetBoolean( | |
| 454 chromeos::kReportDeviceLocation, &report_location_)) { | |
| 455 report_location_ = false; | |
| 456 } | |
| 457 | |
| 458 if (report_location_) { | |
| 459 ScheduleGeolocationUpdateRequest(); | |
| 460 } else { | |
| 461 geolocation_update_timer_.Stop(); | |
| 462 position_ = device::Geoposition(); | |
| 463 local_state_->ClearPref(prefs::kDeviceLocation); | |
| 464 } | |
| 465 | |
| 466 if (!report_hardware_status_) { | 518 if (!report_hardware_status_) { |
| 467 ClearCachedHardwareStatus(); | 519 ClearCachedResourceUsage(); |
| 468 } else if (!already_reporting_hardware_status) { | 520 } else if (!already_reporting_hardware_status) { |
| 469 // Turning on hardware status reporting - fetch an initial sample | 521 // Turning on hardware status reporting - fetch an initial sample |
| 470 // immediately instead of waiting for the sampling timer to fire. | 522 // immediately instead of waiting for the sampling timer to fire. |
| 471 SampleHardwareStatus(); | 523 SampleResourceUsage(); |
| 472 } | 524 } |
| 473 | 525 |
| 474 // Os update status and running kiosk app reporting are disabled by default. | 526 // Os update status and running kiosk app reporting are disabled by default. |
| 475 if (!cros_settings_->GetBoolean(chromeos::kReportOsUpdateStatus, | 527 if (!cros_settings_->GetBoolean(chromeos::kReportOsUpdateStatus, |
| 476 &report_os_update_status_)) { | 528 &report_os_update_status_)) { |
| 477 report_os_update_status_ = false; | 529 report_os_update_status_ = false; |
| 478 } | 530 } |
| 479 if (!cros_settings_->GetBoolean(chromeos::kReportRunningKioskApp, | 531 if (!cros_settings_->GetBoolean(chromeos::kReportRunningKioskApp, |
| 480 &report_running_kiosk_app_)) { | 532 &report_running_kiosk_app_)) { |
| 481 report_running_kiosk_app_ = false; | 533 report_running_kiosk_app_ = false; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 midnight += TimeDelta::FromDays(1); | 591 midnight += TimeDelta::FromDays(1); |
| 540 int64_t activity = (std::min(end, midnight) - start).InMilliseconds(); | 592 int64_t activity = (std::min(end, midnight) - start).InMilliseconds(); |
| 541 std::string day_key = base::Int64ToString(TimestampToDayKey(start)); | 593 std::string day_key = base::Int64ToString(TimestampToDayKey(start)); |
| 542 int previous_activity = 0; | 594 int previous_activity = 0; |
| 543 activity_times->GetInteger(day_key, &previous_activity); | 595 activity_times->GetInteger(day_key, &previous_activity); |
| 544 activity_times->SetInteger(day_key, previous_activity + activity); | 596 activity_times->SetInteger(day_key, previous_activity + activity); |
| 545 start = midnight; | 597 start = midnight; |
| 546 } | 598 } |
| 547 } | 599 } |
| 548 | 600 |
| 549 void DeviceStatusCollector::ClearCachedHardwareStatus() { | 601 void DeviceStatusCollector::ClearCachedResourceUsage() { |
| 550 volume_info_.clear(); | |
| 551 resource_usage_.clear(); | 602 resource_usage_.clear(); |
| 552 last_cpu_active_ = 0; | 603 last_cpu_active_ = 0; |
| 553 last_cpu_idle_ = 0; | 604 last_cpu_idle_ = 0; |
| 554 } | 605 } |
| 555 | 606 |
| 556 void DeviceStatusCollector::IdleStateCallback(ui::IdleState state) { | 607 void DeviceStatusCollector::IdleStateCallback(ui::IdleState state) { |
| 557 // Do nothing if device activity reporting is disabled. | 608 // Do nothing if device activity reporting is disabled. |
| 558 if (!report_activity_times_) | 609 if (!report_activity_times_) |
| 559 return; | 610 return; |
| 560 | 611 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 587 if (chromeos::KioskAppManager::Get()->GetApp(account->kiosk_app_id, | 638 if (chromeos::KioskAppManager::Get()->GetApp(account->kiosk_app_id, |
| 588 ¤t_app) && | 639 ¤t_app) && |
| 589 current_app.was_auto_launched_with_zero_delay) { | 640 current_app.was_auto_launched_with_zero_delay) { |
| 590 return account; | 641 return account; |
| 591 } | 642 } |
| 592 } | 643 } |
| 593 // No auto-launched kiosk session active. | 644 // No auto-launched kiosk session active. |
| 594 return std::unique_ptr<DeviceLocalAccount>(); | 645 return std::unique_ptr<DeviceLocalAccount>(); |
| 595 } | 646 } |
| 596 | 647 |
| 597 void DeviceStatusCollector::SampleHardwareStatus() { | 648 void DeviceStatusCollector::SampleResourceUsage() { |
| 598 // Results must be written in the creation thread since that's where they | 649 // Results must be written in the creation thread since that's where they |
| 599 // are read from in the Get*StatusAsync methods. | 650 // are read from in the Get*StatusAsync methods. |
| 600 CHECK(content::BrowserThread::CurrentlyOn(creation_thread_)); | 651 DCHECK(thread_checker_.CalledOnValidThread()); |
| 601 | 652 |
| 602 // If hardware reporting has been disabled, do nothing here. | 653 // If hardware reporting has been disabled, do nothing here. |
| 603 if (!report_hardware_status_) | 654 if (!report_hardware_status_) |
| 604 return; | 655 return; |
| 605 | 656 |
| 606 // Create list of mounted disk volumes to query status. | 657 // Call out to the blocking pool to sample CPU stats. |
| 607 std::vector<storage::MountPoints::MountPointInfo> external_mount_points; | |
| 608 storage::ExternalMountPoints::GetSystemInstance()->AddMountPointInfosTo( | |
| 609 &external_mount_points); | |
| 610 | |
| 611 std::vector<std::string> mount_points; | |
| 612 for (const auto& info : external_mount_points) | |
| 613 mount_points.push_back(info.path.value()); | |
| 614 | |
| 615 for (const auto& mount_info : | |
| 616 chromeos::disks::DiskMountManager::GetInstance()->mount_points()) { | |
| 617 // Extract a list of mount points to populate. | |
| 618 mount_points.push_back(mount_info.first); | |
| 619 } | |
| 620 | |
| 621 // Call out to the blocking pool to measure disk, CPU usage and CPU temp. | |
| 622 base::PostTaskAndReplyWithResult( | |
| 623 content::BrowserThread::GetBlockingPool(), | |
| 624 FROM_HERE, | |
| 625 base::Bind(volume_info_fetcher_, mount_points), | |
| 626 base::Bind(&DeviceStatusCollector::ReceiveVolumeInfo, | |
| 627 weak_factory_.GetWeakPtr())); | |
| 628 | |
| 629 base::PostTaskAndReplyWithResult( | 658 base::PostTaskAndReplyWithResult( |
| 630 content::BrowserThread::GetBlockingPool(), FROM_HERE, | 659 content::BrowserThread::GetBlockingPool(), FROM_HERE, |
| 631 cpu_statistics_fetcher_, | 660 cpu_statistics_fetcher_, |
| 632 base::Bind(&DeviceStatusCollector::ReceiveCPUStatistics, | 661 base::Bind(&DeviceStatusCollector::ReceiveCPUStatistics, |
| 633 weak_factory_.GetWeakPtr())); | 662 weak_factory_.GetWeakPtr())); |
| 634 | |
| 635 base::PostTaskAndReplyWithResult( | |
| 636 content::BrowserThread::GetBlockingPool(), FROM_HERE, cpu_temp_fetcher_, | |
| 637 base::Bind(&DeviceStatusCollector::StoreCPUTempInfo, | |
| 638 weak_factory_.GetWeakPtr())); | |
| 639 } | 663 } |
| 640 | 664 |
| 641 void DeviceStatusCollector::ReceiveCPUStatistics(const std::string& stats) { | 665 void DeviceStatusCollector::ReceiveCPUStatistics(const std::string& stats) { |
| 642 int cpu_usage_percent = 0; | 666 int cpu_usage_percent = 0; |
| 643 if (stats.empty()) { | 667 if (stats.empty()) { |
| 644 DLOG(WARNING) << "Unable to read CPU statistics"; | 668 DLOG(WARNING) << "Unable to read CPU statistics"; |
| 645 } else { | 669 } else { |
| 646 // Parse the data from /proc/stat, whose format is defined at | 670 // Parse the data from /proc/stat, whose format is defined at |
| 647 // https://www.kernel.org/doc/Documentation/filesystems/proc.txt. | 671 // https://www.kernel.org/doc/Documentation/filesystems/proc.txt. |
| 648 // | 672 // |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 base::SysInfo::AmountOfAvailablePhysicalMemory()}; | 708 base::SysInfo::AmountOfAvailablePhysicalMemory()}; |
| 685 | 709 |
| 686 resource_usage_.push_back(usage); | 710 resource_usage_.push_back(usage); |
| 687 | 711 |
| 688 // If our cache of samples is full, throw out old samples to make room for new | 712 // If our cache of samples is full, throw out old samples to make room for new |
| 689 // sample. | 713 // sample. |
| 690 if (resource_usage_.size() > kMaxResourceUsageSamples) | 714 if (resource_usage_.size() > kMaxResourceUsageSamples) |
| 691 resource_usage_.pop_front(); | 715 resource_usage_.pop_front(); |
| 692 } | 716 } |
| 693 | 717 |
| 694 void DeviceStatusCollector::StoreCPUTempInfo( | |
| 695 const std::vector<em::CPUTempInfo>& info) { | |
| 696 if (info.empty()) { | |
| 697 DLOG(WARNING) << "Unable to read CPU temp information."; | |
| 698 } | |
| 699 | |
| 700 if (report_hardware_status_) | |
| 701 cpu_temp_info_ = info; | |
| 702 } | |
| 703 | |
| 704 bool DeviceStatusCollector::GetActivityTimes( | 718 bool DeviceStatusCollector::GetActivityTimes( |
| 705 em::DeviceStatusReportRequest* request) { | 719 em::DeviceStatusReportRequest* status) { |
| 706 DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes); | 720 DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes); |
| 707 base::DictionaryValue* activity_times = update.Get(); | 721 base::DictionaryValue* activity_times = update.Get(); |
| 708 | 722 |
| 709 bool anything_reported = false; | 723 bool anything_reported = false; |
| 710 for (base::DictionaryValue::Iterator it(*activity_times); !it.IsAtEnd(); | 724 for (base::DictionaryValue::Iterator it(*activity_times); !it.IsAtEnd(); |
| 711 it.Advance()) { | 725 it.Advance()) { |
| 712 int64_t start_timestamp; | 726 int64_t start_timestamp; |
| 713 int activity_milliseconds; | 727 int activity_milliseconds; |
| 714 if (base::StringToInt64(it.key(), &start_timestamp) && | 728 if (base::StringToInt64(it.key(), &start_timestamp) && |
| 715 it.value().GetAsInteger(&activity_milliseconds)) { | 729 it.value().GetAsInteger(&activity_milliseconds)) { |
| 716 // This is correct even when there are leap seconds, because when a leap | 730 // This is correct even when there are leap seconds, because when a leap |
| 717 // second occurs, two consecutive seconds have the same timestamp. | 731 // second occurs, two consecutive seconds have the same timestamp. |
| 718 int64_t end_timestamp = start_timestamp + Time::kMillisecondsPerDay; | 732 int64_t end_timestamp = start_timestamp + Time::kMillisecondsPerDay; |
| 719 | 733 |
| 720 em::ActiveTimePeriod* active_period = request->add_active_period(); | 734 em::ActiveTimePeriod* active_period = status->add_active_period(); |
| 721 em::TimePeriod* period = active_period->mutable_time_period(); | 735 em::TimePeriod* period = active_period->mutable_time_period(); |
| 722 period->set_start_timestamp(start_timestamp); | 736 period->set_start_timestamp(start_timestamp); |
| 723 period->set_end_timestamp(end_timestamp); | 737 period->set_end_timestamp(end_timestamp); |
| 724 active_period->set_active_duration(activity_milliseconds); | 738 active_period->set_active_duration(activity_milliseconds); |
| 725 if (start_timestamp >= last_reported_day_) { | 739 if (start_timestamp >= last_reported_day_) { |
| 726 last_reported_day_ = start_timestamp; | 740 last_reported_day_ = start_timestamp; |
| 727 duration_for_last_reported_day_ = activity_milliseconds; | 741 duration_for_last_reported_day_ = activity_milliseconds; |
| 728 } | 742 } |
| 729 anything_reported = true; | 743 anything_reported = true; |
| 730 } else { | 744 } else { |
| 731 NOTREACHED(); | 745 NOTREACHED(); |
| 732 } | 746 } |
| 733 } | 747 } |
| 734 return anything_reported; | 748 return anything_reported; |
| 735 } | 749 } |
| 736 | 750 |
| 737 bool DeviceStatusCollector::GetVersionInfo( | 751 bool DeviceStatusCollector::GetVersionInfo( |
| 738 em::DeviceStatusReportRequest* request) { | 752 em::DeviceStatusReportRequest* status) { |
| 739 request->set_browser_version(version_info::GetVersionNumber()); | 753 status->set_browser_version(version_info::GetVersionNumber()); |
| 740 request->set_os_version(os_version_); | 754 status->set_os_version(os_version_); |
| 741 request->set_firmware_version(firmware_version_); | 755 status->set_firmware_version(firmware_version_); |
| 742 return true; | 756 return true; |
| 743 } | 757 } |
| 744 | 758 |
| 745 bool DeviceStatusCollector::GetBootMode( | 759 bool DeviceStatusCollector::GetBootMode(em::DeviceStatusReportRequest* status) { |
| 746 em::DeviceStatusReportRequest* request) { | |
| 747 std::string dev_switch_mode; | 760 std::string dev_switch_mode; |
| 748 bool anything_reported = false; | 761 bool anything_reported = false; |
| 749 if (statistics_provider_->GetMachineStatistic( | 762 if (statistics_provider_->GetMachineStatistic( |
| 750 chromeos::system::kDevSwitchBootKey, &dev_switch_mode)) { | 763 chromeos::system::kDevSwitchBootKey, &dev_switch_mode)) { |
| 751 if (dev_switch_mode == chromeos::system::kDevSwitchBootValueDev) | 764 if (dev_switch_mode == chromeos::system::kDevSwitchBootValueDev) |
| 752 request->set_boot_mode("Dev"); | 765 status->set_boot_mode("Dev"); |
| 753 else if (dev_switch_mode == chromeos::system::kDevSwitchBootValueVerified) | 766 else if (dev_switch_mode == chromeos::system::kDevSwitchBootValueVerified) |
| 754 request->set_boot_mode("Verified"); | 767 status->set_boot_mode("Verified"); |
| 755 anything_reported = true; | 768 anything_reported = true; |
| 756 } | 769 } |
| 757 return anything_reported; | 770 return anything_reported; |
| 758 } | 771 } |
| 759 | 772 |
| 760 bool DeviceStatusCollector::GetLocation( | |
| 761 em::DeviceStatusReportRequest* request) { | |
| 762 em::DeviceLocation* location = request->mutable_device_location(); | |
| 763 if (!position_.Validate()) { | |
| 764 location->set_error_code( | |
| 765 em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE); | |
| 766 location->set_error_message(position_.error_message); | |
| 767 } else { | |
| 768 location->set_latitude(position_.latitude); | |
| 769 location->set_longitude(position_.longitude); | |
| 770 location->set_accuracy(position_.accuracy); | |
| 771 location->set_timestamp( | |
| 772 (position_.timestamp - Time::UnixEpoch()).InMilliseconds()); | |
| 773 // Lowest point on land is at approximately -400 meters. | |
| 774 if (position_.altitude > -10000.) | |
| 775 location->set_altitude(position_.altitude); | |
| 776 if (position_.altitude_accuracy >= 0.) | |
| 777 location->set_altitude_accuracy(position_.altitude_accuracy); | |
| 778 if (position_.heading >= 0. && position_.heading <= 360) | |
| 779 location->set_heading(position_.heading); | |
| 780 if (position_.speed >= 0.) | |
| 781 location->set_speed(position_.speed); | |
| 782 location->set_error_code(em::DeviceLocation::ERROR_CODE_NONE); | |
| 783 } | |
| 784 return true; | |
| 785 } | |
| 786 | |
| 787 bool DeviceStatusCollector::GetNetworkInterfaces( | 773 bool DeviceStatusCollector::GetNetworkInterfaces( |
| 788 em::DeviceStatusReportRequest* request) { | 774 em::DeviceStatusReportRequest* status) { |
| 789 // Maps shill device type strings to proto enum constants. | 775 // Maps shill device type strings to proto enum constants. |
| 790 static const struct { | 776 static const struct { |
| 791 const char* type_string; | 777 const char* type_string; |
| 792 em::NetworkInterface::NetworkDeviceType type_constant; | 778 em::NetworkInterface::NetworkDeviceType type_constant; |
| 793 } kDeviceTypeMap[] = { | 779 } kDeviceTypeMap[] = { |
| 794 { shill::kTypeEthernet, em::NetworkInterface::TYPE_ETHERNET, }, | 780 { shill::kTypeEthernet, em::NetworkInterface::TYPE_ETHERNET, }, |
| 795 { shill::kTypeWifi, em::NetworkInterface::TYPE_WIFI, }, | 781 { shill::kTypeWifi, em::NetworkInterface::TYPE_WIFI, }, |
| 796 { shill::kTypeWimax, em::NetworkInterface::TYPE_WIMAX, }, | 782 { shill::kTypeWimax, em::NetworkInterface::TYPE_WIMAX, }, |
| 797 { shill::kTypeBluetooth, em::NetworkInterface::TYPE_BLUETOOTH, }, | 783 { shill::kTypeBluetooth, em::NetworkInterface::TYPE_BLUETOOTH, }, |
| 798 { shill::kTypeCellular, em::NetworkInterface::TYPE_CELLULAR, }, | 784 { shill::kTypeCellular, em::NetworkInterface::TYPE_CELLULAR, }, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 for (; type_idx < arraysize(kDeviceTypeMap); ++type_idx) { | 816 for (; type_idx < arraysize(kDeviceTypeMap); ++type_idx) { |
| 831 if ((*device)->type() == kDeviceTypeMap[type_idx].type_string) | 817 if ((*device)->type() == kDeviceTypeMap[type_idx].type_string) |
| 832 break; | 818 break; |
| 833 } | 819 } |
| 834 | 820 |
| 835 // If the type isn't in |kDeviceTypeMap|, the interface is not relevant for | 821 // If the type isn't in |kDeviceTypeMap|, the interface is not relevant for |
| 836 // reporting. This filters out VPN devices. | 822 // reporting. This filters out VPN devices. |
| 837 if (type_idx >= arraysize(kDeviceTypeMap)) | 823 if (type_idx >= arraysize(kDeviceTypeMap)) |
| 838 continue; | 824 continue; |
| 839 | 825 |
| 840 em::NetworkInterface* interface = request->add_network_interface(); | 826 em::NetworkInterface* interface = status->add_network_interface(); |
| 841 interface->set_type(kDeviceTypeMap[type_idx].type_constant); | 827 interface->set_type(kDeviceTypeMap[type_idx].type_constant); |
| 842 if (!(*device)->mac_address().empty()) | 828 if (!(*device)->mac_address().empty()) |
| 843 interface->set_mac_address((*device)->mac_address()); | 829 interface->set_mac_address((*device)->mac_address()); |
| 844 if (!(*device)->meid().empty()) | 830 if (!(*device)->meid().empty()) |
| 845 interface->set_meid((*device)->meid()); | 831 interface->set_meid((*device)->meid()); |
| 846 if (!(*device)->imei().empty()) | 832 if (!(*device)->imei().empty()) |
| 847 interface->set_imei((*device)->imei()); | 833 interface->set_imei((*device)->imei()); |
| 848 if (!(*device)->path().empty()) | 834 if (!(*device)->path().empty()) |
| 849 interface->set_device_path((*device)->path()); | 835 interface->set_device_path((*device)->path()); |
| 850 anything_reported = true; | 836 anything_reported = true; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 870 em::NetworkState::UNKNOWN; | 856 em::NetworkState::UNKNOWN; |
| 871 const std::string connection_state_string(state->connection_state()); | 857 const std::string connection_state_string(state->connection_state()); |
| 872 for (size_t i = 0; i < arraysize(kConnectionStateMap); ++i) { | 858 for (size_t i = 0; i < arraysize(kConnectionStateMap); ++i) { |
| 873 if (connection_state_string == kConnectionStateMap[i].state_string) { | 859 if (connection_state_string == kConnectionStateMap[i].state_string) { |
| 874 connection_state_enum = kConnectionStateMap[i].state_constant; | 860 connection_state_enum = kConnectionStateMap[i].state_constant; |
| 875 break; | 861 break; |
| 876 } | 862 } |
| 877 } | 863 } |
| 878 | 864 |
| 879 // Copy fields from NetworkState into the status report. | 865 // Copy fields from NetworkState into the status report. |
| 880 em::NetworkState* proto_state = request->add_network_state(); | 866 em::NetworkState* proto_state = status->add_network_state(); |
| 881 proto_state->set_connection_state(connection_state_enum); | 867 proto_state->set_connection_state(connection_state_enum); |
| 882 anything_reported = true; | 868 anything_reported = true; |
| 883 | 869 |
| 884 // Report signal strength for wifi connections. | 870 // Report signal strength for wifi connections. |
| 885 if (state->type() == shill::kTypeWifi) { | 871 if (state->type() == shill::kTypeWifi) { |
| 886 // If shill has provided a signal strength, convert it to dBm and store it | 872 // If shill has provided a signal strength, convert it to dBm and store it |
| 887 // in the status report. A signal_strength() of 0 connotes "no signal" | 873 // in the status report. A signal_strength() of 0 connotes "no signal" |
| 888 // rather than "really weak signal", so we only report signal strength if | 874 // rather than "really weak signal", so we only report signal strength if |
| 889 // it is non-zero. | 875 // it is non-zero. |
| 890 if (state->signal_strength()) { | 876 if (state->signal_strength()) { |
| 891 proto_state->set_signal_strength( | 877 proto_state->set_signal_strength( |
| 892 ConvertWifiSignalStrength(state->signal_strength())); | 878 ConvertWifiSignalStrength(state->signal_strength())); |
| 893 } | 879 } |
| 894 } | 880 } |
| 895 | 881 |
| 896 if (!state->device_path().empty()) | 882 if (!state->device_path().empty()) |
| 897 proto_state->set_device_path(state->device_path()); | 883 proto_state->set_device_path(state->device_path()); |
| 898 | 884 |
| 899 if (!state->ip_address().empty()) | 885 if (!state->ip_address().empty()) |
| 900 proto_state->set_ip_address(state->ip_address()); | 886 proto_state->set_ip_address(state->ip_address()); |
| 901 | 887 |
| 902 if (!state->gateway().empty()) | 888 if (!state->gateway().empty()) |
| 903 proto_state->set_gateway(state->gateway()); | 889 proto_state->set_gateway(state->gateway()); |
| 904 } | 890 } |
| 905 return anything_reported; | 891 return anything_reported; |
| 906 } | 892 } |
| 907 | 893 |
| 908 bool DeviceStatusCollector::GetUsers(em::DeviceStatusReportRequest* request) { | 894 bool DeviceStatusCollector::GetUsers(em::DeviceStatusReportRequest* status) { |
| 909 const user_manager::UserList& users = | 895 const user_manager::UserList& users = |
| 910 chromeos::ChromeUserManager::Get()->GetUsers(); | 896 chromeos::ChromeUserManager::Get()->GetUsers(); |
| 911 | 897 |
| 912 bool anything_reported = false; | 898 bool anything_reported = false; |
| 913 for (auto* user : users) { | 899 for (auto* user : users) { |
| 914 // Only users with gaia accounts (regular) are reported. | 900 // Only users with gaia accounts (regular) are reported. |
| 915 if (!user->HasGaiaAccount()) | 901 if (!user->HasGaiaAccount()) |
| 916 continue; | 902 continue; |
| 917 | 903 |
| 918 em::DeviceUser* device_user = request->add_user(); | 904 em::DeviceUser* device_user = status->add_user(); |
| 919 if (chromeos::ChromeUserManager::Get()->ShouldReportUser(user->email())) { | 905 if (chromeos::ChromeUserManager::Get()->ShouldReportUser(user->email())) { |
| 920 device_user->set_type(em::DeviceUser::USER_TYPE_MANAGED); | 906 device_user->set_type(em::DeviceUser::USER_TYPE_MANAGED); |
| 921 device_user->set_email(user->email()); | 907 device_user->set_email(user->email()); |
| 922 } else { | 908 } else { |
| 923 device_user->set_type(em::DeviceUser::USER_TYPE_UNMANAGED); | 909 device_user->set_type(em::DeviceUser::USER_TYPE_UNMANAGED); |
| 924 // Do not report the email address of unmanaged users. | 910 // Do not report the email address of unmanaged users. |
| 925 } | 911 } |
| 926 anything_reported = true; | 912 anything_reported = true; |
| 927 } | 913 } |
| 928 return anything_reported; | 914 return anything_reported; |
| 929 } | 915 } |
| 930 | 916 |
| 931 bool DeviceStatusCollector::GetHardwareStatus( | 917 bool DeviceStatusCollector::GetHardwareStatus( |
| 932 em::DeviceStatusReportRequest* status) { | 918 em::DeviceStatusReportRequest* status, |
| 933 // Add volume info. | 919 scoped_refptr<GetStatusState> state) { |
| 934 status->clear_volume_info(); | 920 // Sample disk volume info in a background thread. |
| 935 for (const em::VolumeInfo& info : volume_info_) { | 921 state->SampleVolumeInfo(volume_info_fetcher_); |
| 936 *status->add_volume_info() = info; | |
| 937 } | |
| 938 | 922 |
| 923 // Sample CPU temperature in a background thread. |
| 924 state->SampleCPUTempInfo(cpu_temp_fetcher_); |
| 925 |
| 926 // Add CPU utilization and free RAM. Note that these stats are sampled in |
| 927 // regular intervals. Unlike CPU temp and volume info these are not one-time |
| 928 // sampled values, hence the difference in logic. |
| 939 status->set_system_ram_total(base::SysInfo::AmountOfPhysicalMemory()); | 929 status->set_system_ram_total(base::SysInfo::AmountOfPhysicalMemory()); |
| 940 status->clear_system_ram_free(); | 930 status->clear_system_ram_free(); |
| 941 status->clear_cpu_utilization_pct(); | 931 status->clear_cpu_utilization_pct(); |
| 942 for (const ResourceUsage& usage : resource_usage_) { | 932 for (const ResourceUsage& usage : resource_usage_) { |
| 943 status->add_cpu_utilization_pct(usage.cpu_usage_percent); | 933 status->add_cpu_utilization_pct(usage.cpu_usage_percent); |
| 944 status->add_system_ram_free(usage.bytes_of_ram_free); | 934 status->add_system_ram_free(usage.bytes_of_ram_free); |
| 945 } | 935 } |
| 946 | |
| 947 // Add CPU temp info. | |
| 948 status->clear_cpu_temp_info(); | |
| 949 for (const em::CPUTempInfo& info : cpu_temp_info_) { | |
| 950 *status->add_cpu_temp_info() = info; | |
| 951 } | |
| 952 return true; | 936 return true; |
| 953 } | 937 } |
| 954 | 938 |
| 955 bool DeviceStatusCollector::GetOsUpdateStatus( | 939 bool DeviceStatusCollector::GetOsUpdateStatus( |
| 956 em::DeviceStatusReportRequest* status) { | 940 em::DeviceStatusReportRequest* status) { |
| 957 const base::Version platform_version(GetPlatformVersion()); | 941 const base::Version platform_version(GetPlatformVersion()); |
| 958 if (!platform_version.IsValid()) | 942 if (!platform_version.IsValid()) |
| 959 return false; | 943 return false; |
| 960 | 944 |
| 961 const std::string required_platform_version_string = | 945 const std::string required_platform_version_string = |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 em::OsUpdateStatus::OS_IMAGE_DOWNLOAD_NOT_STARTED); | 987 em::OsUpdateStatus::OS_IMAGE_DOWNLOAD_NOT_STARTED); |
| 1004 } | 988 } |
| 1005 | 989 |
| 1006 return true; | 990 return true; |
| 1007 } | 991 } |
| 1008 | 992 |
| 1009 bool DeviceStatusCollector::GetRunningKioskApp( | 993 bool DeviceStatusCollector::GetRunningKioskApp( |
| 1010 em::DeviceStatusReportRequest* status) { | 994 em::DeviceStatusReportRequest* status) { |
| 1011 // Must be on creation thread since some stats are written to in that thread | 995 // Must be on creation thread since some stats are written to in that thread |
| 1012 // and accessing them from another thread would lead to race conditions. | 996 // and accessing them from another thread would lead to race conditions. |
| 1013 CHECK(content::BrowserThread::CurrentlyOn(creation_thread_)); | 997 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1014 | 998 |
| 1015 std::unique_ptr<const DeviceLocalAccount> account = | 999 std::unique_ptr<const DeviceLocalAccount> account = |
| 1016 GetAutoLaunchedKioskSessionInfo(); | 1000 GetAutoLaunchedKioskSessionInfo(); |
| 1017 // Only generate running kiosk app reports if we are in an auto-launched kiosk | 1001 // Only generate running kiosk app reports if we are in an auto-launched kiosk |
| 1018 // session. | 1002 // session. |
| 1019 if (!account) | 1003 if (!account) |
| 1020 return false; | 1004 return false; |
| 1021 | 1005 |
| 1022 em::AppStatus* running_kiosk_app = status->mutable_running_kiosk_app(); | 1006 em::AppStatus* running_kiosk_app = status->mutable_running_kiosk_app(); |
| 1023 running_kiosk_app->set_app_id(account->kiosk_app_id); | 1007 running_kiosk_app->set_app_id(account->kiosk_app_id); |
| 1024 | 1008 |
| 1025 const std::string app_version = GetAppVersion(account->kiosk_app_id); | 1009 const std::string app_version = GetAppVersion(account->kiosk_app_id); |
| 1026 if (app_version.empty()) { | 1010 if (app_version.empty()) { |
| 1027 DLOG(ERROR) << "Unable to get version for extension: " | 1011 DLOG(ERROR) << "Unable to get version for extension: " |
| 1028 << account->kiosk_app_id; | 1012 << account->kiosk_app_id; |
| 1029 } else { | 1013 } else { |
| 1030 running_kiosk_app->set_extension_version(app_version); | 1014 running_kiosk_app->set_extension_version(app_version); |
| 1031 } | 1015 } |
| 1032 | 1016 |
| 1033 chromeos::KioskAppManager::App app_info; | 1017 chromeos::KioskAppManager::App app_info; |
| 1034 if (chromeos::KioskAppManager::Get()->GetApp(account->kiosk_app_id, | 1018 if (chromeos::KioskAppManager::Get()->GetApp(account->kiosk_app_id, |
| 1035 &app_info)) { | 1019 &app_info)) { |
| 1036 running_kiosk_app->set_required_platform_version( | 1020 running_kiosk_app->set_required_platform_version( |
| 1037 app_info.required_platform_version); | 1021 app_info.required_platform_version); |
| 1038 } | 1022 } |
| 1039 return true; | 1023 return true; |
| 1040 } | 1024 } |
| 1041 | 1025 |
| 1042 void DeviceStatusCollector::GetDeviceStatusAsync( | 1026 void DeviceStatusCollector::GetDeviceAndSessionStatusAsync( |
| 1043 const DeviceStatusCallback& response) { | 1027 const StatusCallback& response) { |
| 1044 // Must be on creation thread since some stats are written to in that thread | 1028 // Must be on creation thread since some stats are written to in that thread |
| 1045 // and accessing them from another thread would lead to race conditions. | 1029 // and accessing them from another thread would lead to race conditions. |
| 1046 CHECK(content::BrowserThread::CurrentlyOn(creation_thread_)); | 1030 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1047 | 1031 |
| 1048 std::unique_ptr<em::DeviceStatusReportRequest> status = | 1032 // Some of the data we're collecting is gathered in background threads. |
| 1049 base::MakeUnique<em::DeviceStatusReportRequest>(); | 1033 // This object keeps track of the state of each async request. |
| 1050 bool got_status = false; | 1034 scoped_refptr<GetStatusState> state( |
| 1035 new GetStatusState(task_runner_, response)); |
| 1036 |
| 1037 // Gather device status (might queue some async queries) |
| 1038 GetDeviceStatus(state); |
| 1039 |
| 1040 // Gather device status (might queue some async queries) |
| 1041 GetSessionStatus(state); |
| 1042 |
| 1043 // If there are no outstanding async queries, e.g. from GetHardwareStatus(), |
| 1044 // the destructor of |state| calls |response|. If there are async queries, the |
| 1045 // queries hold references to |state|, so that |state| is only destroyed when |
| 1046 // the last async query has finished. |
| 1047 } |
| 1048 |
| 1049 void DeviceStatusCollector::GetDeviceStatus( |
| 1050 scoped_refptr<GetStatusState> state) { |
| 1051 em::DeviceStatusReportRequest* status = state->device_status(); |
| 1052 bool anything_reported = false; |
| 1051 | 1053 |
| 1052 if (report_activity_times_) | 1054 if (report_activity_times_) |
| 1053 got_status |= GetActivityTimes(status.get()); | 1055 anything_reported |= GetActivityTimes(status); |
| 1054 | 1056 |
| 1055 if (report_version_info_) | 1057 if (report_version_info_) |
| 1056 got_status |= GetVersionInfo(status.get()); | 1058 anything_reported |= GetVersionInfo(status); |
| 1057 | 1059 |
| 1058 if (report_boot_mode_) | 1060 if (report_boot_mode_) |
| 1059 got_status |= GetBootMode(status.get()); | 1061 anything_reported |= GetBootMode(status); |
| 1060 | |
| 1061 if (report_location_) | |
| 1062 got_status |= GetLocation(status.get()); | |
| 1063 | 1062 |
| 1064 if (report_network_interfaces_) | 1063 if (report_network_interfaces_) |
| 1065 got_status |= GetNetworkInterfaces(status.get()); | 1064 anything_reported |= GetNetworkInterfaces(status); |
| 1066 | 1065 |
| 1067 if (report_users_) | 1066 if (report_users_) |
| 1068 got_status |= GetUsers(status.get()); | 1067 anything_reported |= GetUsers(status); |
| 1069 | 1068 |
| 1070 if (report_hardware_status_) | 1069 if (report_hardware_status_) |
| 1071 got_status |= GetHardwareStatus(status.get()); | 1070 anything_reported |= GetHardwareStatus(status, state); |
| 1072 | 1071 |
| 1073 if (report_os_update_status_) | 1072 if (report_os_update_status_) |
| 1074 got_status |= GetOsUpdateStatus(status.get()); | 1073 anything_reported |= GetOsUpdateStatus(status); |
| 1075 | 1074 |
| 1076 if (report_running_kiosk_app_) | 1075 if (report_running_kiosk_app_) |
| 1077 got_status |= GetRunningKioskApp(status.get()); | 1076 anything_reported |= GetRunningKioskApp(status); |
| 1078 | 1077 |
| 1079 // Wipe pointer if we didn't actually add any data. | 1078 // Wipe pointer if we didn't actually add any data. |
| 1080 if (!got_status) | 1079 if (!anything_reported) |
| 1081 status.reset(); | 1080 state->ResetDeviceStatus(); |
| 1082 | |
| 1083 content::BrowserThread::PostTask(creation_thread_, FROM_HERE, | |
| 1084 base::Bind(response, base::Passed(&status))); | |
| 1085 } | 1081 } |
| 1086 | 1082 |
| 1087 void DeviceStatusCollector::GetDeviceSessionStatusAsync( | 1083 void DeviceStatusCollector::GetSessionStatus( |
| 1088 const DeviceSessionStatusCallback& response) { | 1084 scoped_refptr<GetStatusState> state) { |
| 1089 // Only generate session status reports if session status reporting is | 1085 em::SessionStatusReportRequest* status = state->session_status(); |
| 1090 // enabled. | 1086 bool anything_reported = false; |
| 1091 if (!report_session_status_) { | |
| 1092 content::BrowserThread::PostTask(creation_thread_, FROM_HERE, | |
| 1093 base::Bind(response, nullptr)); | |
| 1094 return; | |
| 1095 } | |
| 1096 | 1087 |
| 1088 if (report_session_status_) |
| 1089 anything_reported |= GetAccountStatus(status); |
| 1090 |
| 1091 // Wipe pointer if we didn't actually add any data. |
| 1092 if (!anything_reported) |
| 1093 state->ResetSessionStatus(); |
| 1094 } |
| 1095 |
| 1096 bool DeviceStatusCollector::GetAccountStatus( |
| 1097 em::SessionStatusReportRequest* status) { |
| 1097 std::unique_ptr<const DeviceLocalAccount> account = | 1098 std::unique_ptr<const DeviceLocalAccount> account = |
| 1098 GetAutoLaunchedKioskSessionInfo(); | 1099 GetAutoLaunchedKioskSessionInfo(); |
| 1099 // Only generate session status reports if we are in an auto-launched kiosk | 1100 if (!account) |
| 1100 // session. | 1101 return false; |
| 1101 if (!account) { | |
| 1102 content::BrowserThread::PostTask(creation_thread_, FROM_HERE, | |
| 1103 base::Bind(response, nullptr)); | |
| 1104 return; | |
| 1105 } | |
| 1106 | |
| 1107 std::unique_ptr<em::SessionStatusReportRequest> status = | |
| 1108 base::MakeUnique<em::SessionStatusReportRequest>(); | |
| 1109 | 1102 |
| 1110 // Get the account ID associated with this user. | 1103 // Get the account ID associated with this user. |
| 1111 status->set_device_local_account_id(account->account_id); | 1104 status->set_device_local_account_id(account->account_id); |
| 1112 em::AppStatus* app_status = status->add_installed_apps(); | 1105 em::AppStatus* app_status = status->add_installed_apps(); |
| 1113 app_status->set_app_id(account->kiosk_app_id); | 1106 app_status->set_app_id(account->kiosk_app_id); |
| 1114 | 1107 |
| 1115 // Look up the app and get the version. | 1108 // Look up the app and get the version. |
| 1116 const std::string app_version = GetAppVersion(account->kiosk_app_id); | 1109 const std::string app_version = GetAppVersion(account->kiosk_app_id); |
| 1117 if (app_version.empty()) { | 1110 if (app_version.empty()) { |
| 1118 DLOG(ERROR) << "Unable to get version for extension: " | 1111 DLOG(ERROR) << "Unable to get version for extension: " |
| 1119 << account->kiosk_app_id; | 1112 << account->kiosk_app_id; |
| 1120 } else { | 1113 } else { |
| 1121 app_status->set_extension_version(app_version); | 1114 app_status->set_extension_version(app_version); |
| 1122 } | 1115 } |
| 1123 | 1116 |
| 1124 content::BrowserThread::PostTask(creation_thread_, FROM_HERE, | 1117 return true; |
| 1125 base::Bind(response, base::Passed(&status))); | |
| 1126 } | 1118 } |
| 1127 | 1119 |
| 1128 std::string DeviceStatusCollector::GetAppVersion( | 1120 std::string DeviceStatusCollector::GetAppVersion( |
| 1129 const std::string& kiosk_app_id) { | 1121 const std::string& kiosk_app_id) { |
| 1130 Profile* const profile = | 1122 Profile* const profile = |
| 1131 chromeos::ProfileHelper::Get()->GetProfileByUser( | 1123 chromeos::ProfileHelper::Get()->GetProfileByUser( |
| 1132 user_manager::UserManager::Get()->GetActiveUser()); | 1124 user_manager::UserManager::Get()->GetActiveUser()); |
| 1133 const extensions::ExtensionRegistry* const registry = | 1125 const extensions::ExtensionRegistry* const registry = |
| 1134 extensions::ExtensionRegistry::Get(profile); | 1126 extensions::ExtensionRegistry::Get(profile); |
| 1135 const extensions::Extension* const extension = registry->GetExtensionById( | 1127 const extensions::Extension* const extension = registry->GetExtensionById( |
| 1136 kiosk_app_id, extensions::ExtensionRegistry::EVERYTHING); | 1128 kiosk_app_id, extensions::ExtensionRegistry::EVERYTHING); |
| 1137 if (!extension) | 1129 if (!extension) |
| 1138 return std::string(); | 1130 return std::string(); |
| 1139 return extension->VersionString(); | 1131 return extension->VersionString(); |
| 1140 } | 1132 } |
| 1141 | 1133 |
| 1142 void DeviceStatusCollector::OnSubmittedSuccessfully() { | 1134 void DeviceStatusCollector::OnSubmittedSuccessfully() { |
| 1143 TrimStoredActivityPeriods(last_reported_day_, duration_for_last_reported_day_, | 1135 TrimStoredActivityPeriods(last_reported_day_, duration_for_last_reported_day_, |
| 1144 std::numeric_limits<int64_t>::max()); | 1136 std::numeric_limits<int64_t>::max()); |
| 1145 } | 1137 } |
| 1146 | 1138 |
| 1147 void DeviceStatusCollector::OnOSVersion(const std::string& version) { | 1139 void DeviceStatusCollector::OnOSVersion(const std::string& version) { |
| 1148 os_version_ = version; | 1140 os_version_ = version; |
| 1149 } | 1141 } |
| 1150 | 1142 |
| 1151 void DeviceStatusCollector::OnOSFirmware(const std::string& version) { | 1143 void DeviceStatusCollector::OnOSFirmware(const std::string& version) { |
| 1152 firmware_version_ = version; | 1144 firmware_version_ = version; |
| 1153 } | 1145 } |
| 1154 | 1146 |
| 1155 void DeviceStatusCollector::ScheduleGeolocationUpdateRequest() { | |
| 1156 if (geolocation_update_timer_.IsRunning() || geolocation_update_in_progress_) | |
| 1157 return; | |
| 1158 | |
| 1159 if (position_.Validate()) { | |
| 1160 TimeDelta elapsed = GetCurrentTime() - position_.timestamp; | |
| 1161 TimeDelta interval = | |
| 1162 TimeDelta::FromSeconds(kGeolocationPollIntervalSeconds); | |
| 1163 if (elapsed <= interval) { | |
| 1164 geolocation_update_timer_.Start( | |
| 1165 FROM_HERE, | |
| 1166 interval - elapsed, | |
| 1167 this, | |
| 1168 &DeviceStatusCollector::ScheduleGeolocationUpdateRequest); | |
| 1169 return; | |
| 1170 } | |
| 1171 } | |
| 1172 | |
| 1173 geolocation_update_in_progress_ = true; | |
| 1174 if (location_update_requester_.is_null()) { | |
| 1175 geolocation_subscription_ = | |
| 1176 device::GeolocationProvider::GetInstance()->AddLocationUpdateCallback( | |
| 1177 base::Bind(&DeviceStatusCollector::ReceiveGeolocationUpdate, | |
| 1178 weak_factory_.GetWeakPtr()), | |
| 1179 true); | |
| 1180 } else { | |
| 1181 location_update_requester_.Run(base::Bind( | |
| 1182 &DeviceStatusCollector::ReceiveGeolocationUpdate, | |
| 1183 weak_factory_.GetWeakPtr())); | |
| 1184 } | |
| 1185 } | |
| 1186 | |
| 1187 void DeviceStatusCollector::ReceiveGeolocationUpdate( | |
| 1188 const device::Geoposition& position) { | |
| 1189 geolocation_update_in_progress_ = false; | |
| 1190 | |
| 1191 // Ignore update if device location reporting has since been disabled. | |
| 1192 if (!report_location_) | |
| 1193 return; | |
| 1194 | |
| 1195 if (position.Validate()) { | |
| 1196 position_ = position; | |
| 1197 base::DictionaryValue location; | |
| 1198 location.SetDouble(kLatitude, position.latitude); | |
| 1199 location.SetDouble(kLongitude, position.longitude); | |
| 1200 location.SetDouble(kAltitude, position.altitude); | |
| 1201 location.SetDouble(kAccuracy, position.accuracy); | |
| 1202 location.SetDouble(kAltitudeAccuracy, position.altitude_accuracy); | |
| 1203 location.SetDouble(kHeading, position.heading); | |
| 1204 location.SetDouble(kSpeed, position.speed); | |
| 1205 location.SetString(kTimestamp, | |
| 1206 base::Int64ToString(position.timestamp.ToInternalValue())); | |
| 1207 local_state_->Set(prefs::kDeviceLocation, location); | |
| 1208 } | |
| 1209 | |
| 1210 ScheduleGeolocationUpdateRequest(); | |
| 1211 } | |
| 1212 | |
| 1213 void DeviceStatusCollector::ReceiveVolumeInfo( | |
| 1214 const std::vector<em::VolumeInfo>& info) { | |
| 1215 if (report_hardware_status_) | |
| 1216 volume_info_ = info; | |
| 1217 } | |
| 1218 | |
| 1219 } // namespace policy | 1147 } // namespace policy |
| OLD | NEW |