user_policy_disk_cache.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 17namespace em = enterprise_management; 18 19namespace policy { 20 21UserPolicyDiskCache::Delegate::~Delegate() {} 22 23UserPolicyDiskCache::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 32void 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 39void 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 47UserPolicyDiskCache::~UserPolicyDiskCache() {} 48 49void 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 78void 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 87void 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 112void 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 (file_util::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