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 #ifndef CHROME_BROWSER_POLICY_ASYNC_POLICY_LOADER_H_ 6 #define CHROME_BROWSER_POLICY_ASYNC_POLICY_LOADER_H_ 7 8 #include <map> 9 10 #include "base/callback.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/time/time.h" 15 #include "chrome/browser/policy/policy_service.h" 16 17 namespace policy { 18 19 class PolicyBundle; 20 class PolicyDomainDescriptor; 21 22 // Base implementation for platform-specific policy loaders. Together with the 23 // AsyncPolicyProvider, this base implementation takes care of the initial load, 24 // periodic reloads, watching file changes, refreshing policies and object 25 // lifetime. 26 // 27 // All methods are invoked on the FILE thread, including the destructor. 28 // The only exceptions are the constructor (which may be called on any thread), 29 // and the initial Load() which is called on the thread that owns the provider. 30 // LastModificationTime() is also invoked once on that thread at startup. 31 class AsyncPolicyLoader { 32 public: 33 AsyncPolicyLoader(); 34 virtual ~AsyncPolicyLoader(); 35 36 // Returns the currently configured policies. Load() is always invoked on 37 // the FILE thread, except for the initial Load() at startup which is invoked 38 // from the thread that owns the provider. 39 virtual scoped_ptr<PolicyBundle> Load() = 0; 40 41 // Allows implementations to finalize their initialization on the FILE 42 // thread (e.g. setup file watchers). 43 virtual void InitOnFile() = 0; 44 45 // Implementations should return the time of the last modification detected, 46 // or base::Time() if it doesn't apply, which is the default. 47 virtual base::Time LastModificationTime(); 48 49 // Implementations should invoke Reload() when a change is detected. This 50 // must be invoked from the FILE thread and will trigger a Load(), and pass 51 // the returned bundle to the provider. 52 // The load is immediate when |force| is true. Otherwise, the loader 53 // reschedules the reload until the LastModificationTime() is a couple of 54 // seconds in the past. This mitigates the problem of reading files that are 55 // currently being written to, and whose contents are incomplete. 56 // A reload is posted periodically, if it hasn't been triggered recently. This 57 // makes sure the policies are reloaded if the update events aren't triggered. 58 void Reload(bool force); 59 60 // Passes the current |descriptor| for a domain, which is used to determine 61 // which policy names are supported for each component. 62 void RegisterPolicyDomain( 63 scoped_refptr<const PolicyDomainDescriptor> descriptor); 64 65 protected: 66 typedef std::map<PolicyDomain, scoped_refptr<const PolicyDomainDescriptor> > 67 DescriptorMap; 68 69 // Returns the current DescriptorMap. This can be used by implementations to 70 // determine the components registered for each domain, and to filter out 71 // unknonwn policies. 72 const DescriptorMap& descriptor_map() const { return descriptor_map_; } 73 74 private: 75 // Allow AsyncPolicyProvider to call Init(). 76 friend class AsyncPolicyProvider; 77 78 typedef base::Callback<void(scoped_ptr<PolicyBundle>)> UpdateCallback; 79 80 // Used by the AsyncPolicyProvider to do the initial Load(). The first load 81 // is also used to initialize |last_modification_time_|. 82 scoped_ptr<PolicyBundle> InitialLoad(); 83 84 // Used by the AsyncPolicyProvider to install the |update_callback_|. 85 // Invoked on the FILE thread. 86 void Init(const UpdateCallback& update_callback); 87 88 // Cancels any pending periodic reload and posts one |delay| time units from 89 // now. 90 void ScheduleNextReload(base::TimeDelta delay); 91 92 // Checks if the underlying files haven't changed recently, by checking the 93 // LastModificationTime(). |delay| is updated with a suggested time to wait 94 // before retrying when this returns false. 95 bool IsSafeToReload(const base::Time& now, base::TimeDelta* delay); 96 97 // Callback for updates, passed in Init(). 98 UpdateCallback update_callback_; 99 100 // Used to get WeakPtrs for the periodic reload task. 101 base::WeakPtrFactory<AsyncPolicyLoader> weak_factory_; 102 103 // Records last known modification timestamp. 104 base::Time last_modification_time_; 105 106 // The wall clock time at which the last modification timestamp was 107 // recorded. It's better to not assume the file notification time and the 108 // wall clock times come from the same source, just in case there is some 109 // non-local filesystem involved. 110 base::Time last_modification_clock_; 111 112 // A map of the currently registered domains and their descriptors. 113 DescriptorMap descriptor_map_; 114 115 DISALLOW_COPY_AND_ASSIGN(AsyncPolicyLoader); 116 }; 117 118 } // namespace policy 119 120 #endif // CHROME_BROWSER_POLICY_ASYNC_POLICY_LOADER_H_ 121