Index: chrome/browser/policy/cloud_policy_cache.cc |
diff --git a/chrome/browser/policy/cloud_policy_cache.cc b/chrome/browser/policy/cloud_policy_cache.cc |
index b81fb81899091a6f5710a4fa6746d525f1dee8f7..d7511d3a23b7dcd16661f321e5e18e97129aa6f9 100644 |
--- a/chrome/browser/policy/cloud_policy_cache.cc |
+++ b/chrome/browser/policy/cloud_policy_cache.cc |
@@ -11,8 +11,8 @@ |
#include "base/task.h" |
#include "base/values.h" |
#include "chrome/browser/browser_thread.h" |
+#include "chrome/browser/policy/configuration_policy_pref_store.h" |
#include "chrome/browser/policy/proto/cloud_policy.pb.h" |
-#include "chrome/browser/policy/proto/device_management_backend.pb.h" |
#include "chrome/browser/policy/proto/device_management_constants.h" |
#include "chrome/browser/policy/proto/device_management_local.pb.h" |
@@ -33,6 +33,51 @@ namespace policy { |
void DecodePolicy(const em::CloudPolicySettings& policy, |
PolicyMap* mandatory, PolicyMap* recommended); |
+// A thin ConfigurationPolicyProvider implementation sitting on top of |
+// CloudPolicyCache for hooking up with ConfigurationPolicyPrefStore. |
+class CloudPolicyCache::CloudPolicyProvider |
+ : public ConfigurationPolicyProvider { |
+ public: |
+ CloudPolicyProvider(const PolicyDefinitionList* policy_list, |
+ CloudPolicyCache* cache, |
+ CloudPolicyCache::PolicyLevel level) |
+ : ConfigurationPolicyProvider(policy_list), |
+ cache_(cache), |
+ level_(level) {} |
+ virtual ~CloudPolicyProvider() {} |
+ |
+ virtual bool Provide(ConfigurationPolicyStoreInterface* store) { |
+ if (!cache_->has_device_policy()) { |
+ if (level_ == POLICY_LEVEL_MANDATORY) |
+ ApplyPolicyMap(&cache_->mandatory_policy_, store); |
+ else if (level_ == POLICY_LEVEL_RECOMMENDED) |
+ ApplyPolicyMap(&cache_->recommended_policy_, store); |
+ } else { |
+ ApplyPolicyValueTree(cache_->device_policy_.get(), store); |
+ } |
+ return true; |
+ } |
+ |
+ virtual bool IsInitializationComplete() const { |
+ return cache_->initialization_complete_; |
+ } |
+ |
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) { |
+ cache_->observer_list_.AddObserver(observer); |
+ } |
+ virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer) { |
+ cache_->observer_list_.RemoveObserver(observer); |
+ } |
+ |
+ private: |
+ // The underlying policy cache. |
+ CloudPolicyCache* cache_; |
+ // Policy level this provider will handle. |
+ CloudPolicyCache::PolicyLevel level_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider); |
+}; |
+ |
// Saves policy information to a file. |
class PersistPolicyTask : public Task { |
public: |
@@ -85,17 +130,30 @@ CloudPolicyCache::CloudPolicyCache( |
const FilePath& backing_file_path) |
: backing_file_path_(backing_file_path), |
device_policy_(new DictionaryValue), |
- fresh_policy_(false), |
+ initialization_complete_(false), |
is_unmanaged_(false), |
has_device_policy_(false) { |
+ managed_policy_provider_.reset( |
+ new CloudPolicyProvider( |
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), |
+ this, |
+ POLICY_LEVEL_MANDATORY)); |
+ recommended_policy_provider_.reset( |
+ new CloudPolicyProvider( |
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), |
+ this, |
+ POLICY_LEVEL_RECOMMENDED)); |
} |
-CloudPolicyCache::~CloudPolicyCache() {} |
+CloudPolicyCache::~CloudPolicyCache() { |
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnProviderGoingAway()); |
+} |
-void CloudPolicyCache::LoadPolicyFromFile() { |
+void CloudPolicyCache::LoadFromFile() { |
// TODO(jkummerow): This method is doing file IO during browser startup. In |
// the long run it would be better to delay this until the FILE thread exists. |
- if (!file_util::PathExists(backing_file_path_) || fresh_policy_) { |
+ if (!file_util::PathExists(backing_file_path_) || initialization_complete_) { |
return; |
} |
@@ -136,55 +194,46 @@ void CloudPolicyCache::LoadPolicyFromFile() { |
return; |
} |
// Swap in the new policy information. |
- if (is_unmanaged_) { |
- base::AutoLock lock(lock_); |
- last_policy_refresh_time_ = timestamp; |
- return; |
- } else if (cached_response.has_cloud_policy()) { |
- if (!fresh_policy_) { |
- base::AutoLock lock(lock_); |
- // The use of |Swap()| here makes sure that the old value in |
- // |mandatory_policy_| is deleted when |mandatory_policy| goes out of |
- // scope. (The same applies to |SetPolicy()| below.) |
- mandatory_policy_.Swap(&mandatory_policy); |
- recommended_policy_.Swap(&recommended_policy); |
- last_policy_refresh_time_ = timestamp; |
- has_device_policy_ = false; |
- } |
+ if (cached_response.has_cloud_policy()) { |
+ mandatory_policy_.Swap(&mandatory_policy); |
+ recommended_policy_.Swap(&recommended_policy); |
+ has_device_policy_ = false; |
} else if (cached_response.has_device_policy()) { |
scoped_ptr<DictionaryValue> value( |
DecodeDevicePolicy(cached_response.device_policy())); |
- if (!fresh_policy_) { |
- base::AutoLock lock(lock_); |
- device_policy_.reset(value.release()); |
- last_policy_refresh_time_ = timestamp; |
- has_device_policy_ = true; |
- } |
+ device_policy_.reset(value.release()); |
+ has_device_policy_ = true; |
} |
+ last_policy_refresh_time_ = timestamp; |
+ initialization_complete_ = true; |
+ |
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnUpdatePolicy()); |
} |
-bool CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+void CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) { |
+ DCHECK(CalledOnValidThread()); |
is_unmanaged_ = false; |
base::Time timestamp; |
PolicyMap mandatory_policy; |
PolicyMap recommended_policy; |
bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy, |
×tamp); |
- if (!ok) { |
- // TODO(jkummerow): Signal error to PolicyProvider. |
- return false; |
- } |
+ if (!ok) |
+ return; |
+ |
const bool new_policy_differs = |
- !mandatory_policy.Equals(mandatory_policy_) || |
- !recommended_policy.Equals(recommended_policy_); |
- { |
- base::AutoLock lock(lock_); |
- mandatory_policy_.Swap(&mandatory_policy); |
- recommended_policy_.Swap(&recommended_policy); |
- fresh_policy_ = true; |
- last_policy_refresh_time_ = timestamp; |
- has_device_policy_ = false; |
+ !mandatory_policy_.Equals(mandatory_policy) || |
+ !recommended_policy_.Equals(recommended_policy); |
+ mandatory_policy_.Swap(&mandatory_policy); |
+ recommended_policy_.Swap(&recommended_policy); |
+ initialization_complete_ = true; |
+ last_policy_refresh_time_ = timestamp; |
+ has_device_policy_ = false; |
+ |
+ if (new_policy_differs) { |
Mattias Nissler (ping if slow)
2011/02/21 14:39:13
Do we need also notify if initialization_complete_
Jakob Kummerow
2011/02/22 10:02:33
Done.
I believe this case won't happen anyway with
|
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnUpdatePolicy()); |
} |
if (timestamp > base::Time::NowFromSystemTime() + |
@@ -199,21 +248,22 @@ bool CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) { |
FROM_HERE, |
new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false)); |
} |
- return new_policy_differs; |
} |
-bool CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+void CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) { |
+ DCHECK(CalledOnValidThread()); |
is_unmanaged_ = false; |
DictionaryValue* value = DecodeDevicePolicy(policy); |
const bool new_policy_differs = !(value->Equals(device_policy_.get())); |
base::Time now(base::Time::NowFromSystemTime()); |
- { |
- base::AutoLock lock(lock_); |
- device_policy_.reset(value); |
- fresh_policy_ = true; |
- last_policy_refresh_time_ = now; |
- has_device_policy_ = true; |
+ device_policy_.reset(value); |
+ initialization_complete_ = true; |
+ last_policy_refresh_time_ = now; |
+ has_device_policy_ = true; |
+ |
+ if (new_policy_differs) { |
Mattias Nissler (ping if slow)
2011/02/21 14:39:13
Same here?
Jakob Kummerow
2011/02/22 10:02:33
Done.
|
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnUpdatePolicy()); |
} |
em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse; |
@@ -222,35 +272,29 @@ bool CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) { |
BrowserThread::FILE, |
FROM_HERE, |
new PersistPolicyTask(backing_file_path_, NULL, policy_copy, false)); |
- return new_policy_differs; |
} |
-DictionaryValue* CloudPolicyCache::GetDevicePolicy() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- base::AutoLock lock(lock_); |
- return device_policy_->DeepCopy(); |
+ConfigurationPolicyProvider* CloudPolicyCache::GetManagedPolicyProvider() { |
+ DCHECK(CalledOnValidThread()); |
+ return managed_policy_provider_.get(); |
} |
-const PolicyMap* CloudPolicyCache::GetMandatoryPolicy() const { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return &mandatory_policy_; |
-} |
- |
-const PolicyMap* CloudPolicyCache::GetRecommendedPolicy() const { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return &recommended_policy_; |
+ConfigurationPolicyProvider* CloudPolicyCache::GetRecommendedPolicyProvider() { |
+ DCHECK(CalledOnValidThread()); |
+ return recommended_policy_provider_.get(); |
} |
void CloudPolicyCache::SetUnmanaged() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK(CalledOnValidThread()); |
is_unmanaged_ = true; |
- { |
- base::AutoLock lock(lock_); |
- mandatory_policy_.Clear(); |
- recommended_policy_.Clear(); |
- device_policy_.reset(new DictionaryValue); |
- last_policy_refresh_time_ = base::Time::NowFromSystemTime(); |
- } |
+ mandatory_policy_.Clear(); |
+ recommended_policy_.Clear(); |
+ device_policy_.reset(new DictionaryValue); |
+ last_policy_refresh_time_ = base::Time::NowFromSystemTime(); |
+ |
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnUpdatePolicy()); |
+ |
BrowserThread::PostTask( |
BrowserThread::FILE, |
FROM_HERE, |