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