summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordubroy@chromium.org <dubroy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-16 16:33:40 +0000
committerdubroy@chromium.org <dubroy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-16 16:33:40 +0000
commit262ff6bcd7cf6fbaef3376bfa18d762b21556153 (patch)
tree6110a517ff6cf5ef3941a4b1890dd41eae3c4c15
parent04f51f5808cb973d7910d936d35dde87d9fc9edf (diff)
downloadchromium_src-262ff6bcd7cf6fbaef3376bfa18d762b21556153.zip
chromium_src-262ff6bcd7cf6fbaef3376bfa18d762b21556153.tar.gz
chromium_src-262ff6bcd7cf6fbaef3376bfa18d762b21556153.tar.bz2
Aggregate device activity, and report per-day activity in device status reports.
BUG=chromium-os:26372 TEST=Manual. Review URL: http://codereview.chromium.org/9348105 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122299 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/policy/device_status_collector.cc173
-rw-r--r--chrome/browser/policy/device_status_collector.h17
-rw-r--r--chrome/browser/policy/device_status_collector_unittest.cc124
-rw-r--r--chrome/browser/policy/proto/device_management_backend.proto12
-rw-r--r--chrome/common/pref_names.cc4
-rw-r--r--chrome/common/pref_names.h1
6 files changed, 224 insertions, 107 deletions
diff --git a/chrome/browser/policy/device_status_collector.cc b/chrome/browser/policy/device_status_collector.cc
index f4fb746..7017207 100644
--- a/chrome/browser/policy/device_status_collector.cc
+++ b/chrome/browser/policy/device_status_collector.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_version_info.h"
+#include "chrome/common/pref_names.h"
using base::Time;
using base::TimeDelta;
@@ -26,17 +27,26 @@ namespace {
// How many seconds of inactivity triggers the idle state.
const unsigned int kIdleStateThresholdSeconds = 300;
-// The maximum number of time periods stored in the local state.
-const unsigned int kMaxStoredActivePeriods = 500;
-
-// Stores a list of timestamps representing device active periods.
-const char* const kPrefDeviceActivePeriods = "device_status.active_periods";
-
-bool GetTimestamp(const ListValue* list, int index, int64* out_value) {
- std::string string_value;
- if (list->GetString(index, &string_value))
- return base::StringToInt64(string_value, out_value);
- return false;
+// How many days in the past to store active periods for.
+const unsigned int kMaxStoredPastActivityDays = 30;
+
+// How many days in the future to store active periods for.
+const unsigned int kMaxStoredFutureActivityDays = 2;
+
+const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
+
+// Record device activity for the specified day into the given dictionary.
+void AddDeviceActivity(DictionaryValue* activity_times,
+ Time day_midnight,
+ TimeDelta activity) {
+ DCHECK(activity.InMilliseconds() < kMillisecondsPerDay);
+ int64 day_start_timestamp =
+ (day_midnight - Time::UnixEpoch()).InMilliseconds();
+ std::string day_key = base::Int64ToString(day_start_timestamp);
+ int previous_activity = 0;
+ activity_times->GetInteger(day_key, &previous_activity);
+ activity_times->SetInteger(day_key,
+ previous_activity + activity.InMilliseconds());
}
} // namespace
@@ -46,17 +56,16 @@ namespace policy {
DeviceStatusCollector::DeviceStatusCollector(
PrefService* local_state,
chromeos::system::StatisticsProvider* provider)
- : max_stored_active_periods_(kMaxStoredActivePeriods),
+ : max_stored_past_activity_days_(kMaxStoredPastActivityDays),
+ max_stored_future_activity_days_(kMaxStoredFutureActivityDays),
local_state_(local_state),
last_idle_check_(Time()),
- last_idle_state_(IDLE_STATE_UNKNOWN),
statistics_provider_(provider),
report_version_info_(false),
report_activity_times_(false),
report_boot_mode_(false) {
timer_.Start(FROM_HERE,
- TimeDelta::FromSeconds(
- DeviceStatusCollector::kPollIntervalSeconds),
+ TimeDelta::FromSeconds(kPollIntervalSeconds),
this, &DeviceStatusCollector::CheckIdleState);
cros_settings_ = chromeos::CrosSettings::Get();
@@ -91,7 +100,8 @@ DeviceStatusCollector::~DeviceStatusCollector() {
// static
void DeviceStatusCollector::RegisterPrefs(PrefService* local_state) {
- local_state->RegisterListPref(kPrefDeviceActivePeriods, new ListValue);
+ local_state->RegisterDictionaryPref(prefs::kDeviceActivityTimes,
+ new DictionaryValue);
}
void DeviceStatusCollector::CheckIdleState() {
@@ -122,36 +132,61 @@ Time DeviceStatusCollector::GetCurrentTime() {
return Time::Now();
}
+// Remove all out-of-range activity times from the local store.
+void DeviceStatusCollector::PruneStoredActivityPeriods(Time base_time) {
+ const DictionaryValue* activity_times =
+ local_state_->GetDictionary(prefs::kDeviceActivityTimes);
+ if (activity_times->size() <=
+ max_stored_past_activity_days_ + max_stored_future_activity_days_)
+ return;
+
+ Time min_time =
+ base_time - TimeDelta::FromDays(max_stored_past_activity_days_);
+ Time max_time =
+ base_time + TimeDelta::FromDays(max_stored_future_activity_days_);
+ const Time epoch = Time::UnixEpoch();
+
+ DictionaryValue* copy = activity_times->DeepCopy();
+ for (DictionaryValue::key_iterator it = activity_times->begin_keys();
+ it != activity_times->end_keys(); ++it) {
+ int64 timestamp;
+
+ if (base::StringToInt64(*it, &timestamp)) {
+ // Remove data that is too old, or too far in the future.
+ Time day_midnight = epoch + TimeDelta::FromMilliseconds(timestamp);
+ if (day_midnight > min_time && day_midnight < max_time)
+ continue;
+ }
+ // The entry is out of range or couldn't be parsed. Remove it.
+ copy->Remove(*it, NULL);
+ }
+ local_state_->Set(prefs::kDeviceActivityTimes, *copy);
+}
+
void DeviceStatusCollector::AddActivePeriod(Time start, Time end) {
+ DCHECK(start < end);
+
// Maintain the list of active periods in a local_state pref.
- ListPrefUpdate update(local_state_, kPrefDeviceActivePeriods);
- ListValue* active_periods = update.Get();
+ DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes);
+ DictionaryValue* activity_times = update.Get();
- // Cap the number of active periods that we store.
- if (active_periods->GetSize() >= 2 * max_stored_active_periods_)
- return;
+ Time midnight = end.LocalMidnight();
- Time epoch = Time::UnixEpoch();
- int64 start_timestamp = (start - epoch).InMilliseconds();
- Value* end_value = new StringValue(
- base::Int64ToString((end - epoch).InMilliseconds()));
-
- int list_size = active_periods->GetSize();
- DCHECK(list_size % 2 == 0);
-
- // Check if this period can be combined with the previous one.
- if (list_size > 0 && last_idle_state_ == IDLE_STATE_ACTIVE) {
- int64 last_period_end;
- if (GetTimestamp(active_periods, list_size - 1, &last_period_end) &&
- last_period_end == start_timestamp) {
- active_periods->Set(list_size - 1, end_value);
- return;
- }
+ // Figure out UTC midnight on the same day as the local day.
+ Time::Exploded exploded;
+ midnight.LocalExplode(&exploded);
+ Time utc_midnight = Time::FromUTCExploded(exploded);
+
+ // Record the device activity for today.
+ TimeDelta activity_today = end - MAX(midnight, start);
+ AddDeviceActivity(activity_times, utc_midnight, activity_today);
+
+ // If this interval spans two days, record activity for yesterday too.
+ if (start < midnight) {
+ AddDeviceActivity(activity_times,
+ utc_midnight - TimeDelta::FromDays(1),
+ midnight - start);
}
- // Add a new period to the list.
- active_periods->Append(
- new StringValue(base::Int64ToString(start_timestamp)));
- active_periods->Append(end_value);
}
void DeviceStatusCollector::IdleStateCallback(IdleState state) {
@@ -162,44 +197,46 @@ void DeviceStatusCollector::IdleStateCallback(IdleState state) {
Time now = GetCurrentTime();
if (state == IDLE_STATE_ACTIVE) {
- unsigned int poll_interval = DeviceStatusCollector::kPollIntervalSeconds;
-
- // If it's been too long since the last report, assume that the system was
- // in standby, and only count a single interval of activity.
- if ((now - last_idle_check_).InSeconds() >= (2 * poll_interval))
- AddActivePeriod(now - TimeDelta::FromSeconds(poll_interval), now);
+ // If it's been too long since the last report, or if the activity is
+ // negative (which can happen when the clock changes), assume a single
+ // 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);
else
AddActivePeriod(last_idle_check_, now);
+
+ PruneStoredActivityPeriods(now);
}
last_idle_check_ = now;
- last_idle_state_ = state;
}
void DeviceStatusCollector::GetActivityTimes(
em::DeviceStatusReportRequest* request) {
- const ListValue* active_periods =
- local_state_->GetList(kPrefDeviceActivePeriods);
- em::TimePeriod* time_period;
-
- DCHECK(active_periods->GetSize() % 2 == 0);
-
- int period_count = active_periods->GetSize() / 2;
- for (int i = 0; i < period_count; i++) {
- int64 start, end;
-
- if (!GetTimestamp(active_periods, 2 * i, &start) ||
- !GetTimestamp(active_periods, 2 * i + 1, &end) ||
- end < start) {
- // Something is amiss -- bail out.
+ DictionaryPrefUpdate update(local_state_, prefs::kDeviceActivityTimes);
+ DictionaryValue* activity_times = update.Get();
+
+ for (DictionaryValue::key_iterator it = activity_times->begin_keys();
+ it != activity_times->end_keys(); ++it) {
+ int64 start_timestamp;
+ int activity_milliseconds;
+ if (base::StringToInt64(*it, &start_timestamp) &&
+ activity_times->GetInteger(*it, &activity_milliseconds)) {
+ // This is correct even when there are leap seconds, because when a leap
+ // second occurs, two consecutive seconds have the same timestamp.
+ int64 end_timestamp = start_timestamp + kMillisecondsPerDay;
+
+ em::ActiveTimePeriod* active_period = request->add_active_period();
+ em::TimePeriod* period = active_period->mutable_time_period();
+ period->set_start_timestamp(start_timestamp);
+ period->set_end_timestamp(end_timestamp);
+ active_period->set_active_duration(activity_milliseconds);
+ } else {
NOTREACHED();
- break;
}
- time_period = request->add_active_time();
- time_period->set_start_timestamp(start);
- time_period->set_end_timestamp(end);
}
- ListPrefUpdate update(local_state_, kPrefDeviceActivePeriods);
- update.Get()->Clear();
+ activity_times->Clear();
}
void DeviceStatusCollector::GetVersionInfo(
diff --git a/chrome/browser/policy/device_status_collector.h b/chrome/browser/policy/device_status_collector.h
index 1d6d1f0..4afffcb 100644
--- a/chrome/browser/policy/device_status_collector.h
+++ b/chrome/browser/policy/device_status_collector.h
@@ -51,10 +51,20 @@ class DeviceStatusCollector : public content::NotificationObserver {
// Callback which receives the results of the idle state check.
void IdleStateCallback(IdleState state);
- // The maximum number of active periods timestamps to be stored.
- unsigned int max_stored_active_periods_;
+ // The number of days in the past to store device activity.
+ // This is kept in case device status uploads fail for a number of days.
+ unsigned int max_stored_past_activity_days_;
+
+ // The number of days in the future to store device activity.
+ // When changing the system time and/or timezones, it's possible to record
+ // activity time that is slightly in the future.
+ unsigned int max_stored_future_activity_days_;
private:
+ // Prevents the local store of activity periods from growing too large by
+ // removing entries that are outside the reporting window.
+ void PruneStoredActivityPeriods(base::Time base_time);
+
void AddActivePeriod(base::Time start, base::Time end);
// Callbacks from chromeos::VersionLoader.
@@ -88,9 +98,6 @@ class DeviceStatusCollector : public content::NotificationObserver {
// The last time an idle state check was performed.
base::Time last_idle_check_;
- // The idle state the last time it was checked.
- IdleState last_idle_state_;
-
base::RepeatingTimer<DeviceStatusCollector> timer_;
chromeos::VersionLoader version_loader_;
diff --git a/chrome/browser/policy/device_status_collector_unittest.cc b/chrome/browser/policy/device_status_collector_unittest.cc
index 96a77ed..3dcfb3f 100644
--- a/chrome/browser/policy/device_status_collector_unittest.cc
+++ b/chrome/browser/policy/device_status_collector_unittest.cc
@@ -26,14 +26,18 @@ namespace em = enterprise_management;
namespace {
+const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
+
class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
public:
TestingDeviceStatusCollector(
PrefService* local_state,
chromeos::system::StatisticsProvider* provider)
: policy::DeviceStatusCollector(local_state, provider),
- local_state_(local_state),
- baseline_time_(Time::Now()) {
+ local_state_(local_state) {
+ // 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));
}
void Simulate(IdleState* states, int len) {
@@ -41,13 +45,18 @@ class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
IdleStateCallback(states[i]);
}
- void SimulateWithSleep(IdleState* states, int len, int ) {
- for (int i = 0; i < len; i++)
- IdleStateCallback(states[i]);
+ void set_max_stored_past_activity_days(unsigned int value) {
+ max_stored_past_activity_days_ = value;
+ }
+
+ void set_max_stored_future_activity_days(unsigned int value) {
+ max_stored_future_activity_days_ = value;
}
- void set_max_stored_active_periods(unsigned int value) {
- max_stored_active_periods_ = value;
+ // Reset the baseline time.
+ void SetBaselineTime(Time time) {
+ baseline_time_ = time;
+ baseline_offset_periods_ = 0;
}
protected:
@@ -59,27 +68,27 @@ 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 {
- static int call_count = 0;
- return baseline_time_ + TimeDelta::FromSeconds(
- policy::DeviceStatusCollector::kPollIntervalSeconds * call_count++);
+ int poll_interval = policy::DeviceStatusCollector::kPollIntervalSeconds;
+ return baseline_time_ +
+ TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++);
}
private:
PrefService* local_state_;
// Baseline time for the fake times returned from GetCurrentTime().
- // It doesn't really matter what this is, as long as it stays the same over
- // the lifetime of the object.
Time baseline_time_;
+
+ // The number of simulated periods since the baseline time.
+ int baseline_offset_periods_;
};
// Return the total number of active milliseconds contained in a device
// status report.
int64 GetActiveMilliseconds(em::DeviceStatusReportRequest& status) {
int64 active_milliseconds = 0;
- for (int i = 0; i < status.active_time_size(); i++) {
- const em::TimePeriod& period = status.active_time(i);
- active_milliseconds += period.end_timestamp() - period.start_timestamp();
+ for (int i = 0; i < status.active_period_size(); i++) {
+ active_milliseconds += status.active_period(i).active_duration();
}
return active_milliseconds;
}
@@ -152,20 +161,20 @@ TEST_F(DeviceStatusCollectorTest, AllIdle) {
// Test reporting with no data.
status_collector_.GetStatus(&status_);
- EXPECT_EQ(0, status_.active_time_size());
+ 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_);
- EXPECT_EQ(0, status_.active_time_size());
+ 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_);
- EXPECT_EQ(0, status_.active_time_size());
+ EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
}
@@ -180,16 +189,15 @@ TEST_F(DeviceStatusCollectorTest, AllActive) {
// Test a single active sample.
status_collector_.Simulate(test_states, 1);
status_collector_.GetStatus(&status_);
- EXPECT_EQ(1, status_.active_time_size());
+ EXPECT_EQ(1, status_.active_period_size());
EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
- status_.clear_active_time(); // Clear the result protobuf.
+ status_.clear_active_period(); // Clear the result protobuf.
- // Test multiple consecutive active samples -- they should be coalesced
- // into a single active period.
+ // Test multiple consecutive active samples.
status_collector_.Simulate(test_states,
sizeof(test_states) / sizeof(IdleState));
status_collector_.GetStatus(&status_);
- EXPECT_EQ(1, status_.active_time_size());
+ EXPECT_EQ(1, status_.active_period_size());
EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -207,7 +215,6 @@ TEST_F(DeviceStatusCollectorTest, MixedStates) {
status_collector_.Simulate(test_states,
sizeof(test_states) / sizeof(IdleState));
status_collector_.GetStatus(&status_);
- EXPECT_EQ(3, status_.active_time_size());
EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -233,7 +240,6 @@ TEST_F(DeviceStatusCollectorTest, StateKeptInPref) {
sizeof(test_states) / sizeof(IdleState));
second_collector.GetStatus(&status_);
- EXPECT_EQ(4, status_.active_time_size());
EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -250,8 +256,6 @@ TEST_F(DeviceStatusCollectorTest, Times) {
status_collector_.Simulate(test_states,
sizeof(test_states) / sizeof(IdleState));
status_collector_.GetStatus(&status_);
- EXPECT_EQ(2, status_.active_time_size());
-
EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -260,20 +264,45 @@ TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) {
IDLE_STATE_ACTIVE,
IDLE_STATE_IDLE
};
- unsigned int max_periods = 10;
+ unsigned int max_days = 10;
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.set_max_stored_active_periods(max_periods);
+ 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 < 12; i++) {
+ for (int i = 0; i < static_cast<int>(max_days) + 2; i++) {
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);
}
// Check that we don't exceed the max number of periods.
status_collector_.GetStatus(&status_);
- EXPECT_EQ(static_cast<int>(max_periods), status_.active_time_size());
+ 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));
+ // Advance the simulated clock by a day.
+ baseline += TimeDelta::FromDays(1);
+ 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);
+
+ // Collect one more data point to trigger pruning.
+ 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_);
+ EXPECT_LT(status_.active_period_size(), static_cast<int>(max_days));
}
TEST_F(DeviceStatusCollectorTest, ActivityTimesDisabledByDefault) {
@@ -288,10 +317,41 @@ TEST_F(DeviceStatusCollectorTest, ActivityTimesDisabledByDefault) {
status_collector_.Simulate(test_states,
sizeof(test_states) / sizeof(IdleState));
status_collector_.GetStatus(&status_);
- EXPECT_EQ(0, status_.active_time_size());
+ EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
}
+TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
+ IdleState test_states[] = {
+ IDLE_STATE_ACTIVE
+ };
+ cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
+
+ // Set the baseline time to 10 seconds after midnight.
+ status_collector_.SetBaselineTime(
+ Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
+
+ status_collector_.Simulate(test_states, 1);
+ status_collector_.GetStatus(&status_);
+ ASSERT_EQ(2, status_.active_period_size());
+
+ em::ActiveTimePeriod period0 = status_.active_period(0);
+ em::ActiveTimePeriod period1 = status_.active_period(1);
+ EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0.active_duration());
+ EXPECT_EQ(10000, period1.active_duration());
+
+ em::TimePeriod time_period0 = period0.time_period();
+ em::TimePeriod time_period1 = period1.time_period();
+
+ EXPECT_EQ(time_period0.end_timestamp(), time_period1.start_timestamp());
+
+ // Ensure that the start and end times for the period are a day apart.
+ EXPECT_EQ(time_period0.end_timestamp() - time_period0.start_timestamp(),
+ kMillisecondsPerDay);
+ EXPECT_EQ(time_period1.end_timestamp() - time_period1.start_timestamp(),
+ kMillisecondsPerDay);
+}
+
TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
// Test that boot mode data is not reported if the pref is not turned on.
status_collector_.GetStatus(&status_);
diff --git a/chrome/browser/policy/proto/device_management_backend.proto b/chrome/browser/policy/proto/device_management_backend.proto
index eb31ebf..f5da7f7c 100644
--- a/chrome/browser/policy/proto/device_management_backend.proto
+++ b/chrome/browser/policy/proto/device_management_backend.proto
@@ -229,6 +229,11 @@ message TimePeriod {
optional int64 end_timestamp = 2;
}
+message ActiveTimePeriod {
+ optional TimePeriod time_period = 1;
+ optional int32 active_duration = 2;
+}
+
// This captures launch events for one app/extension or other installments.
message InstallableLaunch {
optional string install_id = 1;
@@ -254,11 +259,14 @@ message DeviceStatusReportRequest {
// If the mode is unknown, this field should not be set.
optional string boot_mode = 3;
- // Device active times collection since last report rpc call.
- repeated TimePeriod active_time = 4;
+ // No longer used -- use active_period instead.
+ repeated TimePeriod active_time = 4 [deprecated=true];
// The browser version string as shown in the About dialog.
optional string browser_version = 5;
+
+ // A list of periods when the device was active, aggregated by day.
+ repeated ActiveTimePeriod active_period = 6;
}
// Report session (a user on one device) level status.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index e91a9a6..a71bbcd 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1607,6 +1607,10 @@ 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";
#endif
// Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index f3374b3..396c649 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -617,6 +617,7 @@ extern const char kShouldAutoEnroll[];
extern const char kAutoEnrollmentPowerLimit[];
extern const char kReportDeviceVersionInfo[];
extern const char kReportDeviceActivityTimes[];
+extern const char kDeviceActivityTimes[];
#endif
extern const char kClearPluginLSODataEnabled[];