Home | History | Annotate | Download | only in cloud
      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 "components/policy/core/common/cloud/cloud_policy_manager.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/command_line.h"
     10 #include "base/files/file_path.h"
     11 #include "base/logging.h"
     12 #include "base/prefs/pref_service.h"
     13 #include "components/policy/core/common/cloud/cloud_policy_service.h"
     14 #include "components/policy/core/common/policy_bundle.h"
     15 #include "components/policy/core/common/policy_map.h"
     16 #include "components/policy/core/common/policy_switches.h"
     17 #include "net/url_request/url_request_context_getter.h"
     18 
     19 #if !defined(OS_ANDROID) && !defined(OS_IOS)
     20 #include "components/policy/core/common/cloud/resource_cache.h"
     21 #endif
     22 
     23 namespace policy {
     24 
     25 CloudPolicyManager::CloudPolicyManager(
     26     const PolicyNamespaceKey& policy_ns_key,
     27     CloudPolicyStore* cloud_policy_store,
     28     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     29     const scoped_refptr<base::SequencedTaskRunner>& file_task_runner,
     30     const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
     31     : core_(policy_ns_key, cloud_policy_store, task_runner),
     32       waiting_for_policy_refresh_(false),
     33       file_task_runner_(file_task_runner),
     34       io_task_runner_(io_task_runner) {
     35   store()->AddObserver(this);
     36 
     37   // If the underlying store is already initialized, publish the loaded
     38   // policy. Otherwise, request a load now.
     39   if (store()->is_initialized())
     40     CheckAndPublishPolicy();
     41   else
     42     store()->Load();
     43 }
     44 
     45 CloudPolicyManager::~CloudPolicyManager() {}
     46 
     47 void CloudPolicyManager::Shutdown() {
     48   component_policy_service_.reset();
     49   core_.Disconnect();
     50   store()->RemoveObserver(this);
     51   ConfigurationPolicyProvider::Shutdown();
     52 }
     53 
     54 bool CloudPolicyManager::IsInitializationComplete(PolicyDomain domain) const {
     55   if (domain == POLICY_DOMAIN_CHROME)
     56     return store()->is_initialized();
     57   if (ComponentCloudPolicyService::SupportsDomain(domain) &&
     58       component_policy_service_) {
     59     return component_policy_service_->is_initialized();
     60   }
     61   return true;
     62 }
     63 
     64 void CloudPolicyManager::RefreshPolicies() {
     65   if (service()) {
     66     waiting_for_policy_refresh_ = true;
     67     service()->RefreshPolicy(
     68         base::Bind(&CloudPolicyManager::OnRefreshComplete,
     69                    base::Unretained(this)));
     70   } else {
     71     OnRefreshComplete(false);
     72   }
     73 }
     74 
     75 void CloudPolicyManager::OnStoreLoaded(CloudPolicyStore* cloud_policy_store) {
     76   DCHECK_EQ(store(), cloud_policy_store);
     77   CheckAndPublishPolicy();
     78 }
     79 
     80 void CloudPolicyManager::OnStoreError(CloudPolicyStore* cloud_policy_store) {
     81   DCHECK_EQ(store(), cloud_policy_store);
     82   // Publish policy (even though it hasn't changed) in order to signal load
     83   // complete on the ConfigurationPolicyProvider interface. Technically, this
     84   // is only required on the first load, but doesn't hurt in any case.
     85   CheckAndPublishPolicy();
     86 }
     87 
     88 void CloudPolicyManager::OnComponentCloudPolicyUpdated() {
     89   CheckAndPublishPolicy();
     90 }
     91 
     92 void CloudPolicyManager::CheckAndPublishPolicy() {
     93   if (IsInitializationComplete(POLICY_DOMAIN_CHROME) &&
     94       !waiting_for_policy_refresh_) {
     95     scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
     96     GetChromePolicy(
     97         &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())));
     98     if (component_policy_service_)
     99       bundle->MergeFrom(component_policy_service_->policy());
    100     UpdatePolicy(bundle.Pass());
    101   }
    102 }
    103 
    104 void CloudPolicyManager::GetChromePolicy(PolicyMap* policy_map) {
    105   policy_map->CopyFrom(store()->policy_map());
    106 }
    107 
    108 void CloudPolicyManager::CreateComponentCloudPolicyService(
    109     const base::FilePath& policy_cache_path,
    110     const scoped_refptr<net::URLRequestContextGetter>& request_context) {
    111 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    112   // Init() must have been called.
    113   DCHECK(schema_registry());
    114   // Called at most once.
    115   DCHECK(!component_policy_service_);
    116 
    117   if (CommandLine::ForCurrentProcess()->HasSwitch(
    118           switches::kDisableComponentCloudPolicy) ||
    119       policy_cache_path.empty()) {
    120     return;
    121   }
    122 
    123   // TODO(joaodasilva): Move the |file_task_runner_| to the blocking pool.
    124   // Currently it's not possible because the ComponentCloudPolicyStore is
    125   // NonThreadSafe and doesn't support getting calls from different threads.
    126   scoped_ptr<ResourceCache> resource_cache(
    127       new ResourceCache(policy_cache_path, file_task_runner_));
    128   component_policy_service_.reset(new ComponentCloudPolicyService(
    129       this,
    130       schema_registry(),
    131       core(),
    132       resource_cache.Pass(),
    133       request_context,
    134       file_task_runner_,
    135       io_task_runner_));
    136 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
    137 }
    138 
    139 void CloudPolicyManager::ClearAndDestroyComponentCloudPolicyService() {
    140 #if !defined(OS_ANDROID) && !defined(OS_IOS)
    141   if (component_policy_service_) {
    142     component_policy_service_->ClearCache();
    143     component_policy_service_.reset();
    144   }
    145 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
    146 }
    147 
    148 void CloudPolicyManager::OnRefreshComplete(bool success) {
    149   waiting_for_policy_refresh_ = false;
    150   CheckAndPublishPolicy();
    151 }
    152 
    153 }  // namespace policy
    154