Update V8 to version 4.6.62.
[chromium-blink-merge.git] / components / policy / core / common / policy_loader_mac.mm
blobe10735b7a3bf94e65378ebcbda5f03cd8407be8c
1 // Copyright (c) 2015 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 "components/policy/core/common/policy_loader_mac.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/mac/foundation_util.h"
13 #include "base/mac/scoped_cftyperef.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/strings/sys_string_conversions.h"
16 #include "base/values.h"
17 #include "components/policy/core/common/external_data_fetcher.h"
18 #include "components/policy/core/common/mac_util.h"
19 #include "components/policy/core/common/policy_bundle.h"
20 #include "components/policy/core/common/policy_load_status.h"
21 #include "components/policy/core/common/policy_map.h"
22 #include "components/policy/core/common/preferences_mac.h"
23 #include "components/policy/core/common/schema.h"
24 #include "components/policy/core/common/schema_map.h"
26 using base::ScopedCFTypeRef;
28 namespace policy {
30 PolicyLoaderMac::PolicyLoaderMac(
31     scoped_refptr<base::SequencedTaskRunner> task_runner,
32     const base::FilePath& managed_policy_path,
33     MacPreferences* preferences)
34     : AsyncPolicyLoader(task_runner),
35       preferences_(preferences),
36       managed_policy_path_(managed_policy_path),
37       application_id_(kCFPreferencesCurrentApplication) {
40 PolicyLoaderMac::PolicyLoaderMac(
41     scoped_refptr<base::SequencedTaskRunner> task_runner,
42     const base::FilePath& managed_policy_path,
43     MacPreferences* preferences,
44     CFStringRef application_id)
45     : AsyncPolicyLoader(task_runner),
46       preferences_(preferences),
47       managed_policy_path_(managed_policy_path),
48       application_id_(application_id) {
51 PolicyLoaderMac::~PolicyLoaderMac() {
54 void PolicyLoaderMac::InitOnBackgroundThread() {
55   if (!managed_policy_path_.empty()) {
56     watcher_.Watch(
57         managed_policy_path_, false,
58         base::Bind(&PolicyLoaderMac::OnFileUpdated, base::Unretained(this)));
59   }
62 scoped_ptr<PolicyBundle> PolicyLoaderMac::Load() {
63   preferences_->AppSynchronize(application_id_);
64   scoped_ptr<PolicyBundle> bundle(new PolicyBundle());
66   // Load Chrome's policy.
67   PolicyMap& chrome_policy =
68       bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
70   PolicyLoadStatusSample status;
71   bool policy_present = false;
72   const Schema* schema =
73       schema_map()->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
74   for (Schema::Iterator it = schema->GetPropertiesIterator(); !it.IsAtEnd();
75        it.Advance()) {
76     base::ScopedCFTypeRef<CFStringRef> name(
77         base::SysUTF8ToCFStringRef(it.key()));
78     base::ScopedCFTypeRef<CFPropertyListRef> value(
79         preferences_->CopyAppValue(name, application_id_));
80     if (!value.get())
81       continue;
82     policy_present = true;
83     bool forced = preferences_->AppValueIsForced(name, application_id_);
84     PolicyLevel level =
85         forced ? POLICY_LEVEL_MANDATORY : POLICY_LEVEL_RECOMMENDED;
86     // TODO(joaodasilva): figure the policy scope.
87     scoped_ptr<base::Value> policy = PropertyToValue(value);
88     if (policy) {
89       chrome_policy.Set(it.key(), level, POLICY_SCOPE_USER, policy.release(),
90                         NULL);
91     } else {
92       status.Add(POLICY_LOAD_STATUS_PARSE_ERROR);
93     }
94   }
96   if (!policy_present)
97     status.Add(POLICY_LOAD_STATUS_NO_POLICY);
99   // Load policy for the registered components.
100   LoadPolicyForDomain(POLICY_DOMAIN_EXTENSIONS, "extensions", bundle.get());
102   return bundle.Pass();
105 base::Time PolicyLoaderMac::LastModificationTime() {
106   base::File::Info file_info;
107   if (!base::GetFileInfo(managed_policy_path_, &file_info) ||
108       file_info.is_directory) {
109     return base::Time();
110   }
112   return file_info.last_modified;
115 #if defined(OS_MACOSX) && !defined(OS_IOS)
117 base::FilePath PolicyLoaderMac::GetManagedPolicyPath(CFStringRef bundle_id) {
118   // This constructs the path to the plist file in which Mac OS X stores the
119   // managed preference for the application. This is undocumented and therefore
120   // fragile, but if it doesn't work out, AsyncPolicyLoader has a task that
121   // polls periodically in order to reload managed preferences later even if we
122   // missed the change.
124   base::FilePath path;
125   if (!base::mac::GetLocalDirectory(NSLibraryDirectory, &path))
126     return base::FilePath();
127   path = path.Append(FILE_PATH_LITERAL("Managed Preferences"));
128   char* login = getlogin();
129   if (!login)
130     return base::FilePath();
131   path = path.AppendASCII(login);
132   return path.Append(base::SysCFStringRefToUTF8(bundle_id) + ".plist");
135 #endif
137 void PolicyLoaderMac::LoadPolicyForDomain(PolicyDomain domain,
138                                           const std::string& domain_name,
139                                           PolicyBundle* bundle) {
140   std::string id_prefix(base::mac::BaseBundleID());
141   id_prefix.append(".").append(domain_name).append(".");
143   const ComponentMap* components = schema_map()->GetComponents(domain);
144   if (!components)
145     return;
147   for (ComponentMap::const_iterator it = components->begin();
148        it != components->end(); ++it) {
149     PolicyMap policy;
150     LoadPolicyForComponent(id_prefix + it->first, it->second, &policy);
151     if (!policy.empty())
152       bundle->Get(PolicyNamespace(domain, it->first)).Swap(&policy);
153   }
156 void PolicyLoaderMac::LoadPolicyForComponent(
157     const std::string& bundle_id_string,
158     const Schema& schema,
159     PolicyMap* policy) {
160   // TODO(joaodasilva): Extensions may be registered in a ComponentMap
161   // without a schema, to allow a graceful update of the Legacy Browser Support
162   // extension on Windows. Remove this check once that support is removed.
163   if (!schema.valid())
164     return;
166   base::ScopedCFTypeRef<CFStringRef> bundle_id(
167       base::SysUTF8ToCFStringRef(bundle_id_string));
168   preferences_->AppSynchronize(bundle_id);
170   for (Schema::Iterator it = schema.GetPropertiesIterator(); !it.IsAtEnd();
171        it.Advance()) {
172     base::ScopedCFTypeRef<CFStringRef> pref_name(
173         base::SysUTF8ToCFStringRef(it.key()));
174     base::ScopedCFTypeRef<CFPropertyListRef> value(
175         preferences_->CopyAppValue(pref_name, bundle_id));
176     if (!value.get())
177       continue;
178     bool forced = preferences_->AppValueIsForced(pref_name, bundle_id);
179     PolicyLevel level =
180         forced ? POLICY_LEVEL_MANDATORY : POLICY_LEVEL_RECOMMENDED;
181     scoped_ptr<base::Value> policy_value = PropertyToValue(value);
182     if (policy_value) {
183       policy->Set(it.key(), level, POLICY_SCOPE_USER, policy_value.release(),
184                   NULL);
185     }
186   }
189 void PolicyLoaderMac::OnFileUpdated(const base::FilePath& path, bool error) {
190   if (!error)
191     Reload(false);
194 }  // namespace policy