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"
21 DeviceLocalAccountExtensionTracker::DeviceLocalAccountExtensionTracker(
22 const DeviceLocalAccount
& account
,
23 CloudPolicyStore
* store
,
24 SchemaRegistry
* schema_registry
)
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
34 store_
->AddObserver(this);
40 schema_registry_
->SetReady(POLICY_DOMAIN_EXTENSIONS
);
43 DeviceLocalAccountExtensionTracker::~DeviceLocalAccountExtensionTracker() {
44 store_
->RemoveObserver(this);
47 void DeviceLocalAccountExtensionTracker::OnStoreLoaded(
48 CloudPolicyStore
* store
) {
52 void DeviceLocalAccountExtensionTracker::OnStoreError(CloudPolicyStore
* store
) {
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
))
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
,
72 !value
->GetAsDictionary(&dict
)) {
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
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.
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.