Home | History | Annotate | Download | only in policy
      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 "chrome/browser/chromeos/policy/user_policy_disk_cache.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/file_util.h"
      9 #include "base/location.h"
     10 #include "base/logging.h"
     11 #include "base/message_loop/message_loop_proxy.h"
     12 #include "base/metrics/histogram.h"
     13 #include "base/sequenced_task_runner.h"
     14 #include "components/policy/core/common/cloud/enterprise_metrics.h"
     15 #include "policy/proto/device_management_local.pb.h"
     16 
     17 namespace em = enterprise_management;
     18 
     19 namespace policy {
     20 
     21 UserPolicyDiskCache::Delegate::~Delegate() {}
     22 
     23 UserPolicyDiskCache::UserPolicyDiskCache(
     24     const base::WeakPtr<Delegate>& delegate,
     25     const base::FilePath& backing_file_path,
     26     scoped_refptr<base::SequencedTaskRunner> background_task_runner)
     27     : delegate_(delegate),
     28       backing_file_path_(backing_file_path),
     29       origin_task_runner_(base::MessageLoopProxy::current()),
     30       background_task_runner_(background_task_runner) {}
     31 
     32 void UserPolicyDiskCache::Load() {
     33   DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
     34   bool ret = background_task_runner_->PostTask(
     35       FROM_HERE, base::Bind(&UserPolicyDiskCache::LoadOnFileThread, this));
     36   DCHECK(ret);
     37 }
     38 
     39 void UserPolicyDiskCache::Store(
     40     const em::CachedCloudPolicyResponse& policy) {
     41   DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
     42   background_task_runner_->PostTask(
     43       FROM_HERE,
     44       base::Bind(&UserPolicyDiskCache::StoreOnFileThread, this, policy));
     45 }
     46 
     47 UserPolicyDiskCache::~UserPolicyDiskCache() {}
     48 
     49 void UserPolicyDiskCache::LoadOnFileThread() {
     50   DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
     51 
     52   em::CachedCloudPolicyResponse cached_response;
     53   if (!base::PathExists(backing_file_path_)) {
     54     LoadDone(LOAD_RESULT_NOT_FOUND, cached_response);
     55     return;
     56   }
     57 
     58   // Read the protobuf from the file.
     59   std::string data;
     60   if (!base::ReadFileToString(backing_file_path_, &data)) {
     61     LOG(WARNING) << "Failed to read policy data from "
     62                  << backing_file_path_.value();
     63     LoadDone(LOAD_RESULT_READ_ERROR, cached_response);
     64     return;
     65   }
     66 
     67   // Decode it.
     68   if (!cached_response.ParseFromArray(data.c_str(), data.size())) {
     69     LOG(WARNING) << "Failed to parse policy data read from "
     70                  << backing_file_path_.value();
     71     LoadDone(LOAD_RESULT_PARSE_ERROR, cached_response);
     72     return;
     73   }
     74 
     75   LoadDone(LOAD_RESULT_SUCCESS, cached_response);
     76 }
     77 
     78 void UserPolicyDiskCache::LoadDone(
     79     LoadResult result,
     80     const em::CachedCloudPolicyResponse& policy) {
     81   origin_task_runner_->PostTask(
     82       FROM_HERE,
     83       base::Bind(
     84           &UserPolicyDiskCache::ReportResultOnUIThread, this, result, policy));
     85 }
     86 
     87 void UserPolicyDiskCache::ReportResultOnUIThread(
     88     LoadResult result,
     89     const em::CachedCloudPolicyResponse& policy) {
     90   DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
     91 
     92   switch (result) {
     93     case LOAD_RESULT_NOT_FOUND:
     94       break;
     95     case LOAD_RESULT_READ_ERROR:
     96     case LOAD_RESULT_PARSE_ERROR:
     97       UMA_HISTOGRAM_ENUMERATION(policy::kMetricPolicy,
     98                                 kMetricPolicyLoadFailed,
     99                                 policy::kMetricPolicySize);
    100       break;
    101     case LOAD_RESULT_SUCCESS:
    102       UMA_HISTOGRAM_ENUMERATION(policy::kMetricPolicy,
    103                                 kMetricPolicyLoadSucceeded,
    104                                 policy::kMetricPolicySize);
    105       break;
    106   }
    107 
    108   if (delegate_.get())
    109     delegate_->OnDiskCacheLoaded(result, policy);
    110 }
    111 
    112 void UserPolicyDiskCache::StoreOnFileThread(
    113     const em::CachedCloudPolicyResponse& policy) {
    114   DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
    115   std::string data;
    116   if (!policy.SerializeToString(&data)) {
    117     LOG(WARNING) << "Failed to serialize policy data";
    118     UMA_HISTOGRAM_ENUMERATION(policy::kMetricPolicy,
    119                               kMetricPolicyStoreFailed,
    120                               policy::kMetricPolicySize);
    121     return;
    122   }
    123 
    124   if (!base::CreateDirectory(backing_file_path_.DirName())) {
    125     LOG(WARNING) << "Failed to create directory "
    126                  << backing_file_path_.DirName().value();
    127     UMA_HISTOGRAM_ENUMERATION(policy::kMetricPolicy,
    128                               kMetricPolicyStoreFailed,
    129                               policy::kMetricPolicySize);
    130     return;
    131   }
    132 
    133   int size = data.size();
    134   if (base::WriteFile(backing_file_path_, data.c_str(), size) != size) {
    135     LOG(WARNING) << "Failed to write " << backing_file_path_.value();
    136     UMA_HISTOGRAM_ENUMERATION(policy::kMetricPolicy,
    137                               kMetricPolicyStoreFailed,
    138                               policy::kMetricPolicySize);
    139     return;
    140   }
    141   UMA_HISTOGRAM_ENUMERATION(policy::kMetricPolicy,
    142                             kMetricPolicyStoreSucceeded,
    143                             policy::kMetricPolicySize);
    144 }
    145 
    146 }  // namespace policy
    147