1167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// Copyright 2013 The Chromium Authors. All rights reserved.
2167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// Use of this source code is governed by a BSD-style license that can be
3167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org// found in the LICENSE file.
4167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
5167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org#include "components/policy/core/common/forwarding_policy_provider.h"
6167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
7167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org#include "components/policy/core/common/schema_map.h"
8167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org#include "components/policy/core/common/schema_registry.h"
9167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
10167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgnamespace policy {
11167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
12167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgForwardingPolicyProvider::ForwardingPolicyProvider(
13167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    ConfigurationPolicyProvider* delegate)
14167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    : delegate_(delegate), state_(WAITING_FOR_REGISTRY_READY) {
15167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  delegate_->AddObserver(this);
16167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  // Serve the initial |delegate_| policies.
17167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  OnUpdatePolicy(delegate_);
18167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
19d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org
20d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgForwardingPolicyProvider::~ForwardingPolicyProvider() {
21167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  delegate_->RemoveObserver(this);
22167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
23167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
24167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgvoid ForwardingPolicyProvider::Init(SchemaRegistry* registry) {
25d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  ConfigurationPolicyProvider::Init(registry);
26167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  if (registry->IsReady())
27167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    OnSchemaRegistryReady();
28167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
29167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
30167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgbool ForwardingPolicyProvider::IsInitializationComplete(PolicyDomain domain)
31167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    const {
32167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  if (domain == POLICY_DOMAIN_CHROME)
33167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    return delegate_->IsInitializationComplete(domain);
34167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  // This provider keeps its own state for all the other domains.
35167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  return state_ == READY;
36167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
37167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
38167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgvoid ForwardingPolicyProvider::RefreshPolicies() {
39167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org  delegate_->RefreshPolicies();
40}
41
42void ForwardingPolicyProvider::OnSchemaRegistryReady() {
43  DCHECK_EQ(WAITING_FOR_REGISTRY_READY, state_);
44  // This provider's registry is ready, meaning that it has all the initial
45  // components schemas; the delegate's registry should also see them now,
46  // since it's tracking the former.
47  // Asking the delegate to RefreshPolicies now means that the next
48  // OnUpdatePolicy from the delegate will have the initial policy for
49  // components.
50  if (!schema_map()->HasComponents()) {
51    // If there are no component registered for this provider then there's no
52    // need to reload.
53    state_ = READY;
54    OnUpdatePolicy(delegate_);
55    return;
56  }
57
58  state_ = WAITING_FOR_REFRESH;
59  RefreshPolicies();
60}
61
62void ForwardingPolicyProvider::OnSchemaRegistryUpdated(bool has_new_schemas) {
63  if (state_ != READY)
64    return;
65  if (has_new_schemas) {
66    RefreshPolicies();
67  } else {
68    // Remove the policies that were being served for the component that have
69    // been removed. This is important so that update notifications are also
70    // sent in case those component are reinstalled during the current session.
71    OnUpdatePolicy(delegate_);
72  }
73}
74
75void ForwardingPolicyProvider::OnUpdatePolicy(
76    ConfigurationPolicyProvider* provider) {
77  DCHECK_EQ(delegate_, provider);
78
79  if (state_ == WAITING_FOR_REFRESH)
80    state_ = READY;
81
82  scoped_ptr<PolicyBundle> bundle(new PolicyBundle());
83  if (state_ == READY) {
84    bundle->CopyFrom(delegate_->policies());
85    schema_map()->FilterBundle(bundle.get());
86  } else {
87    // Always forward the Chrome policy, even if the components are not ready
88    // yet.
89    const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
90    bundle->Get(chrome_ns).CopyFrom(delegate_->policies().Get(chrome_ns));
91  }
92
93  UpdatePolicy(bundle.Pass());
94}
95
96}  // namespace policy
97