• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2012 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.
4
5#include "remoting/host/policy_hack/policy_watcher.h"
6
7#include <CoreFoundation/CoreFoundation.h>
8
9#include "base/compiler_specific.h"
10#include "base/mac/foundation_util.h"
11#include "base/mac/scoped_cftyperef.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/single_thread_task_runner.h"
14#include "base/strings/sys_string_conversions.h"
15#include "base/values.h"
16
17namespace remoting {
18namespace policy_hack {
19
20// The MacOS version does not watch files because it is accepted
21// practice on the Mac that the user must logout/login for policies to be
22// applied. This will actually pick up policies every
23// |kFallbackReloadDelayMinutes| which is sufficient for right now.
24class PolicyWatcherMac : public PolicyWatcher {
25 public:
26  explicit PolicyWatcherMac(
27      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
28    : PolicyWatcher(task_runner) {
29  }
30
31  virtual ~PolicyWatcherMac() {
32  }
33
34 protected:
35  virtual void StartWatchingInternal() OVERRIDE {
36    Reload();
37  }
38
39  virtual void StopWatchingInternal() OVERRIDE {
40  }
41
42  virtual void Reload() OVERRIDE {
43    DCHECK(OnPolicyWatcherThread());
44    base::DictionaryValue policy;
45
46    CFStringRef policy_bundle_id = CFSTR("com.google.Chrome");
47    if (CFPreferencesAppSynchronize(policy_bundle_id)) {
48      for (base::DictionaryValue::Iterator i(Defaults());
49           !i.IsAtEnd(); i.Advance()) {
50        const std::string& policy_name = i.key();
51        base::ScopedCFTypeRef<CFStringRef> policy_key(
52            base::SysUTF8ToCFStringRef(policy_name));
53
54        if (i.value().GetType() == base::DictionaryValue::TYPE_BOOLEAN) {
55          Boolean valid = false;
56          bool value = CFPreferencesGetAppBooleanValue(policy_key,
57                                                       policy_bundle_id,
58                                                       &valid);
59          if (valid) {
60            policy.SetBoolean(policy_name, value);
61          }
62        }
63
64        if (i.value().GetType() == base::DictionaryValue::TYPE_STRING) {
65          base::ScopedCFTypeRef<CFPropertyListRef> property_list(
66              CFPreferencesCopyAppValue(policy_key, policy_bundle_id));
67          if (property_list.get() != NULL) {
68            CFStringRef policy_value = base::mac::CFCast<CFStringRef>(
69                property_list.get());
70            if (policy_value != NULL) {
71              policy.SetString(policy_name,
72                               base::SysCFStringRefToUTF8(policy_value));
73            }
74          }
75        }
76
77      }
78    }
79
80    // Set policy. Policy must be set (even if it is empty) so that the
81    // default policy is picked up the first time reload is called.
82    UpdatePolicies(&policy);
83
84    // Reschedule task.
85    ScheduleFallbackReloadTask();
86  }
87};
88
89PolicyWatcher* PolicyWatcher::Create(
90        scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
91  return new PolicyWatcherMac(task_runner);
92}
93
94}  // namespace policy_hack
95}  // namespace remoting
96