summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbartfab@chromium.org <bartfab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 15:34:03 +0000
committerbartfab@chromium.org <bartfab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 15:34:03 +0000
commitb2f0bb484b12d50613019ac84beeebb9942dc7f8 (patch)
tree4b648785066ca7f946a38b20e08c234b48114880
parent72f582938721f2ad69e3eb034d0562938ae1c4f7 (diff)
downloadchromium_src-b2f0bb484b12d50613019ac84beeebb9942dc7f8.zip
chromium_src-b2f0bb484b12d50613019ac84beeebb9942dc7f8.tar.gz
chromium_src-b2f0bb484b12d50613019ac84beeebb9942dc7f8.tar.bz2
Add device location reporting
This CL implements device location reporting for Enterprise-enrolled Chrome OS devices. The position is determined using the existing Chrome geolocation stack. This CL depends on https://chromiumcodereview.appspot.com/10344016/ ISSUE=chromium-os:18710 TEST=unit_tests including new DeviceStatusCollectorTest.Location Review URL: http://codereview.chromium.org/10103029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135348 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/cros_settings_names.cc8
-rw-r--r--chrome/browser/chromeos/cros_settings_names.h1
-rw-r--r--chrome/browser/chromeos/device_settings_provider.cc17
-rw-r--r--chrome/browser/chromeos/login/version_info_updater.cc1
-rw-r--r--chrome/browser/chromeos/stub_cros_settings_provider.cc1
-rw-r--r--chrome/browser/policy/browser_policy_connector.cc3
-rw-r--r--chrome/browser/policy/device_status_collector.cc184
-rw-r--r--chrome/browser/policy/device_status_collector.h45
-rw-r--r--chrome/browser/policy/device_status_collector_unittest.cc287
-rw-r--r--chrome/browser/policy/proto/device_management_backend.proto41
-rw-r--r--chrome/common/pref_names.cc14
-rw-r--r--chrome/common/pref_names.h3
12 files changed, 484 insertions, 121 deletions
diff --git a/chrome/browser/chromeos/cros_settings_names.cc b/chrome/browser/chromeos/cros_settings_names.cc
index e619787..fd6a0fb 100644
--- a/chrome/browser/chromeos/cros_settings_names.cc
+++ b/chrome/browser/chromeos/cros_settings_names.cc
@@ -42,10 +42,14 @@ const char kReportDeviceVersionInfo[] =
const char kReportDeviceActivityTimes[] =
"cros.device_status.report_activity_times";
-// A boolean pref that indicates whether device the state of the dev switch
-// at boot mode should be reported along with device policy requests.
+// A boolean pref that indicates whether the state of the dev mode switch at
+// boot should be reported along with device policy requests.
const char kReportDeviceBootMode[] = "cros.device_status.report_boot_mode";
+// A boolean pref that indicates whether the current location should be reported
+// along with device policy requests.
+const char kReportDeviceLocation[] = "cros.device_status.report_location";
+
// A list of dictionaries, each detailing one extension to install as part of
// the AppPack and including the following fields:
// "extension-id": ID of the extension to install
diff --git a/chrome/browser/chromeos/cros_settings_names.h b/chrome/browser/chromeos/cros_settings_names.h
index ac672d5..9284886 100644
--- a/chrome/browser/chromeos/cros_settings_names.h
+++ b/chrome/browser/chromeos/cros_settings_names.h
@@ -32,6 +32,7 @@ extern const char kReleaseChannelDelegated[];
extern const char kReportDeviceVersionInfo[];
extern const char kReportDeviceActivityTimes[];
extern const char kReportDeviceBootMode[];
+extern const char kReportDeviceLocation[];
extern const char kAppPack[];
diff --git a/chrome/browser/chromeos/device_settings_provider.cc b/chrome/browser/chromeos/device_settings_provider.cc
index c24d778..60faf48 100644
--- a/chrome/browser/chromeos/device_settings_provider.cc
+++ b/chrome/browser/chromeos/device_settings_provider.cc
@@ -53,6 +53,7 @@ const char* kKnownSettings[] = {
kReleaseChannelDelegated,
kReportDeviceActivityTimes,
kReportDeviceBootMode,
+ kReportDeviceLocation,
kReportDeviceVersionInfo,
kScreenSaverExtensionId,
kScreenSaverTimeout,
@@ -287,14 +288,15 @@ void DeviceSettingsProvider::SetInPolicy() {
// The remaining settings don't support Set(), since they are not
// intended to be customizable by the user:
// kAppPack
- // kIdleLogoutTimeout,
- // kIdleLogoutWarningDuration,
- // kReleaseChannelDelegated,
+ // kIdleLogoutTimeout
+ // kIdleLogoutWarningDuration
+ // kReleaseChannelDelegated
// kReportDeviceVersionInfo
// kReportDeviceActivityTimes
// kReportDeviceBootMode
- // kScreenSaverExtensionId,
- // kScreenSaverTimeout,
+ // kReportDeviceLocation
+ // kScreenSaverExtensionId
+ // kScreenSaverTimeout
// kStartUpUrls
NOTREACHED();
@@ -490,6 +492,11 @@ void DeviceSettingsProvider::DecodeReportingPolicies(
kReportDeviceBootMode,
policy.device_reporting().report_boot_mode());
}
+ if (policy.device_reporting().has_report_location()) {
+ new_values_cache->SetBoolean(
+ kReportDeviceLocation,
+ policy.device_reporting().report_location());
+ }
}
}
diff --git a/chrome/browser/chromeos/login/version_info_updater.cc b/chrome/browser/chromeos/login/version_info_updater.cc
index dde2af2..f429916 100644
--- a/chrome/browser/chromeos/login/version_info_updater.cc
+++ b/chrome/browser/chromeos/login/version_info_updater.cc
@@ -38,6 +38,7 @@ const char* kReportingFlags[] = {
chromeos::kReportDeviceVersionInfo,
chromeos::kReportDeviceActivityTimes,
chromeos::kReportDeviceBootMode,
+ chromeos::kReportDeviceLocation,
};
}
diff --git a/chrome/browser/chromeos/stub_cros_settings_provider.cc b/chrome/browser/chromeos/stub_cros_settings_provider.cc
index b20d8f7..64a5318 100644
--- a/chrome/browser/chromeos/stub_cros_settings_provider.cc
+++ b/chrome/browser/chromeos/stub_cros_settings_provider.cc
@@ -26,6 +26,7 @@ const char* kHandledSettings[] = {
kReportDeviceVersionInfo,
kReportDeviceActivityTimes,
kReportDeviceBootMode,
+ kReportDeviceLocation,
kSettingProxyEverywhere,
kSignedDataRoamingEnabled,
kStatsReportingPref,
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc
index 1ca3af7..080d941 100644
--- a/chrome/browser/policy/browser_policy_connector.cc
+++ b/chrome/browser/policy/browser_policy_connector.cc
@@ -494,7 +494,8 @@ void BrowserPolicyConnector::CompleteInitialization() {
device_data_store_->set_device_status_collector(
new DeviceStatusCollector(
g_browser_process->local_state(),
- chromeos::system::StatisticsProvider::GetInstance()));
+ chromeos::system::StatisticsProvider::GetInstance(),
+ NULL));
#endif
}
diff --git a/chrome/browser/policy/device_status_collector.cc b/chrome/browser/policy/device_status_collector.cc
index 5a1be4a..cb547cf 100644
--- a/chrome/browser/policy/device_status_collector.cc
+++ b/chrome/browser/policy/device_status_collector.cc
@@ -5,8 +5,12 @@
#include "chrome/browser/policy/device_status_collector.h"
#include "base/bind.h"
-#include "base/callback.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
+#include "base/values.h"
#include "chrome/browser/chromeos/cros_settings.h"
#include "chrome/browser/chromeos/cros_settings_names.h"
#include "chrome/browser/chromeos/system/statistics_provider.h"
@@ -16,6 +20,8 @@
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
using base::Time;
using base::TimeDelta;
@@ -33,10 +39,29 @@ 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;
+
const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
+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";
+
// Record device activity for the specified day into the given dictionary.
-void AddDeviceActivity(DictionaryValue* activity_times,
+void AddDeviceActivity(base::DictionaryValue* activity_times,
Time day_midnight,
TimeDelta activity) {
DCHECK(activity.InMilliseconds() < kMillisecondsPerDay);
@@ -55,18 +80,25 @@ namespace policy {
DeviceStatusCollector::DeviceStatusCollector(
PrefService* local_state,
- chromeos::system::StatisticsProvider* provider)
+ chromeos::system::StatisticsProvider* provider,
+ LocationUpdateRequester location_update_requester)
: max_stored_past_activity_days_(kMaxStoredPastActivityDays),
max_stored_future_activity_days_(kMaxStoredFutureActivityDays),
local_state_(local_state),
last_idle_check_(Time()),
+ geolocation_update_in_progress_(false),
statistics_provider_(provider),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ location_update_requester_(location_update_requester),
report_version_info_(false),
report_activity_times_(false),
- report_boot_mode_(false) {
- timer_.Start(FROM_HERE,
- TimeDelta::FromSeconds(kPollIntervalSeconds),
- this, &DeviceStatusCollector::CheckIdleState);
+ report_boot_mode_(false),
+ report_location_(false) {
+ if (!location_update_requester_)
+ location_update_requester_ = &content::RequestLocationUpdate;
+ idle_poll_timer_.Start(FROM_HERE,
+ TimeDelta::FromSeconds(kIdlePollIntervalSeconds),
+ this, &DeviceStatusCollector::CheckIdleState);
cros_settings_ = chromeos::CrosSettings::Get();
@@ -76,6 +108,28 @@ DeviceStatusCollector::DeviceStatusCollector(
cros_settings_->AddSettingsObserver(chromeos::kReportDeviceActivityTimes,
this);
cros_settings_->AddSettingsObserver(chromeos::kReportDeviceBootMode, this);
+ cros_settings_->AddSettingsObserver(chromeos::kReportDeviceLocation, this);
+
+ // 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.
+ content::Geoposition position;
+ std::string timestamp_str;
+ int64 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, &timestamp_str) &&
+ base::StringToInt64(timestamp_str, &timestamp)) {
+ position.timestamp = Time::FromInternalValue(timestamp);
+ position_ = position;
+ }
// Fetch the current values of the policies.
UpdateReportingSettings();
@@ -96,12 +150,15 @@ DeviceStatusCollector::~DeviceStatusCollector() {
cros_settings_->RemoveSettingsObserver(chromeos::kReportDeviceActivityTimes,
this);
cros_settings_->RemoveSettingsObserver(chromeos::kReportDeviceBootMode, this);
+ cros_settings_->RemoveSettingsObserver(chromeos::kReportDeviceLocation, this);
}
// static
void DeviceStatusCollector::RegisterPrefs(PrefService* local_state) {
local_state->RegisterDictionaryPref(prefs::kDeviceActivityTimes,
- new DictionaryValue);
+ new base::DictionaryValue);
+ local_state->RegisterDictionaryPref(prefs::kDeviceLocation,
+ new base::DictionaryValue);
}
void DeviceStatusCollector::CheckIdleState() {
@@ -125,6 +182,16 @@ void DeviceStatusCollector::UpdateReportingSettings() {
chromeos::kReportDeviceActivityTimes, &report_activity_times_);
cros_settings_->GetBoolean(
chromeos::kReportDeviceBootMode, &report_boot_mode_);
+ cros_settings_->GetBoolean(
+ chromeos::kReportDeviceLocation, &report_location_);
+
+ if (report_location_) {
+ ScheduleGeolocationUpdateRequest();
+ } else {
+ geolocation_update_timer_.Stop();
+ position_ = content::Geoposition();
+ local_state_->ClearPref(prefs::kDeviceLocation);
+ }
}
Time DeviceStatusCollector::GetCurrentTime() {
@@ -133,7 +200,7 @@ Time DeviceStatusCollector::GetCurrentTime() {
// Remove all out-of-range activity times from the local store.
void DeviceStatusCollector::PruneStoredActivityPeriods(Time base_time) {
- const DictionaryValue* activity_times =
+ const base::DictionaryValue* activity_times =
local_state_->GetDictionary(prefs::kDeviceActivityTimes);
if (activity_times->size() <=
max_stored_past_activity_days_ + max_stored_future_activity_days_)
@@ -145,8 +212,8 @@ void DeviceStatusCollector::PruneStoredActivityPeriods(Time base_time) {
base_time + TimeDelta::FromDays(max_stored_future_activity_days_);
const Time epoch = Time::UnixEpoch();
- scoped_ptr<DictionaryValue> copy(activity_times->DeepCopy());
- for (DictionaryValue::key_iterator it = activity_times->begin_keys();
+ scoped_ptr<base::DictionaryValue> copy(activity_times->DeepCopy());
+ for (base::DictionaryValue::key_iterator it = activity_times->begin_keys();
it != activity_times->end_keys(); ++it) {
int64 timestamp;
@@ -167,7 +234,7 @@ void DeviceStatusCollector::AddActivePeriod(Time start, Time end) {
// Maintain the list of active periods in a local_state pref.
DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes);
- DictionaryValue* activity_times = update.Get();
+ base::DictionaryValue* activity_times = update.Get();
Time midnight = end.LocalMidnight();
@@ -201,8 +268,9 @@ void DeviceStatusCollector::IdleStateCallback(IdleState state) {
// interval of activity.
int active_seconds = (now - last_idle_check_).InSeconds();
if (active_seconds < 0 ||
- active_seconds >= static_cast<int>((2 * kPollIntervalSeconds)))
- AddActivePeriod(now - TimeDelta::FromSeconds(kPollIntervalSeconds), now);
+ active_seconds >= static_cast<int>((2 * kIdlePollIntervalSeconds)))
+ AddActivePeriod(now - TimeDelta::FromSeconds(kIdlePollIntervalSeconds),
+ now);
else
AddActivePeriod(last_idle_check_, now);
@@ -214,9 +282,9 @@ void DeviceStatusCollector::IdleStateCallback(IdleState state) {
void DeviceStatusCollector::GetActivityTimes(
em::DeviceStatusReportRequest* request) {
DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes);
- DictionaryValue* activity_times = update.Get();
+ base::DictionaryValue* activity_times = update.Get();
- for (DictionaryValue::key_iterator it = activity_times->begin_keys();
+ for (base::DictionaryValue::key_iterator it = activity_times->begin_keys();
it != activity_times->end_keys(); ++it) {
int64 start_timestamp;
int activity_milliseconds;
@@ -258,6 +326,32 @@ void DeviceStatusCollector::GetBootMode(
}
}
+void 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);
+ }
+}
+
void DeviceStatusCollector::GetStatus(em::DeviceStatusReportRequest* request) {
if (report_activity_times_)
GetActivityTimes(request);
@@ -267,6 +361,9 @@ void DeviceStatusCollector::GetStatus(em::DeviceStatusReportRequest* request) {
if (report_boot_mode_)
GetBootMode(request);
+
+ if (report_location_)
+ GetLocation(request);
}
void DeviceStatusCollector::OnOSVersion(VersionLoader::Handle handle,
@@ -289,4 +386,59 @@ void DeviceStatusCollector::Observe(
NOTREACHED();
}
+void DeviceStatusCollector::ScheduleGeolocationUpdateRequest() {
+ if (geolocation_update_timer_.IsRunning() || geolocation_update_in_progress_)
+ return;
+
+ if (position_.Validate()) {
+ TimeDelta elapsed = Time::Now() - position_.timestamp;
+ TimeDelta interval =
+ TimeDelta::FromSeconds(kGeolocationPollIntervalSeconds);
+ if (elapsed > interval) {
+ geolocation_update_in_progress_ = true;
+ location_update_requester_(base::Bind(
+ &DeviceStatusCollector::ReceiveGeolocationUpdate,
+ weak_factory_.GetWeakPtr()));
+ } else {
+ geolocation_update_timer_.Start(
+ FROM_HERE,
+ interval - elapsed,
+ this,
+ &DeviceStatusCollector::ScheduleGeolocationUpdateRequest);
+ }
+ } else {
+ geolocation_update_in_progress_ = true;
+ location_update_requester_(base::Bind(
+ &DeviceStatusCollector::ReceiveGeolocationUpdate,
+ weak_factory_.GetWeakPtr()));
+
+ }
+}
+
+void DeviceStatusCollector::ReceiveGeolocationUpdate(
+ const content::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();
+}
+
} // namespace policy
diff --git a/chrome/browser/policy/device_status_collector.h b/chrome/browser/policy/device_status_collector.h
index 4afffcb..254a318 100644
--- a/chrome/browser/policy/device_status_collector.h
+++ b/chrome/browser/policy/device_status_collector.h
@@ -6,11 +6,19 @@
#define CHROME_BROWSER_POLICY_DEVICE_STATUS_COLLECTOR_H_
#pragma once
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
#include "base/time.h"
#include "base/timer.h"
+#include "chrome/browser/cancelable_request.h"
#include "chrome/browser/chromeos/version_loader.h"
#include "chrome/browser/idle.h"
+#include "content/public/browser/geolocation.h"
#include "content/public/browser/notification_observer.h"
+#include "content/public/common/geoposition.h"
namespace chromeos {
class CrosSettings;
@@ -19,6 +27,11 @@ class StatisticsProvider;
}
}
+namespace content {
+class NotificationDetails;
+class NotificationSource;
+}
+
namespace enterprise_management {
class DeviceStatusReportRequest;
}
@@ -30,8 +43,14 @@ namespace policy {
// Collects and summarizes the status of an enterprised-managed ChromeOS device.
class DeviceStatusCollector : public content::NotificationObserver {
public:
+ // TODO(bartfab): Remove this once crbug.com/125931 is addressed and a proper
+ // way to mock geolocation exists.
+ typedef void(*LocationUpdateRequester)(
+ const content::GeolocationUpdateCallback& callback);
+
DeviceStatusCollector(PrefService* local_state,
- chromeos::system::StatisticsProvider* provider);
+ chromeos::system::StatisticsProvider* provider,
+ LocationUpdateRequester location_update_requester);
virtual ~DeviceStatusCollector();
void GetStatus(enterprise_management::DeviceStatusReportRequest* request);
@@ -39,7 +58,7 @@ class DeviceStatusCollector : public content::NotificationObserver {
static void RegisterPrefs(PrefService* local_state);
// How often, in seconds, to poll to see if the user is idle.
- static const unsigned int kPollIntervalSeconds = 30;
+ static const unsigned int kIdlePollIntervalSeconds = 30;
protected:
// Check whether the user has been idle for a certain period of time.
@@ -80,6 +99,8 @@ class DeviceStatusCollector : public content::NotificationObserver {
enterprise_management::DeviceStatusReportRequest* request);
void GetBootMode(
enterprise_management::DeviceStatusReportRequest* request);
+ void GetLocation(
+ enterprise_management::DeviceStatusReportRequest* request);
// Update the cached values of the reporting settings.
void UpdateReportingSettings();
@@ -90,6 +111,11 @@ class DeviceStatusCollector : public content::NotificationObserver {
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ void ScheduleGeolocationUpdateRequest();
+
+ // content::GeolocationUpdateCallback implementation.
+ void ReceiveGeolocationUpdate(const content::Geoposition&);
+
// How often to poll to see if the user is idle.
int poll_interval_seconds_;
@@ -98,7 +124,11 @@ class DeviceStatusCollector : public content::NotificationObserver {
// The last time an idle state check was performed.
base::Time last_idle_check_;
- base::RepeatingTimer<DeviceStatusCollector> timer_;
+ // Whether a geolocation update is currently in progress.
+ bool geolocation_update_in_progress_;
+
+ base::RepeatingTimer<DeviceStatusCollector> idle_poll_timer_;
+ base::OneShotTimer<DeviceStatusCollector> geolocation_update_timer_;
chromeos::VersionLoader version_loader_;
CancelableRequestConsumer consumer_;
@@ -106,14 +136,23 @@ class DeviceStatusCollector : public content::NotificationObserver {
std::string os_version_;
std::string firmware_version_;
+ content::Geoposition position_;
+
chromeos::system::StatisticsProvider* statistics_provider_;
chromeos::CrosSettings* cros_settings_;
+ base::WeakPtrFactory<DeviceStatusCollector> weak_factory_;
+
+ // TODO(bartfab): Remove this once crbug.com/125931 is addressed and a proper
+ // way to mock geolocation exists.
+ LocationUpdateRequester location_update_requester_;
+
// Cached values of the reporting settings from the device policy.
bool report_version_info_;
bool report_activity_times_;
bool report_boot_mode_;
+ bool report_location_;
DISALLOW_COPY_AND_ASSIGN(DeviceStatusCollector);
};
diff --git a/chrome/browser/policy/device_status_collector_unittest.cc b/chrome/browser/policy/device_status_collector_unittest.cc
index 3dcfb3f..ca4ff99 100644
--- a/chrome/browser/policy/device_status_collector_unittest.cc
+++ b/chrome/browser/policy/device_status_collector_unittest.cc
@@ -4,21 +4,29 @@
#include "chrome/browser/policy/device_status_collector.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
-#include "base/time.h"
-#include "chrome/browser/idle.h"
#include "chrome/browser/chromeos/cros_settings.h"
#include "chrome/browser/chromeos/cros_settings_names.h"
#include "chrome/browser/chromeos/cros_settings_provider.h"
#include "chrome/browser/chromeos/stub_cros_settings_provider.h"
#include "chrome/browser/chromeos/system/mock_statistics_provider.h"
+#include "chrome/browser/chromeos/system/statistics_provider.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_pref_service.h"
+#include "content/public/browser/browser_thread.h"
#include "content/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::NotNull;
+using ::testing::Return;
+using ::testing::SetArgPointee;
using base::TimeDelta;
using base::Time;
@@ -28,13 +36,36 @@ namespace {
const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
+scoped_ptr<content::Geoposition> mock_position_to_return_next;
+
+void SetMockPositionToReturnNext(const content::Geoposition &position) {
+ mock_position_to_return_next.reset(new content::Geoposition(position));
+}
+
+void MockPositionUpdateRequester(
+ const content::GeolocationUpdateCallback& callback) {
+ if (!mock_position_to_return_next.get())
+ return;
+
+ // If the fix is invalid, the DeviceStatusCollector will immediately request
+ // another update when it receives the callback. This is desirable and safe in
+ // real life where geolocation updates arrive asynchronously. In this testing
+ // harness, the callback is invoked synchronously upon request, leading to a
+ // request-callback loop. The loop is broken by returning the mock position
+ // only once.
+ scoped_ptr<content::Geoposition> position(
+ mock_position_to_return_next.release());
+ callback.Run(*position);
+}
+
class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
public:
TestingDeviceStatusCollector(
PrefService* local_state,
chromeos::system::StatisticsProvider* provider)
- : policy::DeviceStatusCollector(local_state, provider),
- local_state_(local_state) {
+ : policy::DeviceStatusCollector(local_state,
+ provider,
+ &MockPositionUpdateRequester) {
// Set the baseline time to a fixed value (1 AM) to prevent test flakiness
// due to a single activity period spanning two days.
SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
@@ -68,14 +99,12 @@ class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
// Each time this is called, returns a time that is a fixed increment
// later than the previous time.
virtual Time GetCurrentTime() OVERRIDE {
- int poll_interval = policy::DeviceStatusCollector::kPollIntervalSeconds;
+ int poll_interval = policy::DeviceStatusCollector::kIdlePollIntervalSeconds;
return baseline_time_ +
TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++);
}
private:
- PrefService* local_state_;
-
// Baseline time for the fake times returned from GetCurrentTime().
Time baseline_time_;
@@ -97,32 +126,28 @@ int64 GetActiveMilliseconds(em::DeviceStatusReportRequest& status) {
namespace policy {
-using ::testing::_;
-using ::testing::NotNull;
-using ::testing::Return;
-using ::testing::SetArgPointee;
-
class DeviceStatusCollectorTest : public testing::Test {
public:
DeviceStatusCollectorTest()
: message_loop_(MessageLoop::TYPE_UI),
ui_thread_(content::BrowserThread::UI, &message_loop_),
file_thread_(content::BrowserThread::FILE, &message_loop_),
- status_collector_(&prefs_, &statistics_provider_) {
+ io_thread_(content::BrowserThread::IO, &message_loop_) {
+ TestingDeviceStatusCollector::RegisterPrefs(&prefs_);
- DeviceStatusCollector::RegisterPrefs(&prefs_);
EXPECT_CALL(statistics_provider_, GetMachineStatistic(_, NotNull()))
.WillRepeatedly(Return(false));
- cros_settings_ = chromeos::CrosSettings::Get();
-
// Remove the real DeviceSettingsProvider and replace it with a stub.
+ cros_settings_ = chromeos::CrosSettings::Get();
device_settings_provider_ =
cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo);
EXPECT_TRUE(device_settings_provider_ != NULL);
EXPECT_TRUE(
cros_settings_->RemoveSettingsProvider(device_settings_provider_));
cros_settings_->AddSettingsProvider(&stub_settings_provider_);
+
+ RestartStatusCollector();
}
~DeviceStatusCollectorTest() {
@@ -132,19 +157,69 @@ class DeviceStatusCollectorTest : public testing::Test {
cros_settings_->AddSettingsProvider(device_settings_provider_);
}
+ void RestartStatusCollector() {
+ status_collector_.reset(
+ new TestingDeviceStatusCollector(&prefs_, &statistics_provider_));
+ }
+
+ void GetStatus() {
+ status_.Clear();
+ status_collector_->GetStatus(&status_);
+ }
+
+ void CheckThatNoLocationIsReported() {
+ GetStatus();
+ EXPECT_FALSE(status_.has_device_location());
+ }
+
+ void CheckThatAValidLocationIsReported() {
+ // Checks that a location is being reported which matches the valid fix
+ // set using SetMockPositionToReturnNext().
+ GetStatus();
+ EXPECT_TRUE(status_.has_device_location());
+ em::DeviceLocation location = status_.device_location();
+ if (location.has_error_code())
+ EXPECT_EQ(em::DeviceLocation::ERROR_CODE_NONE, location.error_code());
+ EXPECT_TRUE(location.has_latitude());
+ EXPECT_TRUE(location.has_longitude());
+ EXPECT_TRUE(location.has_accuracy());
+ EXPECT_TRUE(location.has_timestamp());
+ EXPECT_FALSE(location.has_altitude());
+ EXPECT_FALSE(location.has_altitude_accuracy());
+ EXPECT_FALSE(location.has_heading());
+ EXPECT_FALSE(location.has_speed());
+ EXPECT_FALSE(location.has_error_message());
+ EXPECT_DOUBLE_EQ(4.3, location.latitude());
+ EXPECT_DOUBLE_EQ(-7.8, location.longitude());
+ EXPECT_DOUBLE_EQ(3., location.accuracy());
+ // Check that the timestamp is not older than ten minutes.
+ EXPECT_TRUE(Time::Now() - Time::FromDoubleT(location.timestamp() / 1000.) <
+ TimeDelta::FromMinutes(10));
+ }
+
+ void CheckThatALocationErrorIsReported() {
+ GetStatus();
+ EXPECT_TRUE(status_.has_device_location());
+ em::DeviceLocation location = status_.device_location();
+ EXPECT_TRUE(location.has_error_code());
+ EXPECT_EQ(em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE,
+ location.error_code());
+ }
+
protected:
// Convenience method.
int64 ActivePeriodMilliseconds() {
- return policy::DeviceStatusCollector::kPollIntervalSeconds * 1000;
+ return policy::DeviceStatusCollector::kIdlePollIntervalSeconds * 1000;
}
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread file_thread_;
+ content::TestBrowserThread io_thread_;
TestingPrefService prefs_;
chromeos::system::MockStatisticsProvider statistics_provider_;
- TestingDeviceStatusCollector status_collector_;
+ scoped_ptr<TestingDeviceStatusCollector> status_collector_;
em::DeviceStatusReportRequest status_;
chromeos::CrosSettings* cros_settings_;
chromeos::CrosSettingsProvider* device_settings_provider_;
@@ -160,20 +235,20 @@ TEST_F(DeviceStatusCollectorTest, AllIdle) {
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
// Test reporting with no data.
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
// Test reporting with a single idle sample.
- status_collector_.Simulate(test_states, 1);
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states, 1);
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
// Test reporting with multiple consecutive idle samples.
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
}
@@ -187,16 +262,16 @@ TEST_F(DeviceStatusCollectorTest, AllActive) {
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
// Test a single active sample.
- status_collector_.Simulate(test_states, 1);
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states, 1);
+ GetStatus();
EXPECT_EQ(1, status_.active_period_size());
EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
status_.clear_active_period(); // Clear the result protobuf.
// Test multiple consecutive active samples.
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(1, status_.active_period_size());
EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -212,9 +287,9 @@ TEST_F(DeviceStatusCollectorTest, MixedStates) {
IDLE_STATE_ACTIVE
};
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -228,18 +303,17 @@ TEST_F(DeviceStatusCollectorTest, StateKeptInPref) {
IDLE_STATE_IDLE
};
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
-
- // Process the list a second time with a different collector.
- // It should be able to count the active periods found by the first
- // collector, because the results are stored in a pref.
- TestingDeviceStatusCollector second_collector(&prefs_,
- &statistics_provider_);
- second_collector.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
-
- second_collector.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+
+ // Process the list a second time after restarting the collector. It should be
+ // able to count the active periods found by the original collector, because
+ // the results are stored in a pref.
+ RestartStatusCollector();
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+
+ GetStatus();
EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -253,9 +327,9 @@ TEST_F(DeviceStatusCollectorTest, Times) {
IDLE_STATE_IDLE
};
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -267,41 +341,41 @@ TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) {
unsigned int max_days = 10;
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.set_max_stored_past_activity_days(max_days - 1);
- status_collector_.set_max_stored_future_activity_days(1);
+ status_collector_->set_max_stored_past_activity_days(max_days - 1);
+ status_collector_->set_max_stored_future_activity_days(1);
Time baseline = Time::Now().LocalMidnight();
// Simulate 12 active periods.
for (int i = 0; i < static_cast<int>(max_days) + 2; i++) {
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
// Advance the simulated clock by a day.
baseline += TimeDelta::FromDays(1);
- status_collector_.SetBaselineTime(baseline);
+ status_collector_->SetBaselineTime(baseline);
}
// Check that we don't exceed the max number of periods.
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ(static_cast<int>(max_days), status_.active_period_size());
// Simulate some future times.
for (int i = 0; i < static_cast<int>(max_days) + 2; i++) {
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
// Advance the simulated clock by a day.
baseline += TimeDelta::FromDays(1);
- status_collector_.SetBaselineTime(baseline);
+ status_collector_->SetBaselineTime(baseline);
}
// Set the clock back so the previous simulated times are in the future.
baseline -= TimeDelta::FromDays(20);
- status_collector_.SetBaselineTime(baseline);
+ status_collector_->SetBaselineTime(baseline);
// Collect one more data point to trigger pruning.
- status_collector_.Simulate(test_states, 1);
+ status_collector_->Simulate(test_states, 1);
// Check that we don't exceed the max number of periods.
status_.clear_active_period();
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_LT(status_.active_period_size(), static_cast<int>(max_days));
}
@@ -314,9 +388,9 @@ TEST_F(DeviceStatusCollectorTest, ActivityTimesDisabledByDefault) {
IDLE_STATE_ACTIVE,
IDLE_STATE_ACTIVE
};
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
}
@@ -328,11 +402,11 @@ TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
// Set the baseline time to 10 seconds after midnight.
- status_collector_.SetBaselineTime(
+ status_collector_->SetBaselineTime(
Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
- status_collector_.Simulate(test_states, 1);
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states, 1);
+ GetStatus();
ASSERT_EQ(2, status_.active_period_size());
em::ActiveTimePeriod period0 = status_.active_period(0);
@@ -354,13 +428,11 @@ TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
// Test that boot mode data is not reported if the pref is not turned on.
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_boot_mode());
-
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillRepeatedly(DoAll(SetArgPointee<1>("0"), Return(true)));
- EXPECT_EQ(false, status_.has_boot_mode());
+ GetStatus();
+ EXPECT_FALSE(status_.has_boot_mode());
// Turn the pref on, and check that the status is reported iff the
// statistics provider returns valid data.
@@ -369,41 +441,41 @@ TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>("(error)"), Return(true)));
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_boot_mode());
+ GetStatus();
+ EXPECT_FALSE(status_.has_boot_mode());
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>(" "), Return(true)));
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_boot_mode());
+ GetStatus();
+ EXPECT_FALSE(status_.has_boot_mode());
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>("0"), Return(true)));
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ("Verified", status_.boot_mode());
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>("1"), Return(true)));
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ("Dev", status_.boot_mode());
}
TEST_F(DeviceStatusCollectorTest, VersionInfo) {
// When the pref to collect this data is not enabled, expect that none of
// the fields are present in the protobuf.
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_browser_version());
- EXPECT_EQ(false, status_.has_os_version());
- EXPECT_EQ(false, status_.has_firmware_version());
+ GetStatus();
+ EXPECT_FALSE(status_.has_browser_version());
+ EXPECT_FALSE(status_.has_os_version());
+ EXPECT_FALSE(status_.has_firmware_version());
cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, true);
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(true, status_.has_browser_version());
- EXPECT_EQ(true, status_.has_os_version());
- EXPECT_EQ(true, status_.has_firmware_version());
+ GetStatus();
+ EXPECT_TRUE(status_.has_browser_version());
+ EXPECT_TRUE(status_.has_os_version());
+ EXPECT_TRUE(status_.has_firmware_version());
// Check that the browser version is not empty. OS version & firmware
// don't have any reasonable values inside the unit test, so those
@@ -411,4 +483,53 @@ TEST_F(DeviceStatusCollectorTest, VersionInfo) {
EXPECT_NE("", status_.browser_version());
}
+TEST_F(DeviceStatusCollectorTest, Location) {
+ content::Geoposition valid_fix;
+ valid_fix.latitude = 4.3;
+ valid_fix.longitude = -7.8;
+ valid_fix.accuracy = 3.;
+ valid_fix.timestamp = Time::Now();
+
+ content::Geoposition invalid_fix;
+ invalid_fix.error_code =
+ content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ invalid_fix.timestamp = Time::Now();
+
+ // Check that when device location reporting is disabled, no location is
+ // reported.
+ SetMockPositionToReturnNext(valid_fix);
+ CheckThatNoLocationIsReported();
+
+ // Check that when device location reporting is enabled and a valid fix is
+ // available, the location is reported and is stored in local state.
+ SetMockPositionToReturnNext(valid_fix);
+ cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
+ EXPECT_FALSE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
+ CheckThatAValidLocationIsReported();
+
+ // Restart the status collector. Check that the last known location has been
+ // retrieved from local state without requesting a geolocation update.
+ SetMockPositionToReturnNext(valid_fix);
+ RestartStatusCollector();
+ CheckThatAValidLocationIsReported();
+ EXPECT_TRUE(mock_position_to_return_next.get());
+
+ // Check that after disabling location reporting again, the last known
+ // location has been cleared from local state and is no longer reported.
+ SetMockPositionToReturnNext(valid_fix);
+ cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, false);
+ // Allow the new pref to propagate to the status collector.
+ message_loop_.RunAllPending();
+ EXPECT_TRUE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
+ CheckThatNoLocationIsReported();
+
+ // Check that after enabling location reporting again, an error is reported
+ // if no valid fix is available.
+ SetMockPositionToReturnNext(invalid_fix);
+ cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
+ // Allow the new pref to propagate to the status collector.
+ message_loop_.RunAllPending();
+ CheckThatALocationErrorIsReported();
+}
+
} // namespace policy
diff --git a/chrome/browser/policy/proto/device_management_backend.proto b/chrome/browser/policy/proto/device_management_backend.proto
index b6396020..0d0cfb9 100644
--- a/chrome/browser/policy/proto/device_management_backend.proto
+++ b/chrome/browser/policy/proto/device_management_backend.proto
@@ -264,6 +264,44 @@ message InstallableLaunch {
optional int64 total_count = 4;
}
+// Used to report the device location.
+message DeviceLocation {
+ enum ErrorCode {
+ ERROR_CODE_NONE = 0;
+ ERROR_CODE_POSITION_UNAVAILABLE = 1;
+ }
+
+ // Latitude in decimal degrees north (WGS84 coordinate frame).
+ optional double latitude = 1;
+
+ // Longitude in decimal degrees west (WGS84 coordinate frame).
+ optional double longitude = 2;
+
+ // Altitude in meters (above WGS84 datum).
+ optional double altitude = 3;
+
+ // Accuracy of horizontal position in meters.
+ optional double accuracy = 4;
+
+ // Accuracy of altitude in meters.
+ optional double altitude_accuracy = 5;
+
+ // Heading in decimal degrees clockwise from true north.
+ optional double heading = 6;
+
+ // Horizontal component of device velocity in meters per second.
+ optional double speed = 7;
+
+ // Time of position measurement in milisecons since Epoch in UTC time.
+ optional int64 timestamp = 8;
+
+ // Error code, see enum above.
+ optional ErrorCode error_code = 9;
+
+ // Human-readable error message.
+ optional string error_message = 10;
+}
+
// Report device level status.
message DeviceStatusReportRequest {
optional string os_version = 1;
@@ -281,6 +319,9 @@ message DeviceStatusReportRequest {
// A list of periods when the device was active, aggregated by day.
repeated ActiveTimePeriod active_period = 6;
+
+ // The device location.
+ optional DeviceLocation device_location = 7;
}
// Report session (a user on one device) level status.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 9bc1859..10cf870 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1655,17 +1655,13 @@ const char kShouldAutoEnroll[] = "ShouldAutoEnroll";
// modulus, then it will retry auto-enrollment using the updated value.
const char kAutoEnrollmentPowerLimit[] = "AutoEnrollmentPowerLimit";
-// A boolean pref that indicates whether OS & firmware version info should be
-// reported along with device policy requests.
-const char kReportDeviceVersionInfo[] = "device_status.report_version_info";
-
-// A boolean pref that indicates whether device activity times should be
-// recorded and reported along with device policy requests.
-const char kReportDeviceActivityTimes[] = "device_status.report_activity_times";
-
// The local state pref that stores device activity times before reporting
// them to the policy server.
-extern const char kDeviceActivityTimes[] = "device_status.activity_times";
+const char kDeviceActivityTimes[] = "device_status.activity_times";
+
+// A pref holding the last known location when device location reporting is
+// enabled.
+const char kDeviceLocation[] = "device_status.location";
// A string that is used to store first-time sync startup after once sync is
// disabled. This will be refreshed every sign-in.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index b71b068..87a5411 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -628,9 +628,8 @@ extern const char kHardwareKeyboardLayout[];
extern const char kCarrierDealPromoShown[];
extern const char kShouldAutoEnroll[];
extern const char kAutoEnrollmentPowerLimit[];
-extern const char kReportDeviceVersionInfo[];
-extern const char kReportDeviceActivityTimes[];
extern const char kDeviceActivityTimes[];
+extern const char kDeviceLocation[];
extern const char kSyncSpareBootstrapToken[];
#endif