15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/policy_statistics_collector.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/policy_service.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "policy/policy_constants.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int PolicyStatisticsCollector::kStatisticsUpdateRate =
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    24 * 60 * 60 * 1000;  // 24 hours.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyStatisticsCollector::PolicyStatisticsCollector(
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PolicyService* policy_service,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefService* prefs,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<base::TaskRunner>& task_runner)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : max_policy_id_(-1),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy_service_(policy_service),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs_(prefs),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      task_runner_(task_runner) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyStatisticsCollector::~PolicyStatisticsCollector() {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyStatisticsCollector::Initialize() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  using base::Time;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  using base::TimeDelta;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta update_rate = TimeDelta::FromMilliseconds(kStatisticsUpdateRate);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time last_update = Time::FromInternalValue(
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs_->GetInt64(prefs::kLastPolicyStatisticsUpdate));
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta delay = std::max(Time::Now() - last_update, TimeDelta::FromDays(0));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delay >= update_rate)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CollectStatistics();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleUpdate(update_rate - delay);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyStatisticsCollector::RegisterPrefs(PrefRegistrySimple* registry) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterInt64Pref(prefs::kLastPolicyStatisticsUpdate, 0);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyStatisticsCollector::RecordPolicyUse(int id) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (max_policy_id_ == -1) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const policy::PolicyDefinitionList* policy_list =
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        policy::GetChromePolicyDefinitionList();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (const policy::PolicyDefinitionList::Entry* policy = policy_list->begin;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         policy != policy_list->end; ++policy) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (policy->id > max_policy_id_)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        max_policy_id_ = policy->id;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the boundary to be max policy id + 1. Note that this may decrease in
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // future builds if the policy with maximum id is removed. This does not
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pose a problem.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LE(id, max_policy_id_);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Enterprise.Policies", id, max_policy_id_ + 1);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyStatisticsCollector::CollectStatistics() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const policy::PolicyDefinitionList* policy_list =
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy::GetChromePolicyDefinitionList();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const PolicyMap& policies = policy_service_->GetPolicies(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collect statistics.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (const policy::PolicyDefinitionList::Entry* policy = policy_list->begin;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       policy != policy_list->end; ++policy) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policies.Get(policy->name))
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RecordPolicyUse(policy->id);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Take care of next update.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs_->SetInt64(prefs::kLastPolicyStatisticsUpdate,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Time::Now().ToInternalValue());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleUpdate(base::TimeDelta::FromMilliseconds(kStatisticsUpdateRate));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyStatisticsCollector::ScheduleUpdate(base::TimeDelta delay) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_callback_.Reset(base::Bind(
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &PolicyStatisticsCollector::CollectStatistics,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Unretained(this)));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner_->PostDelayedTask(FROM_HERE, update_callback_.callback(), delay);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
102