| Index: chrome/browser/chromeos/policy/device_status_collector.cc
|
| diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc
|
| index 03e207bd74e1a4811fb45778644574c15212854e..616aa251950bd8636c01e7e18d2226da5ecdb9ab 100644
|
| --- a/chrome/browser/chromeos/policy/device_status_collector.cc
|
| +++ b/chrome/browser/chromeos/policy/device_status_collector.cc
|
| @@ -18,16 +18,17 @@
|
| #include "base/files/file_enumerator.h"
|
| #include "base/files/file_util.h"
|
| #include "base/format_macros.h"
|
| -#include "base/location.h"
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/memory/ref_counted.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/sys_info.h"
|
| #include "base/task_runner_util.h"
|
| +#include "base/threading/sequenced_task_runner_handle.h"
|
| #include "base/values.h"
|
| #include "base/version.h"
|
| #include "chrome/browser/browser_process.h"
|
| @@ -56,6 +57,7 @@
|
| #include "components/user_manager/user_manager.h"
|
| #include "components/user_manager/user_type.h"
|
| #include "components/version_info/version_info.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| #include "extensions/browser/extension_registry.h"
|
| #include "extensions/common/extension.h"
|
| #include "storage/browser/fileapi/external_mount_points.h"
|
| @@ -76,21 +78,8 @@ const unsigned int kMaxStoredPastActivityDays = 30;
|
| // How many days in the future to store active periods for.
|
| const unsigned int kMaxStoredFutureActivityDays = 2;
|
|
|
| -// How often, in seconds, to update the device location.
|
| -const unsigned int kGeolocationPollIntervalSeconds = 30 * 60;
|
| -
|
| -// How often, in seconds, to sample the hardware state.
|
| -const unsigned int kHardwareStatusSampleIntervalSeconds = 120;
|
| -
|
| -// Keys for the geolocation status dictionary in local state.
|
| -const char kLatitude[] = "latitude";
|
| -const char kLongitude[] = "longitude";
|
| -const char kAltitude[] = "altitude";
|
| -const char kAccuracy[] = "accuracy";
|
| -const char kAltitudeAccuracy[] = "altitude_accuracy";
|
| -const char kHeading[] = "heading";
|
| -const char kSpeed[] = "speed";
|
| -const char kTimestamp[] = "timestamp";
|
| +// How often, in seconds, to sample the hardware resource usage.
|
| +const unsigned int kResourceUsageSampleIntervalSeconds = 120;
|
|
|
| // The location we read our CPU statistics from.
|
| const char kProcStat[] = "/proc/stat";
|
| @@ -283,10 +272,111 @@ int ConvertWifiSignalStrength(int signal_strength) {
|
|
|
| namespace policy {
|
|
|
| +// Helper class for state tracking of async status queries. Creates device and
|
| +// session status blobs in the constructor and sends them to the the status
|
| +// response callback in the destructor.
|
| +//
|
| +// Some methods like |SampleVolumeInfo| queue async queries to collect data. The
|
| +// response callback of these queries, e.g. |OnVolumeInfoReceived|, holds a
|
| +// reference to the instance of this class, so that the destructor will not be
|
| +// invoked and the status response callback will not be fired until the original
|
| +// owner of the instance releases its reference and all async queries finish.
|
| +//
|
| +// Therefore, if you create an instance of this class, make sure to release your
|
| +// reference after quering all async queries (if any), e.g. by using a local
|
| +// |scoped_refptr<GetStatusState>| and letting it go out of scope.
|
| +class GetStatusState : public base::RefCountedThreadSafe<GetStatusState> {
|
| + public:
|
| + explicit GetStatusState(
|
| + const scoped_refptr<base::SequencedTaskRunner> task_runner,
|
| + const policy::DeviceStatusCollector::StatusCallback& response)
|
| + : task_runner_(task_runner), response_(response) {}
|
| +
|
| + inline em::DeviceStatusReportRequest* device_status() {
|
| + return device_status_.get();
|
| + }
|
| +
|
| + inline em::SessionStatusReportRequest* session_status() {
|
| + return session_status_.get();
|
| + }
|
| +
|
| + inline void ResetDeviceStatus() { device_status_.reset(); }
|
| +
|
| + inline void ResetSessionStatus() { session_status_.reset(); }
|
| +
|
| + // Queues an async callback to query disk volume information.
|
| + void SampleVolumeInfo(const policy::DeviceStatusCollector::VolumeInfoFetcher&
|
| + volume_info_fetcher) {
|
| + // Create list of mounted disk volumes to query status.
|
| + std::vector<storage::MountPoints::MountPointInfo> external_mount_points;
|
| + storage::ExternalMountPoints::GetSystemInstance()->AddMountPointInfosTo(
|
| + &external_mount_points);
|
| +
|
| + std::vector<std::string> mount_points;
|
| + for (const auto& info : external_mount_points)
|
| + mount_points.push_back(info.path.value());
|
| +
|
| + for (const auto& mount_info :
|
| + chromeos::disks::DiskMountManager::GetInstance()->mount_points()) {
|
| + // Extract a list of mount points to populate.
|
| + mount_points.push_back(mount_info.first);
|
| + }
|
| +
|
| + // Call out to the blocking pool to sample disk volume info.
|
| + base::PostTaskAndReplyWithResult(
|
| + content::BrowserThread::GetBlockingPool(), FROM_HERE,
|
| + base::Bind(volume_info_fetcher, mount_points),
|
| + base::Bind(&GetStatusState::OnVolumeInfoReceived, this));
|
| + }
|
| +
|
| + // Queues an async callback to query CPU temperature information.
|
| + void SampleCPUTempInfo(
|
| + const policy::DeviceStatusCollector::CPUTempFetcher& cpu_temp_fetcher) {
|
| + // Call out to the blocking pool to sample CPU temp.
|
| + base::PostTaskAndReplyWithResult(
|
| + content::BrowserThread::GetBlockingPool(), FROM_HERE, cpu_temp_fetcher,
|
| + base::Bind(&GetStatusState::OnCPUTempInfoReceived, this));
|
| + }
|
| +
|
| + private:
|
| + friend class RefCountedThreadSafe<GetStatusState>;
|
| +
|
| + // Posts the response on the UI thread. As long as there is an outstanding
|
| + // async query, the query holds a reference to us, so the destructor is
|
| + // not called.
|
| + ~GetStatusState() {
|
| + task_runner_->PostTask(FROM_HERE,
|
| + base::Bind(response_, base::Passed(&device_status_),
|
| + base::Passed(&session_status_)));
|
| + }
|
| +
|
| + void OnVolumeInfoReceived(const std::vector<em::VolumeInfo>& volume_info) {
|
| + device_status_->clear_volume_info();
|
| + for (const em::VolumeInfo& info : volume_info)
|
| + *device_status_->add_volume_info() = info;
|
| + }
|
| +
|
| + void OnCPUTempInfoReceived(
|
| + const std::vector<em::CPUTempInfo>& cpu_temp_info) {
|
| + if (cpu_temp_info.empty())
|
| + DLOG(WARNING) << "Unable to read CPU temp information.";
|
| +
|
| + device_status_->clear_cpu_temp_info();
|
| + for (const em::CPUTempInfo& info : cpu_temp_info)
|
| + *device_status_->add_cpu_temp_info() = info;
|
| + }
|
| +
|
| + const scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
| + policy::DeviceStatusCollector::StatusCallback response_;
|
| + std::unique_ptr<em::DeviceStatusReportRequest> device_status_ =
|
| + base::MakeUnique<em::DeviceStatusReportRequest>();
|
| + std::unique_ptr<em::SessionStatusReportRequest> session_status_ =
|
| + base::MakeUnique<em::SessionStatusReportRequest>();
|
| +};
|
| +
|
| DeviceStatusCollector::DeviceStatusCollector(
|
| PrefService* local_state,
|
| chromeos::system::StatisticsProvider* provider,
|
| - const LocationUpdateRequester& location_update_requester,
|
| const VolumeInfoFetcher& volume_info_fetcher,
|
| const CPUStatisticsFetcher& cpu_statistics_fetcher,
|
| const CPUTempFetcher& cpu_temp_fetcher)
|
| @@ -299,9 +389,12 @@ DeviceStatusCollector::DeviceStatusCollector(
|
| cpu_temp_fetcher_(cpu_temp_fetcher),
|
| statistics_provider_(provider),
|
| cros_settings_(chromeos::CrosSettings::Get()),
|
| - location_update_requester_(location_update_requester),
|
| + task_runner_(nullptr),
|
| weak_factory_(this) {
|
| - CHECK(content::BrowserThread::GetCurrentThreadIdentifier(&creation_thread_));
|
| + // Get the task runner of the current thread, so we can queue status responses
|
| + // on this thread.
|
| + CHECK(base::SequencedTaskRunnerHandle::IsSet());
|
| + task_runner_ = base::SequencedTaskRunnerHandle::Get();
|
|
|
| if (volume_info_fetcher_.is_null())
|
| volume_info_fetcher_ = base::Bind(&GetVolumeInfo);
|
| @@ -315,10 +408,9 @@ DeviceStatusCollector::DeviceStatusCollector(
|
| idle_poll_timer_.Start(FROM_HERE,
|
| TimeDelta::FromSeconds(kIdlePollIntervalSeconds),
|
| this, &DeviceStatusCollector::CheckIdleState);
|
| - hardware_status_sampling_timer_.Start(
|
| - FROM_HERE,
|
| - TimeDelta::FromSeconds(kHardwareStatusSampleIntervalSeconds),
|
| - this, &DeviceStatusCollector::SampleHardwareStatus);
|
| + resource_usage_sampling_timer_.Start(
|
| + FROM_HERE, TimeDelta::FromSeconds(kResourceUsageSampleIntervalSeconds),
|
| + this, &DeviceStatusCollector::SampleResourceUsage);
|
|
|
| // Watch for changes to the individual policies that control what the status
|
| // reports contain.
|
| @@ -331,8 +423,6 @@ DeviceStatusCollector::DeviceStatusCollector(
|
| chromeos::kReportDeviceActivityTimes, callback);
|
| boot_mode_subscription_ = cros_settings_->AddSettingsObserver(
|
| chromeos::kReportDeviceBootMode, callback);
|
| - location_subscription_ = cros_settings_->AddSettingsObserver(
|
| - chromeos::kReportDeviceLocation, callback);
|
| network_interfaces_subscription_ = cros_settings_->AddSettingsObserver(
|
| chromeos::kReportDeviceNetworkInterfaces, callback);
|
| users_subscription_ = cros_settings_->AddSettingsObserver(
|
| @@ -346,27 +436,6 @@ DeviceStatusCollector::DeviceStatusCollector(
|
| running_kiosk_app_subscription_ = cros_settings_->AddSettingsObserver(
|
| chromeos::kReportRunningKioskApp, callback);
|
|
|
| - // The last known location is persisted in local state. This makes location
|
| - // information available immediately upon startup and avoids the need to
|
| - // reacquire the location on every user session change or browser crash.
|
| - device::Geoposition position;
|
| - std::string timestamp_str;
|
| - int64_t timestamp;
|
| - const base::DictionaryValue* location =
|
| - local_state_->GetDictionary(prefs::kDeviceLocation);
|
| - if (location->GetDouble(kLatitude, &position.latitude) &&
|
| - location->GetDouble(kLongitude, &position.longitude) &&
|
| - location->GetDouble(kAltitude, &position.altitude) &&
|
| - location->GetDouble(kAccuracy, &position.accuracy) &&
|
| - location->GetDouble(kAltitudeAccuracy, &position.altitude_accuracy) &&
|
| - location->GetDouble(kHeading, &position.heading) &&
|
| - location->GetDouble(kSpeed, &position.speed) &&
|
| - location->GetString(kTimestamp, ×tamp_str) &&
|
| - base::StringToInt64(timestamp_str, ×tamp)) {
|
| - position.timestamp = Time::FromInternalValue(timestamp);
|
| - position_ = position;
|
| - }
|
| -
|
| // Fetch the current values of the policies.
|
| UpdateReportingSettings();
|
|
|
| @@ -393,8 +462,6 @@ DeviceStatusCollector::~DeviceStatusCollector() {
|
| void DeviceStatusCollector::RegisterPrefs(PrefRegistrySimple* registry) {
|
| registry->RegisterDictionaryPref(prefs::kDeviceActivityTimes,
|
| new base::DictionaryValue);
|
| - registry->RegisterDictionaryPref(prefs::kDeviceLocation,
|
| - new base::DictionaryValue);
|
| }
|
|
|
| void DeviceStatusCollector::CheckIdleState() {
|
| @@ -448,27 +515,12 @@ void DeviceStatusCollector::UpdateReportingSettings() {
|
| report_session_status_ = true;
|
| }
|
|
|
| - // Device location reporting is disabled by default because it is
|
| - // not launched yet.
|
| - if (!cros_settings_->GetBoolean(
|
| - chromeos::kReportDeviceLocation, &report_location_)) {
|
| - report_location_ = false;
|
| - }
|
| -
|
| - if (report_location_) {
|
| - ScheduleGeolocationUpdateRequest();
|
| - } else {
|
| - geolocation_update_timer_.Stop();
|
| - position_ = device::Geoposition();
|
| - local_state_->ClearPref(prefs::kDeviceLocation);
|
| - }
|
| -
|
| if (!report_hardware_status_) {
|
| - ClearCachedHardwareStatus();
|
| + ClearCachedResourceUsage();
|
| } else if (!already_reporting_hardware_status) {
|
| // Turning on hardware status reporting - fetch an initial sample
|
| // immediately instead of waiting for the sampling timer to fire.
|
| - SampleHardwareStatus();
|
| + SampleResourceUsage();
|
| }
|
|
|
| // Os update status and running kiosk app reporting are disabled by default.
|
| @@ -546,8 +598,7 @@ void DeviceStatusCollector::AddActivePeriod(Time start, Time end) {
|
| }
|
| }
|
|
|
| -void DeviceStatusCollector::ClearCachedHardwareStatus() {
|
| - volume_info_.clear();
|
| +void DeviceStatusCollector::ClearCachedResourceUsage() {
|
| resource_usage_.clear();
|
| last_cpu_active_ = 0;
|
| last_cpu_idle_ = 0;
|
| @@ -594,48 +645,21 @@ DeviceStatusCollector::GetAutoLaunchedKioskSessionInfo() {
|
| return std::unique_ptr<DeviceLocalAccount>();
|
| }
|
|
|
| -void DeviceStatusCollector::SampleHardwareStatus() {
|
| +void DeviceStatusCollector::SampleResourceUsage() {
|
| // Results must be written in the creation thread since that's where they
|
| // are read from in the Get*StatusAsync methods.
|
| - CHECK(content::BrowserThread::CurrentlyOn(creation_thread_));
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| // If hardware reporting has been disabled, do nothing here.
|
| if (!report_hardware_status_)
|
| return;
|
|
|
| - // Create list of mounted disk volumes to query status.
|
| - std::vector<storage::MountPoints::MountPointInfo> external_mount_points;
|
| - storage::ExternalMountPoints::GetSystemInstance()->AddMountPointInfosTo(
|
| - &external_mount_points);
|
| -
|
| - std::vector<std::string> mount_points;
|
| - for (const auto& info : external_mount_points)
|
| - mount_points.push_back(info.path.value());
|
| -
|
| - for (const auto& mount_info :
|
| - chromeos::disks::DiskMountManager::GetInstance()->mount_points()) {
|
| - // Extract a list of mount points to populate.
|
| - mount_points.push_back(mount_info.first);
|
| - }
|
| -
|
| - // Call out to the blocking pool to measure disk, CPU usage and CPU temp.
|
| - base::PostTaskAndReplyWithResult(
|
| - content::BrowserThread::GetBlockingPool(),
|
| - FROM_HERE,
|
| - base::Bind(volume_info_fetcher_, mount_points),
|
| - base::Bind(&DeviceStatusCollector::ReceiveVolumeInfo,
|
| - weak_factory_.GetWeakPtr()));
|
| -
|
| + // Call out to the blocking pool to sample CPU stats.
|
| base::PostTaskAndReplyWithResult(
|
| content::BrowserThread::GetBlockingPool(), FROM_HERE,
|
| cpu_statistics_fetcher_,
|
| base::Bind(&DeviceStatusCollector::ReceiveCPUStatistics,
|
| weak_factory_.GetWeakPtr()));
|
| -
|
| - base::PostTaskAndReplyWithResult(
|
| - content::BrowserThread::GetBlockingPool(), FROM_HERE, cpu_temp_fetcher_,
|
| - base::Bind(&DeviceStatusCollector::StoreCPUTempInfo,
|
| - weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| void DeviceStatusCollector::ReceiveCPUStatistics(const std::string& stats) {
|
| @@ -691,18 +715,8 @@ void DeviceStatusCollector::ReceiveCPUStatistics(const std::string& stats) {
|
| resource_usage_.pop_front();
|
| }
|
|
|
| -void DeviceStatusCollector::StoreCPUTempInfo(
|
| - const std::vector<em::CPUTempInfo>& info) {
|
| - if (info.empty()) {
|
| - DLOG(WARNING) << "Unable to read CPU temp information.";
|
| - }
|
| -
|
| - if (report_hardware_status_)
|
| - cpu_temp_info_ = info;
|
| -}
|
| -
|
| bool DeviceStatusCollector::GetActivityTimes(
|
| - em::DeviceStatusReportRequest* request) {
|
| + em::DeviceStatusReportRequest* status) {
|
| DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes);
|
| base::DictionaryValue* activity_times = update.Get();
|
|
|
| @@ -717,7 +731,7 @@ bool DeviceStatusCollector::GetActivityTimes(
|
| // second occurs, two consecutive seconds have the same timestamp.
|
| int64_t end_timestamp = start_timestamp + Time::kMillisecondsPerDay;
|
|
|
| - em::ActiveTimePeriod* active_period = request->add_active_period();
|
| + em::ActiveTimePeriod* active_period = status->add_active_period();
|
| em::TimePeriod* period = active_period->mutable_time_period();
|
| period->set_start_timestamp(start_timestamp);
|
| period->set_end_timestamp(end_timestamp);
|
| @@ -735,57 +749,29 @@ bool DeviceStatusCollector::GetActivityTimes(
|
| }
|
|
|
| bool DeviceStatusCollector::GetVersionInfo(
|
| - em::DeviceStatusReportRequest* request) {
|
| - request->set_browser_version(version_info::GetVersionNumber());
|
| - request->set_os_version(os_version_);
|
| - request->set_firmware_version(firmware_version_);
|
| + em::DeviceStatusReportRequest* status) {
|
| + status->set_browser_version(version_info::GetVersionNumber());
|
| + status->set_os_version(os_version_);
|
| + status->set_firmware_version(firmware_version_);
|
| return true;
|
| }
|
|
|
| -bool DeviceStatusCollector::GetBootMode(
|
| - em::DeviceStatusReportRequest* request) {
|
| +bool DeviceStatusCollector::GetBootMode(em::DeviceStatusReportRequest* status) {
|
| std::string dev_switch_mode;
|
| bool anything_reported = false;
|
| if (statistics_provider_->GetMachineStatistic(
|
| chromeos::system::kDevSwitchBootKey, &dev_switch_mode)) {
|
| if (dev_switch_mode == chromeos::system::kDevSwitchBootValueDev)
|
| - request->set_boot_mode("Dev");
|
| + status->set_boot_mode("Dev");
|
| else if (dev_switch_mode == chromeos::system::kDevSwitchBootValueVerified)
|
| - request->set_boot_mode("Verified");
|
| + status->set_boot_mode("Verified");
|
| anything_reported = true;
|
| }
|
| return anything_reported;
|
| }
|
|
|
| -bool DeviceStatusCollector::GetLocation(
|
| - em::DeviceStatusReportRequest* request) {
|
| - em::DeviceLocation* location = request->mutable_device_location();
|
| - if (!position_.Validate()) {
|
| - location->set_error_code(
|
| - em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE);
|
| - location->set_error_message(position_.error_message);
|
| - } else {
|
| - location->set_latitude(position_.latitude);
|
| - location->set_longitude(position_.longitude);
|
| - location->set_accuracy(position_.accuracy);
|
| - location->set_timestamp(
|
| - (position_.timestamp - Time::UnixEpoch()).InMilliseconds());
|
| - // Lowest point on land is at approximately -400 meters.
|
| - if (position_.altitude > -10000.)
|
| - location->set_altitude(position_.altitude);
|
| - if (position_.altitude_accuracy >= 0.)
|
| - location->set_altitude_accuracy(position_.altitude_accuracy);
|
| - if (position_.heading >= 0. && position_.heading <= 360)
|
| - location->set_heading(position_.heading);
|
| - if (position_.speed >= 0.)
|
| - location->set_speed(position_.speed);
|
| - location->set_error_code(em::DeviceLocation::ERROR_CODE_NONE);
|
| - }
|
| - return true;
|
| -}
|
| -
|
| bool DeviceStatusCollector::GetNetworkInterfaces(
|
| - em::DeviceStatusReportRequest* request) {
|
| + em::DeviceStatusReportRequest* status) {
|
| // Maps shill device type strings to proto enum constants.
|
| static const struct {
|
| const char* type_string;
|
| @@ -837,7 +823,7 @@ bool DeviceStatusCollector::GetNetworkInterfaces(
|
| if (type_idx >= arraysize(kDeviceTypeMap))
|
| continue;
|
|
|
| - em::NetworkInterface* interface = request->add_network_interface();
|
| + em::NetworkInterface* interface = status->add_network_interface();
|
| interface->set_type(kDeviceTypeMap[type_idx].type_constant);
|
| if (!(*device)->mac_address().empty())
|
| interface->set_mac_address((*device)->mac_address());
|
| @@ -877,7 +863,7 @@ bool DeviceStatusCollector::GetNetworkInterfaces(
|
| }
|
|
|
| // Copy fields from NetworkState into the status report.
|
| - em::NetworkState* proto_state = request->add_network_state();
|
| + em::NetworkState* proto_state = status->add_network_state();
|
| proto_state->set_connection_state(connection_state_enum);
|
| anything_reported = true;
|
|
|
| @@ -905,7 +891,7 @@ bool DeviceStatusCollector::GetNetworkInterfaces(
|
| return anything_reported;
|
| }
|
|
|
| -bool DeviceStatusCollector::GetUsers(em::DeviceStatusReportRequest* request) {
|
| +bool DeviceStatusCollector::GetUsers(em::DeviceStatusReportRequest* status) {
|
| const user_manager::UserList& users =
|
| chromeos::ChromeUserManager::Get()->GetUsers();
|
|
|
| @@ -915,7 +901,7 @@ bool DeviceStatusCollector::GetUsers(em::DeviceStatusReportRequest* request) {
|
| if (!user->HasGaiaAccount())
|
| continue;
|
|
|
| - em::DeviceUser* device_user = request->add_user();
|
| + em::DeviceUser* device_user = status->add_user();
|
| if (chromeos::ChromeUserManager::Get()->ShouldReportUser(user->email())) {
|
| device_user->set_type(em::DeviceUser::USER_TYPE_MANAGED);
|
| device_user->set_email(user->email());
|
| @@ -929,13 +915,17 @@ bool DeviceStatusCollector::GetUsers(em::DeviceStatusReportRequest* request) {
|
| }
|
|
|
| bool DeviceStatusCollector::GetHardwareStatus(
|
| - em::DeviceStatusReportRequest* status) {
|
| - // Add volume info.
|
| - status->clear_volume_info();
|
| - for (const em::VolumeInfo& info : volume_info_) {
|
| - *status->add_volume_info() = info;
|
| - }
|
| + em::DeviceStatusReportRequest* status,
|
| + scoped_refptr<GetStatusState> state) {
|
| + // Sample disk volume info in a background thread.
|
| + state->SampleVolumeInfo(volume_info_fetcher_);
|
| +
|
| + // Sample CPU temperature in a background thread.
|
| + state->SampleCPUTempInfo(cpu_temp_fetcher_);
|
|
|
| + // Add CPU utilization and free RAM. Note that these stats are sampled in
|
| + // regular intervals. Unlike CPU temp and volume info these are not one-time
|
| + // sampled values, hence the difference in logic.
|
| status->set_system_ram_total(base::SysInfo::AmountOfPhysicalMemory());
|
| status->clear_system_ram_free();
|
| status->clear_cpu_utilization_pct();
|
| @@ -943,12 +933,6 @@ bool DeviceStatusCollector::GetHardwareStatus(
|
| status->add_cpu_utilization_pct(usage.cpu_usage_percent);
|
| status->add_system_ram_free(usage.bytes_of_ram_free);
|
| }
|
| -
|
| - // Add CPU temp info.
|
| - status->clear_cpu_temp_info();
|
| - for (const em::CPUTempInfo& info : cpu_temp_info_) {
|
| - *status->add_cpu_temp_info() = info;
|
| - }
|
| return true;
|
| }
|
|
|
| @@ -1010,7 +994,7 @@ bool DeviceStatusCollector::GetRunningKioskApp(
|
| em::DeviceStatusReportRequest* status) {
|
| // Must be on creation thread since some stats are written to in that thread
|
| // and accessing them from another thread would lead to race conditions.
|
| - CHECK(content::BrowserThread::CurrentlyOn(creation_thread_));
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| std::unique_ptr<const DeviceLocalAccount> account =
|
| GetAutoLaunchedKioskSessionInfo();
|
| @@ -1039,73 +1023,82 @@ bool DeviceStatusCollector::GetRunningKioskApp(
|
| return true;
|
| }
|
|
|
| -void DeviceStatusCollector::GetDeviceStatusAsync(
|
| - const DeviceStatusCallback& response) {
|
| +void DeviceStatusCollector::GetDeviceAndSessionStatusAsync(
|
| + const StatusCallback& response) {
|
| // Must be on creation thread since some stats are written to in that thread
|
| // and accessing them from another thread would lead to race conditions.
|
| - CHECK(content::BrowserThread::CurrentlyOn(creation_thread_));
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - std::unique_ptr<em::DeviceStatusReportRequest> status =
|
| - base::MakeUnique<em::DeviceStatusReportRequest>();
|
| - bool got_status = false;
|
| + // Some of the data we're collecting is gathered in background threads.
|
| + // This object keeps track of the state of each async request.
|
| + scoped_refptr<GetStatusState> state(
|
| + new GetStatusState(task_runner_, response));
|
| +
|
| + // Gather device status (might queue some async queries)
|
| + GetDeviceStatus(state);
|
| +
|
| + // Gather device status (might queue some async queries)
|
| + GetSessionStatus(state);
|
| +
|
| + // If there are no outstanding async queries, e.g. from GetHardwareStatus(),
|
| + // the destructor of |state| calls |response|. If there are async queries, the
|
| + // queries hold references to |state|, so that |state| is only destroyed when
|
| + // the last async query has finished.
|
| +}
|
| +
|
| +void DeviceStatusCollector::GetDeviceStatus(
|
| + scoped_refptr<GetStatusState> state) {
|
| + em::DeviceStatusReportRequest* status = state->device_status();
|
| + bool anything_reported = false;
|
|
|
| if (report_activity_times_)
|
| - got_status |= GetActivityTimes(status.get());
|
| + anything_reported |= GetActivityTimes(status);
|
|
|
| if (report_version_info_)
|
| - got_status |= GetVersionInfo(status.get());
|
| + anything_reported |= GetVersionInfo(status);
|
|
|
| if (report_boot_mode_)
|
| - got_status |= GetBootMode(status.get());
|
| -
|
| - if (report_location_)
|
| - got_status |= GetLocation(status.get());
|
| + anything_reported |= GetBootMode(status);
|
|
|
| if (report_network_interfaces_)
|
| - got_status |= GetNetworkInterfaces(status.get());
|
| + anything_reported |= GetNetworkInterfaces(status);
|
|
|
| if (report_users_)
|
| - got_status |= GetUsers(status.get());
|
| + anything_reported |= GetUsers(status);
|
|
|
| if (report_hardware_status_)
|
| - got_status |= GetHardwareStatus(status.get());
|
| + anything_reported |= GetHardwareStatus(status, state);
|
|
|
| if (report_os_update_status_)
|
| - got_status |= GetOsUpdateStatus(status.get());
|
| + anything_reported |= GetOsUpdateStatus(status);
|
|
|
| if (report_running_kiosk_app_)
|
| - got_status |= GetRunningKioskApp(status.get());
|
| + anything_reported |= GetRunningKioskApp(status);
|
|
|
| // Wipe pointer if we didn't actually add any data.
|
| - if (!got_status)
|
| - status.reset();
|
| -
|
| - content::BrowserThread::PostTask(creation_thread_, FROM_HERE,
|
| - base::Bind(response, base::Passed(&status)));
|
| + if (!anything_reported)
|
| + state->ResetDeviceStatus();
|
| }
|
|
|
| -void DeviceStatusCollector::GetDeviceSessionStatusAsync(
|
| - const DeviceSessionStatusCallback& response) {
|
| - // Only generate session status reports if session status reporting is
|
| - // enabled.
|
| - if (!report_session_status_) {
|
| - content::BrowserThread::PostTask(creation_thread_, FROM_HERE,
|
| - base::Bind(response, nullptr));
|
| - return;
|
| - }
|
| +void DeviceStatusCollector::GetSessionStatus(
|
| + scoped_refptr<GetStatusState> state) {
|
| + em::SessionStatusReportRequest* status = state->session_status();
|
| + bool anything_reported = false;
|
| +
|
| + if (report_session_status_)
|
| + anything_reported |= GetAccountStatus(status);
|
| +
|
| + // Wipe pointer if we didn't actually add any data.
|
| + if (!anything_reported)
|
| + state->ResetSessionStatus();
|
| +}
|
|
|
| +bool DeviceStatusCollector::GetAccountStatus(
|
| + em::SessionStatusReportRequest* status) {
|
| std::unique_ptr<const DeviceLocalAccount> account =
|
| GetAutoLaunchedKioskSessionInfo();
|
| - // Only generate session status reports if we are in an auto-launched kiosk
|
| - // session.
|
| - if (!account) {
|
| - content::BrowserThread::PostTask(creation_thread_, FROM_HERE,
|
| - base::Bind(response, nullptr));
|
| - return;
|
| - }
|
| -
|
| - std::unique_ptr<em::SessionStatusReportRequest> status =
|
| - base::MakeUnique<em::SessionStatusReportRequest>();
|
| + if (!account)
|
| + return false;
|
|
|
| // Get the account ID associated with this user.
|
| status->set_device_local_account_id(account->account_id);
|
| @@ -1121,8 +1114,7 @@ void DeviceStatusCollector::GetDeviceSessionStatusAsync(
|
| app_status->set_extension_version(app_version);
|
| }
|
|
|
| - content::BrowserThread::PostTask(creation_thread_, FROM_HERE,
|
| - base::Bind(response, base::Passed(&status)));
|
| + return true;
|
| }
|
|
|
| std::string DeviceStatusCollector::GetAppVersion(
|
| @@ -1152,68 +1144,4 @@ void DeviceStatusCollector::OnOSFirmware(const std::string& version) {
|
| firmware_version_ = version;
|
| }
|
|
|
| -void DeviceStatusCollector::ScheduleGeolocationUpdateRequest() {
|
| - if (geolocation_update_timer_.IsRunning() || geolocation_update_in_progress_)
|
| - return;
|
| -
|
| - if (position_.Validate()) {
|
| - TimeDelta elapsed = GetCurrentTime() - position_.timestamp;
|
| - TimeDelta interval =
|
| - TimeDelta::FromSeconds(kGeolocationPollIntervalSeconds);
|
| - if (elapsed <= interval) {
|
| - geolocation_update_timer_.Start(
|
| - FROM_HERE,
|
| - interval - elapsed,
|
| - this,
|
| - &DeviceStatusCollector::ScheduleGeolocationUpdateRequest);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - geolocation_update_in_progress_ = true;
|
| - if (location_update_requester_.is_null()) {
|
| - geolocation_subscription_ =
|
| - device::GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
|
| - base::Bind(&DeviceStatusCollector::ReceiveGeolocationUpdate,
|
| - weak_factory_.GetWeakPtr()),
|
| - true);
|
| - } else {
|
| - location_update_requester_.Run(base::Bind(
|
| - &DeviceStatusCollector::ReceiveGeolocationUpdate,
|
| - weak_factory_.GetWeakPtr()));
|
| - }
|
| -}
|
| -
|
| -void DeviceStatusCollector::ReceiveGeolocationUpdate(
|
| - const device::Geoposition& position) {
|
| - geolocation_update_in_progress_ = false;
|
| -
|
| - // Ignore update if device location reporting has since been disabled.
|
| - if (!report_location_)
|
| - return;
|
| -
|
| - if (position.Validate()) {
|
| - position_ = position;
|
| - base::DictionaryValue location;
|
| - location.SetDouble(kLatitude, position.latitude);
|
| - location.SetDouble(kLongitude, position.longitude);
|
| - location.SetDouble(kAltitude, position.altitude);
|
| - location.SetDouble(kAccuracy, position.accuracy);
|
| - location.SetDouble(kAltitudeAccuracy, position.altitude_accuracy);
|
| - location.SetDouble(kHeading, position.heading);
|
| - location.SetDouble(kSpeed, position.speed);
|
| - location.SetString(kTimestamp,
|
| - base::Int64ToString(position.timestamp.ToInternalValue()));
|
| - local_state_->Set(prefs::kDeviceLocation, location);
|
| - }
|
| -
|
| - ScheduleGeolocationUpdateRequest();
|
| -}
|
| -
|
| -void DeviceStatusCollector::ReceiveVolumeInfo(
|
| - const std::vector<em::VolumeInfo>& info) {
|
| - if (report_hardware_status_)
|
| - volume_info_ = info;
|
| -}
|
| -
|
| } // namespace policy
|
|
|