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