| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "remoting/host/policy_hack/policy_watcher.h" |
| |
| #include <CoreFoundation/CoreFoundation.h> |
| |
| #include "base/compiler_specific.h" |
| #include "base/mac/foundation_util.h" |
| #include "base/mac/scoped_cftyperef.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "base/values.h" |
| |
| namespace remoting { |
| namespace policy_hack { |
| |
| // The MacOS version does not watch files because it is accepted |
| // practice on the Mac that the user must logout/login for policies to be |
| // applied. This will actually pick up policies every |
| // |kFallbackReloadDelayMinutes| which is sufficient for right now. |
| class PolicyWatcherMac : public PolicyWatcher { |
| public: |
| explicit PolicyWatcherMac( |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| : PolicyWatcher(task_runner) { |
| } |
| |
| virtual ~PolicyWatcherMac() { |
| } |
| |
| protected: |
| virtual void StartWatchingInternal() OVERRIDE { |
| Reload(); |
| } |
| |
| virtual void StopWatchingInternal() OVERRIDE { |
| } |
| |
| virtual void Reload() OVERRIDE { |
| DCHECK(OnPolicyWatcherThread()); |
| base::DictionaryValue policy; |
| |
| CFStringRef policy_bundle_id = CFSTR("com.google.Chrome"); |
| if (CFPreferencesAppSynchronize(policy_bundle_id)) { |
| for (base::DictionaryValue::Iterator i(Defaults()); |
| !i.IsAtEnd(); i.Advance()) { |
| const std::string& policy_name = i.key(); |
| base::ScopedCFTypeRef<CFStringRef> policy_key( |
| base::SysUTF8ToCFStringRef(policy_name)); |
| |
| if (i.value().GetType() == base::DictionaryValue::TYPE_BOOLEAN) { |
| Boolean valid = false; |
| bool value = CFPreferencesGetAppBooleanValue(policy_key, |
| policy_bundle_id, |
| &valid); |
| if (valid) { |
| policy.SetBoolean(policy_name, value); |
| } |
| } |
| |
| if (i.value().GetType() == base::DictionaryValue::TYPE_STRING) { |
| base::ScopedCFTypeRef<CFPropertyListRef> property_list( |
| CFPreferencesCopyAppValue(policy_key, policy_bundle_id)); |
| if (property_list.get() != NULL) { |
| CFStringRef policy_value = base::mac::CFCast<CFStringRef>( |
| property_list.get()); |
| if (policy_value != NULL) { |
| policy.SetString(policy_name, |
| base::SysCFStringRefToUTF8(policy_value)); |
| } |
| } |
| } |
| |
| } |
| } |
| |
| // Set policy. Policy must be set (even if it is empty) so that the |
| // default policy is picked up the first time reload is called. |
| UpdatePolicies(&policy); |
| |
| // Reschedule task. |
| ScheduleFallbackReloadTask(); |
| } |
| }; |
| |
| PolicyWatcher* PolicyWatcher::Create( |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| return new PolicyWatcherMac(task_runner); |
| } |
| |
| } // namespace policy_hack |
| } // namespace remoting |