| 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 <stdint.h> | 8 #include <stdint.h> |
| 9 #include <sys/statvfs.h> |
| 8 #include <cstdio> | 10 #include <cstdio> |
| 9 #include <limits> | 11 #include <limits> |
| 10 #include <sstream> | 12 #include <sstream> |
| 11 #include <sys/statvfs.h> | |
| 12 | 13 |
| 13 #include "base/bind.h" | 14 #include "base/bind.h" |
| 14 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
| 15 #include "base/files/file_enumerator.h" | 16 #include "base/files/file_enumerator.h" |
| 16 #include "base/files/file_util.h" | 17 #include "base/files/file_util.h" |
| 17 #include "base/format_macros.h" | 18 #include "base/format_macros.h" |
| 18 #include "base/location.h" | 19 #include "base/location.h" |
| 19 #include "base/logging.h" | 20 #include "base/logging.h" |
| 21 #include "base/macros.h" |
| 20 #include "base/memory/scoped_ptr.h" | 22 #include "base/memory/scoped_ptr.h" |
| 21 #include "base/posix/eintr_wrapper.h" | 23 #include "base/posix/eintr_wrapper.h" |
| 22 #include "base/prefs/pref_registry_simple.h" | 24 #include "base/prefs/pref_registry_simple.h" |
| 23 #include "base/prefs/pref_service.h" | 25 #include "base/prefs/pref_service.h" |
| 24 #include "base/prefs/scoped_user_pref_update.h" | 26 #include "base/prefs/scoped_user_pref_update.h" |
| 25 #include "base/strings/string_number_conversions.h" | 27 #include "base/strings/string_number_conversions.h" |
| 26 #include "base/strings/string_util.h" | 28 #include "base/strings/string_util.h" |
| 27 #include "base/sys_info.h" | 29 #include "base/sys_info.h" |
| 28 #include "base/task_runner_util.h" | 30 #include "base/task_runner_util.h" |
| 29 #include "base/values.h" | 31 #include "base/values.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 const char kProcStat[] = "/proc/stat"; | 91 const char kProcStat[] = "/proc/stat"; |
| 90 | 92 |
| 91 // The location we read our CPU temperature and channel label from. | 93 // The location we read our CPU temperature and channel label from. |
| 92 const char kHwmonDir[] = "/sys/class/hwmon/"; | 94 const char kHwmonDir[] = "/sys/class/hwmon/"; |
| 93 const char kDeviceDir[] = "device"; | 95 const char kDeviceDir[] = "device"; |
| 94 const char kHwmonDirectoryPattern[] = "hwmon*"; | 96 const char kHwmonDirectoryPattern[] = "hwmon*"; |
| 95 const char kCPUTempFilePattern[] = "temp*_input"; | 97 const char kCPUTempFilePattern[] = "temp*_input"; |
| 96 | 98 |
| 97 // Determine the day key (milliseconds since epoch for corresponding day in UTC) | 99 // Determine the day key (milliseconds since epoch for corresponding day in UTC) |
| 98 // for a given |timestamp|. | 100 // for a given |timestamp|. |
| 99 int64 TimestampToDayKey(Time timestamp) { | 101 int64_t TimestampToDayKey(Time timestamp) { |
| 100 Time::Exploded exploded; | 102 Time::Exploded exploded; |
| 101 timestamp.LocalMidnight().LocalExplode(&exploded); | 103 timestamp.LocalMidnight().LocalExplode(&exploded); |
| 102 return (Time::FromUTCExploded(exploded) - Time::UnixEpoch()).InMilliseconds(); | 104 return (Time::FromUTCExploded(exploded) - Time::UnixEpoch()).InMilliseconds(); |
| 103 } | 105 } |
| 104 | 106 |
| 105 // Helper function (invoked via blocking pool) to fetch information about | 107 // Helper function (invoked via blocking pool) to fetch information about |
| 106 // mounted disks. | 108 // mounted disks. |
| 107 std::vector<em::VolumeInfo> GetVolumeInfo( | 109 std::vector<em::VolumeInfo> GetVolumeInfo( |
| 108 const std::vector<std::string>& mount_points) { | 110 const std::vector<std::string>& mount_points) { |
| 109 std::vector<em::VolumeInfo> result; | 111 std::vector<em::VolumeInfo> result; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 | 183 |
| 182 // Read label. | 184 // Read label. |
| 183 std::string label; | 185 std::string label; |
| 184 if (!base::PathExists(base::FilePath(label_path)) || | 186 if (!base::PathExists(base::FilePath(label_path)) || |
| 185 !base::ReadFileToString(base::FilePath(label_path), &label)) { | 187 !base::ReadFileToString(base::FilePath(label_path), &label)) { |
| 186 label = std::string(); | 188 label = std::string(); |
| 187 } | 189 } |
| 188 | 190 |
| 189 // Read temperature in millidegree Celsius. | 191 // Read temperature in millidegree Celsius. |
| 190 std::string temperature_string; | 192 std::string temperature_string; |
| 191 int32 temperature = 0; | 193 int32_t temperature = 0; |
| 192 if (base::ReadFileToString(temperature_path, &temperature_string) && | 194 if (base::ReadFileToString(temperature_path, &temperature_string) && |
| 193 sscanf(temperature_string.c_str(), "%d", &temperature) == 1) { | 195 sscanf(temperature_string.c_str(), "%d", &temperature) == 1) { |
| 194 // CPU temp in millidegree Celsius to Celsius | 196 // CPU temp in millidegree Celsius to Celsius |
| 195 temperature /= 1000; | 197 temperature /= 1000; |
| 196 | 198 |
| 197 em::CPUTempInfo info; | 199 em::CPUTempInfo info; |
| 198 info.set_cpu_label(label); | 200 info.set_cpu_label(label); |
| 199 info.set_cpu_temp(temperature); | 201 info.set_cpu_temp(temperature); |
| 200 contents.push_back(info); | 202 contents.push_back(info); |
| 201 } else { | 203 } else { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 hardware_status_subscription_ = cros_settings_->AddSettingsObserver( | 307 hardware_status_subscription_ = cros_settings_->AddSettingsObserver( |
| 306 chromeos::kReportDeviceHardwareStatus, callback); | 308 chromeos::kReportDeviceHardwareStatus, callback); |
| 307 session_status_subscription_ = cros_settings_->AddSettingsObserver( | 309 session_status_subscription_ = cros_settings_->AddSettingsObserver( |
| 308 chromeos::kReportDeviceSessionStatus, callback); | 310 chromeos::kReportDeviceSessionStatus, callback); |
| 309 | 311 |
| 310 // The last known location is persisted in local state. This makes location | 312 // The last known location is persisted in local state. This makes location |
| 311 // information available immediately upon startup and avoids the need to | 313 // information available immediately upon startup and avoids the need to |
| 312 // reacquire the location on every user session change or browser crash. | 314 // reacquire the location on every user session change or browser crash. |
| 313 content::Geoposition position; | 315 content::Geoposition position; |
| 314 std::string timestamp_str; | 316 std::string timestamp_str; |
| 315 int64 timestamp; | 317 int64_t timestamp; |
| 316 const base::DictionaryValue* location = | 318 const base::DictionaryValue* location = |
| 317 local_state_->GetDictionary(prefs::kDeviceLocation); | 319 local_state_->GetDictionary(prefs::kDeviceLocation); |
| 318 if (location->GetDouble(kLatitude, &position.latitude) && | 320 if (location->GetDouble(kLatitude, &position.latitude) && |
| 319 location->GetDouble(kLongitude, &position.longitude) && | 321 location->GetDouble(kLongitude, &position.longitude) && |
| 320 location->GetDouble(kAltitude, &position.altitude) && | 322 location->GetDouble(kAltitude, &position.altitude) && |
| 321 location->GetDouble(kAccuracy, &position.accuracy) && | 323 location->GetDouble(kAccuracy, &position.accuracy) && |
| 322 location->GetDouble(kAltitudeAccuracy, &position.altitude_accuracy) && | 324 location->GetDouble(kAltitudeAccuracy, &position.altitude_accuracy) && |
| 323 location->GetDouble(kHeading, &position.heading) && | 325 location->GetDouble(kHeading, &position.heading) && |
| 324 location->GetDouble(kSpeed, &position.speed) && | 326 location->GetDouble(kSpeed, &position.speed) && |
| 325 location->GetString(kTimestamp, ×tamp_str) && | 327 location->GetString(kTimestamp, ×tamp_str) && |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 // Remove all out-of-range activity times from the local store. | 442 // Remove all out-of-range activity times from the local store. |
| 441 void DeviceStatusCollector::PruneStoredActivityPeriods(Time base_time) { | 443 void DeviceStatusCollector::PruneStoredActivityPeriods(Time base_time) { |
| 442 Time min_time = | 444 Time min_time = |
| 443 base_time - TimeDelta::FromDays(max_stored_past_activity_days_); | 445 base_time - TimeDelta::FromDays(max_stored_past_activity_days_); |
| 444 Time max_time = | 446 Time max_time = |
| 445 base_time + TimeDelta::FromDays(max_stored_future_activity_days_); | 447 base_time + TimeDelta::FromDays(max_stored_future_activity_days_); |
| 446 TrimStoredActivityPeriods(TimestampToDayKey(min_time), 0, | 448 TrimStoredActivityPeriods(TimestampToDayKey(min_time), 0, |
| 447 TimestampToDayKey(max_time)); | 449 TimestampToDayKey(max_time)); |
| 448 } | 450 } |
| 449 | 451 |
| 450 void DeviceStatusCollector::TrimStoredActivityPeriods(int64 min_day_key, | 452 void DeviceStatusCollector::TrimStoredActivityPeriods(int64_t min_day_key, |
| 451 int min_day_trim_duration, | 453 int min_day_trim_duration, |
| 452 int64 max_day_key) { | 454 int64_t max_day_key) { |
| 453 const base::DictionaryValue* activity_times = | 455 const base::DictionaryValue* activity_times = |
| 454 local_state_->GetDictionary(prefs::kDeviceActivityTimes); | 456 local_state_->GetDictionary(prefs::kDeviceActivityTimes); |
| 455 | 457 |
| 456 scoped_ptr<base::DictionaryValue> copy(activity_times->DeepCopy()); | 458 scoped_ptr<base::DictionaryValue> copy(activity_times->DeepCopy()); |
| 457 for (base::DictionaryValue::Iterator it(*activity_times); !it.IsAtEnd(); | 459 for (base::DictionaryValue::Iterator it(*activity_times); !it.IsAtEnd(); |
| 458 it.Advance()) { | 460 it.Advance()) { |
| 459 int64 timestamp; | 461 int64_t timestamp; |
| 460 if (base::StringToInt64(it.key(), ×tamp)) { | 462 if (base::StringToInt64(it.key(), ×tamp)) { |
| 461 // Remove data that is too old, or too far in the future. | 463 // Remove data that is too old, or too far in the future. |
| 462 if (timestamp >= min_day_key && timestamp < max_day_key) { | 464 if (timestamp >= min_day_key && timestamp < max_day_key) { |
| 463 if (timestamp == min_day_key) { | 465 if (timestamp == min_day_key) { |
| 464 int new_activity_duration = 0; | 466 int new_activity_duration = 0; |
| 465 if (it.value().GetAsInteger(&new_activity_duration)) { | 467 if (it.value().GetAsInteger(&new_activity_duration)) { |
| 466 new_activity_duration = | 468 new_activity_duration = |
| 467 std::max(new_activity_duration - min_day_trim_duration, 0); | 469 std::max(new_activity_duration - min_day_trim_duration, 0); |
| 468 } | 470 } |
| 469 copy->SetInteger(it.key(), new_activity_duration); | 471 copy->SetInteger(it.key(), new_activity_duration); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 481 DCHECK(start < end); | 483 DCHECK(start < end); |
| 482 | 484 |
| 483 // Maintain the list of active periods in a local_state pref. | 485 // Maintain the list of active periods in a local_state pref. |
| 484 DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes); | 486 DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes); |
| 485 base::DictionaryValue* activity_times = update.Get(); | 487 base::DictionaryValue* activity_times = update.Get(); |
| 486 | 488 |
| 487 // Assign the period to day buckets in local time. | 489 // Assign the period to day buckets in local time. |
| 488 Time midnight = start.LocalMidnight(); | 490 Time midnight = start.LocalMidnight(); |
| 489 while (midnight < end) { | 491 while (midnight < end) { |
| 490 midnight += TimeDelta::FromDays(1); | 492 midnight += TimeDelta::FromDays(1); |
| 491 int64 activity = (std::min(end, midnight) - start).InMilliseconds(); | 493 int64_t activity = (std::min(end, midnight) - start).InMilliseconds(); |
| 492 std::string day_key = base::Int64ToString(TimestampToDayKey(start)); | 494 std::string day_key = base::Int64ToString(TimestampToDayKey(start)); |
| 493 int previous_activity = 0; | 495 int previous_activity = 0; |
| 494 activity_times->GetInteger(day_key, &previous_activity); | 496 activity_times->GetInteger(day_key, &previous_activity); |
| 495 activity_times->SetInteger(day_key, previous_activity + activity); | 497 activity_times->SetInteger(day_key, previous_activity + activity); |
| 496 start = midnight; | 498 start = midnight; |
| 497 } | 499 } |
| 498 } | 500 } |
| 499 | 501 |
| 500 void DeviceStatusCollector::ClearCachedHardwareStatus() { | 502 void DeviceStatusCollector::ClearCachedHardwareStatus() { |
| 501 volume_info_.clear(); | 503 volume_info_.clear(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 // The CPU usage values in /proc/stat are measured in the imprecise unit | 598 // The CPU usage values in /proc/stat are measured in the imprecise unit |
| 597 // "jiffies", but we just care about the relative magnitude of "active" vs | 599 // "jiffies", but we just care about the relative magnitude of "active" vs |
| 598 // "idle" so the exact value of a jiffy is irrelevant. | 600 // "idle" so the exact value of a jiffy is irrelevant. |
| 599 // | 601 // |
| 600 // An example value for this line: | 602 // An example value for this line: |
| 601 // | 603 // |
| 602 // cpu 123 456 789 012 345 678 | 604 // cpu 123 456 789 012 345 678 |
| 603 // | 605 // |
| 604 // We only care about the first four numbers: user_time, nice_time, | 606 // We only care about the first four numbers: user_time, nice_time, |
| 605 // sys_time, and idle_time. | 607 // sys_time, and idle_time. |
| 606 uint64 user = 0, nice = 0, system = 0, idle = 0; | 608 uint64_t user = 0, nice = 0, system = 0, idle = 0; |
| 607 int vals = sscanf(stats.c_str(), | 609 int vals = sscanf(stats.c_str(), |
| 608 "cpu %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, &user, | 610 "cpu %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, &user, |
| 609 &nice, &system, &idle); | 611 &nice, &system, &idle); |
| 610 DCHECK_EQ(4, vals); | 612 DCHECK_EQ(4, vals); |
| 611 | 613 |
| 612 // The values returned from /proc/stat are cumulative totals, so calculate | 614 // The values returned from /proc/stat are cumulative totals, so calculate |
| 613 // the difference between the last sample and this one. | 615 // the difference between the last sample and this one. |
| 614 uint64 active = user + nice + system; | 616 uint64_t active = user + nice + system; |
| 615 uint64 total = active + idle; | 617 uint64_t total = active + idle; |
| 616 uint64 last_total = last_cpu_active_ + last_cpu_idle_; | 618 uint64_t last_total = last_cpu_active_ + last_cpu_idle_; |
| 617 DCHECK_GE(active, last_cpu_active_); | 619 DCHECK_GE(active, last_cpu_active_); |
| 618 DCHECK_GE(idle, last_cpu_idle_); | 620 DCHECK_GE(idle, last_cpu_idle_); |
| 619 DCHECK_GE(total, last_total); | 621 DCHECK_GE(total, last_total); |
| 620 | 622 |
| 621 if ((total - last_total) > 0) { | 623 if ((total - last_total) > 0) { |
| 622 cpu_usage_percent = | 624 cpu_usage_percent = |
| 623 (100 * (active - last_cpu_active_)) / (total - last_total); | 625 (100 * (active - last_cpu_active_)) / (total - last_total); |
| 624 } | 626 } |
| 625 last_cpu_active_ = active; | 627 last_cpu_active_ = active; |
| 626 last_cpu_idle_ = idle; | 628 last_cpu_idle_ = idle; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 648 cpu_temp_info_ = info; | 650 cpu_temp_info_ = info; |
| 649 } | 651 } |
| 650 | 652 |
| 651 void DeviceStatusCollector::GetActivityTimes( | 653 void DeviceStatusCollector::GetActivityTimes( |
| 652 em::DeviceStatusReportRequest* request) { | 654 em::DeviceStatusReportRequest* request) { |
| 653 DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes); | 655 DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes); |
| 654 base::DictionaryValue* activity_times = update.Get(); | 656 base::DictionaryValue* activity_times = update.Get(); |
| 655 | 657 |
| 656 for (base::DictionaryValue::Iterator it(*activity_times); !it.IsAtEnd(); | 658 for (base::DictionaryValue::Iterator it(*activity_times); !it.IsAtEnd(); |
| 657 it.Advance()) { | 659 it.Advance()) { |
| 658 int64 start_timestamp; | 660 int64_t start_timestamp; |
| 659 int activity_milliseconds; | 661 int activity_milliseconds; |
| 660 if (base::StringToInt64(it.key(), &start_timestamp) && | 662 if (base::StringToInt64(it.key(), &start_timestamp) && |
| 661 it.value().GetAsInteger(&activity_milliseconds)) { | 663 it.value().GetAsInteger(&activity_milliseconds)) { |
| 662 // This is correct even when there are leap seconds, because when a leap | 664 // This is correct even when there are leap seconds, because when a leap |
| 663 // second occurs, two consecutive seconds have the same timestamp. | 665 // second occurs, two consecutive seconds have the same timestamp. |
| 664 int64 end_timestamp = start_timestamp + Time::kMillisecondsPerDay; | 666 int64_t end_timestamp = start_timestamp + Time::kMillisecondsPerDay; |
| 665 | 667 |
| 666 em::ActiveTimePeriod* active_period = request->add_active_period(); | 668 em::ActiveTimePeriod* active_period = request->add_active_period(); |
| 667 em::TimePeriod* period = active_period->mutable_time_period(); | 669 em::TimePeriod* period = active_period->mutable_time_period(); |
| 668 period->set_start_timestamp(start_timestamp); | 670 period->set_start_timestamp(start_timestamp); |
| 669 period->set_end_timestamp(end_timestamp); | 671 period->set_end_timestamp(end_timestamp); |
| 670 active_period->set_active_duration(activity_milliseconds); | 672 active_period->set_active_duration(activity_milliseconds); |
| 671 if (start_timestamp >= last_reported_day_) { | 673 if (start_timestamp >= last_reported_day_) { |
| 672 last_reported_day_ = start_timestamp; | 674 last_reported_day_ = start_timestamp; |
| 673 duration_for_last_reported_day_ = activity_milliseconds; | 675 duration_for_last_reported_day_ = activity_milliseconds; |
| 674 } | 676 } |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 extensions::ExtensionRegistry::Get(profile); | 973 extensions::ExtensionRegistry::Get(profile); |
| 972 const extensions::Extension* const extension = registry->GetExtensionById( | 974 const extensions::Extension* const extension = registry->GetExtensionById( |
| 973 kiosk_app_id, extensions::ExtensionRegistry::EVERYTHING); | 975 kiosk_app_id, extensions::ExtensionRegistry::EVERYTHING); |
| 974 if (!extension) | 976 if (!extension) |
| 975 return std::string(); | 977 return std::string(); |
| 976 return extension->VersionString(); | 978 return extension->VersionString(); |
| 977 } | 979 } |
| 978 | 980 |
| 979 void DeviceStatusCollector::OnSubmittedSuccessfully() { | 981 void DeviceStatusCollector::OnSubmittedSuccessfully() { |
| 980 TrimStoredActivityPeriods(last_reported_day_, duration_for_last_reported_day_, | 982 TrimStoredActivityPeriods(last_reported_day_, duration_for_last_reported_day_, |
| 981 std::numeric_limits<int64>::max()); | 983 std::numeric_limits<int64_t>::max()); |
| 982 } | 984 } |
| 983 | 985 |
| 984 void DeviceStatusCollector::OnOSVersion(const std::string& version) { | 986 void DeviceStatusCollector::OnOSVersion(const std::string& version) { |
| 985 os_version_ = version; | 987 os_version_ = version; |
| 986 } | 988 } |
| 987 | 989 |
| 988 void DeviceStatusCollector::OnOSFirmware(const std::string& version) { | 990 void DeviceStatusCollector::OnOSFirmware(const std::string& version) { |
| 989 firmware_version_ = version; | 991 firmware_version_ = version; |
| 990 } | 992 } |
| 991 | 993 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 ScheduleGeolocationUpdateRequest(); | 1049 ScheduleGeolocationUpdateRequest(); |
| 1048 } | 1050 } |
| 1049 | 1051 |
| 1050 void DeviceStatusCollector::ReceiveVolumeInfo( | 1052 void DeviceStatusCollector::ReceiveVolumeInfo( |
| 1051 const std::vector<em::VolumeInfo>& info) { | 1053 const std::vector<em::VolumeInfo>& info) { |
| 1052 if (report_hardware_status_) | 1054 if (report_hardware_status_) |
| 1053 volume_info_ = info; | 1055 volume_info_ = info; |
| 1054 } | 1056 } |
| 1055 | 1057 |
| 1056 } // namespace policy | 1058 } // namespace policy |
| OLD | NEW |