Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / device_local_account_extension_tracker.cc
blob546c5bdf8a3e8cbb5e42f0d4a70f0f3224073956
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/policy/device_local_account_extension_tracker.h"
7 #include "base/logging.h"
8 #include "base/prefs/pref_value_map.h"
9 #include "base/values.h"
10 #include "chrome/browser/chromeos/policy/device_local_account.h"
11 #include "chrome/browser/extensions/policy_handlers.h"
12 #include "components/policy/core/common/policy_map.h"
13 #include "components/policy/core/common/policy_namespace.h"
14 #include "components/policy/core/common/schema.h"
15 #include "components/policy/core/common/schema_map.h"
16 #include "components/policy/core/common/schema_registry.h"
17 #include "extensions/browser/pref_names.h"
19 namespace policy {
21 DeviceLocalAccountExtensionTracker::DeviceLocalAccountExtensionTracker(
22 const DeviceLocalAccount& account,
23 CloudPolicyStore* store,
24 SchemaRegistry* schema_registry)
25 : store_(store),
26 schema_registry_(schema_registry) {
27 if (account.type == DeviceLocalAccount::TYPE_KIOSK_APP) {
28 // This is easy: Just add a component for the app id.
29 PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, account.kiosk_app_id);
30 schema_registry_->RegisterComponent(ns, Schema());
31 } else if (account.type == DeviceLocalAccount::TYPE_PUBLIC_SESSION) {
32 // For public sessions, track the value of the ExtensionInstallForcelist
33 // policy.
34 store_->AddObserver(this);
35 UpdateFromStore();
36 } else {
37 NOTREACHED();
40 schema_registry_->SetReady(POLICY_DOMAIN_EXTENSIONS);
43 DeviceLocalAccountExtensionTracker::~DeviceLocalAccountExtensionTracker() {
44 store_->RemoveObserver(this);
47 void DeviceLocalAccountExtensionTracker::OnStoreLoaded(
48 CloudPolicyStore* store) {
49 UpdateFromStore();
52 void DeviceLocalAccountExtensionTracker::OnStoreError(CloudPolicyStore* store) {
53 UpdateFromStore();
56 void DeviceLocalAccountExtensionTracker::UpdateFromStore() {
57 const policy::PolicyMap& policy_map = store_->policy_map();
59 // TODO(binjin): Use two policy handlers here after
60 // ExtensionManagementPolicyHandler is introduced.
61 extensions::ExtensionInstallForcelistPolicyHandler policy_handler;
62 if (!policy_handler.CheckPolicySettings(policy_map, NULL))
63 return;
65 PrefValueMap pref_value_map;
66 policy_handler.ApplyPolicySettings(policy_map, &pref_value_map);
68 const base::Value* value = NULL;
69 const base::DictionaryValue* dict = NULL;
70 if (!pref_value_map.GetValue(extensions::pref_names::kInstallForceList,
71 &value) ||
72 !value->GetAsDictionary(&dict)) {
73 return;
76 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
77 PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, it.key());
78 if (schema_registry_->schema_map()->GetSchema(ns)) {
79 // Important detail: Don't register the component again if it already
80 // has a schema! If the session already started for this public session
81 // then the real Schema for the extension has already been set by the
82 // ManagedValueStoreCache::ExtensionTracker. Do not override that schema
83 // with an invalid one now, or the policy for the extension will be
84 // dropped.
85 // However, if the forcelist is updated then we need to register the new
86 // component ID so that its remote policy data can be fetched.
87 continue;
89 schema_registry_->RegisterComponent(ns, Schema());
92 // Removing an extension from a public session at runtime can happen but is
93 // a rare event. In that case we leave the extension ID in the SchemaRegistry,
94 // and it will be purged on the next restart.
97 } // namespace policy