Home | History | Annotate | Download | only in policy_hack
      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 
     17 namespace remoting {
     18 namespace 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.
     24 class 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 
     89 PolicyWatcher* 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