| OLD | NEW |
| (Empty) |
| 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/login/signed_settings_helper.h" | |
| 6 | |
| 7 #include <vector> | |
| 8 | |
| 9 #include "base/lazy_instance.h" | |
| 10 #include "base/logging.h" | |
| 11 #include "base/memory/ref_counted.h" | |
| 12 #include "chrome/browser/policy/proto/device_management_backend.pb.h" | |
| 13 #include "content/public/browser/browser_thread.h" | |
| 14 | |
| 15 using content::BrowserThread; | |
| 16 | |
| 17 namespace em = enterprise_management; | |
| 18 | |
| 19 namespace chromeos { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 class OpContext { | |
| 24 public: | |
| 25 class Delegate { | |
| 26 public: | |
| 27 virtual void OnOpCreated(OpContext* context) = 0; | |
| 28 virtual void OnOpStarted(OpContext* context) = 0; | |
| 29 virtual void OnOpCompleted(OpContext* context) = 0; | |
| 30 }; | |
| 31 | |
| 32 virtual ~OpContext() {} | |
| 33 | |
| 34 // Creates and execute op. | |
| 35 void Execute() { | |
| 36 CreateOp(); | |
| 37 CHECK(op_.get()); | |
| 38 if (delegate_) | |
| 39 delegate_->OnOpCreated(this); | |
| 40 | |
| 41 // Note that the context could be released when op_->Execute() returns. | |
| 42 // So keep a local copy of delegate and executing flag to use after | |
| 43 // the call. | |
| 44 Delegate* delegate = delegate_; | |
| 45 executing_ = true; | |
| 46 op_->Execute(); | |
| 47 if (delegate) | |
| 48 delegate->OnOpStarted(this); | |
| 49 } | |
| 50 | |
| 51 // Cancels the callback and cancels the op if it is not executing. | |
| 52 void Cancel() { | |
| 53 if (!executing_) | |
| 54 OnOpCompleted(); | |
| 55 } | |
| 56 | |
| 57 // Accessors. | |
| 58 SignedSettings* op() const { | |
| 59 return op_.get(); | |
| 60 } | |
| 61 | |
| 62 void set_delegate(Delegate* delegate) { | |
| 63 delegate_ = delegate; | |
| 64 } | |
| 65 | |
| 66 protected: | |
| 67 explicit OpContext(Delegate* delegate) | |
| 68 : executing_(false), | |
| 69 delegate_(delegate) { | |
| 70 } | |
| 71 | |
| 72 // Creates the op to execute. | |
| 73 virtual void CreateOp() = 0; | |
| 74 | |
| 75 // Callback on op completion. | |
| 76 virtual void OnOpCompleted() { | |
| 77 if (delegate_) | |
| 78 delegate_->OnOpCompleted(this); | |
| 79 | |
| 80 delete this; | |
| 81 } | |
| 82 | |
| 83 bool executing_; | |
| 84 Delegate* delegate_; | |
| 85 | |
| 86 scoped_refptr<SignedSettings> op_; | |
| 87 }; | |
| 88 | |
| 89 class StorePolicyOpContext | |
| 90 : public SignedSettings::Delegate<bool>, | |
| 91 public OpContext { | |
| 92 public: | |
| 93 StorePolicyOpContext(const em::PolicyFetchResponse& policy, | |
| 94 SignedSettingsHelper::StorePolicyCallback callback, | |
| 95 OpContext::Delegate* delegate) | |
| 96 : OpContext(delegate), | |
| 97 callback_(callback), | |
| 98 policy_(policy) { | |
| 99 } | |
| 100 | |
| 101 // chromeos::SignedSettings::Delegate implementation | |
| 102 virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, | |
| 103 bool unused) OVERRIDE { | |
| 104 VLOG(2) << "OnSettingsOpCompleted, code = " << code; | |
| 105 callback_.Run(code); | |
| 106 OnOpCompleted(); | |
| 107 } | |
| 108 | |
| 109 protected: | |
| 110 // OpContext implementation | |
| 111 virtual void CreateOp() OVERRIDE { | |
| 112 op_ = SignedSettings::CreateStorePolicyOp(&policy_, this); | |
| 113 } | |
| 114 | |
| 115 private: | |
| 116 SignedSettingsHelper::StorePolicyCallback callback_; | |
| 117 em::PolicyFetchResponse policy_; | |
| 118 | |
| 119 DISALLOW_COPY_AND_ASSIGN(StorePolicyOpContext); | |
| 120 }; | |
| 121 | |
| 122 class RetrievePolicyOpContext | |
| 123 : public SignedSettings::Delegate<const em::PolicyFetchResponse&>, | |
| 124 public OpContext { | |
| 125 public: | |
| 126 RetrievePolicyOpContext(SignedSettingsHelper::RetrievePolicyCallback callback, | |
| 127 OpContext::Delegate* delegate) | |
| 128 : OpContext(delegate), | |
| 129 callback_(callback){ | |
| 130 } | |
| 131 | |
| 132 // chromeos::SignedSettings::Delegate implementation | |
| 133 virtual void OnSettingsOpCompleted( | |
| 134 SignedSettings::ReturnCode code, | |
| 135 const em::PolicyFetchResponse& policy) OVERRIDE { | |
| 136 callback_.Run(code, policy); | |
| 137 OnOpCompleted(); | |
| 138 } | |
| 139 | |
| 140 protected: | |
| 141 // OpContext implementation | |
| 142 virtual void CreateOp() OVERRIDE { | |
| 143 op_ = SignedSettings::CreateRetrievePolicyOp(this); | |
| 144 } | |
| 145 | |
| 146 private: | |
| 147 SignedSettingsHelper::RetrievePolicyCallback callback_; | |
| 148 | |
| 149 DISALLOW_COPY_AND_ASSIGN(RetrievePolicyOpContext); | |
| 150 }; | |
| 151 | |
| 152 } // namespace | |
| 153 | |
| 154 | |
| 155 class SignedSettingsHelperImpl : public SignedSettingsHelper, | |
| 156 public OpContext::Delegate { | |
| 157 public: | |
| 158 // SignedSettingsHelper implementation | |
| 159 virtual void StartStorePolicyOp(const em::PolicyFetchResponse& policy, | |
| 160 StorePolicyCallback callback) OVERRIDE; | |
| 161 virtual void StartRetrievePolicyOp(RetrievePolicyCallback callback) OVERRIDE; | |
| 162 | |
| 163 // OpContext::Delegate implementation | |
| 164 virtual void OnOpCreated(OpContext* context); | |
| 165 virtual void OnOpStarted(OpContext* context); | |
| 166 virtual void OnOpCompleted(OpContext* context); | |
| 167 | |
| 168 private: | |
| 169 SignedSettingsHelperImpl(); | |
| 170 virtual ~SignedSettingsHelperImpl(); | |
| 171 | |
| 172 void AddOpContext(OpContext* context); | |
| 173 void ClearAll(); | |
| 174 | |
| 175 std::vector<OpContext*> pending_contexts_; | |
| 176 | |
| 177 friend struct base::DefaultLazyInstanceTraits<SignedSettingsHelperImpl>; | |
| 178 DISALLOW_COPY_AND_ASSIGN(SignedSettingsHelperImpl); | |
| 179 }; | |
| 180 | |
| 181 static base::LazyInstance<SignedSettingsHelperImpl> | |
| 182 g_signed_settings_helper_impl = LAZY_INSTANCE_INITIALIZER; | |
| 183 | |
| 184 SignedSettingsHelperImpl::SignedSettingsHelperImpl() { | |
| 185 } | |
| 186 | |
| 187 SignedSettingsHelperImpl::~SignedSettingsHelperImpl() { | |
| 188 if (!pending_contexts_.empty()) { | |
| 189 LOG(WARNING) << "SignedSettingsHelperImpl shutdown with pending ops, " | |
| 190 << "changes will be lost."; | |
| 191 ClearAll(); | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 void SignedSettingsHelperImpl::StartStorePolicyOp( | |
| 196 const em::PolicyFetchResponse& policy, | |
| 197 StorePolicyCallback callback) { | |
| 198 AddOpContext(new StorePolicyOpContext(policy, callback, this)); | |
| 199 } | |
| 200 | |
| 201 void SignedSettingsHelperImpl::StartRetrievePolicyOp( | |
| 202 RetrievePolicyCallback callback) { | |
| 203 AddOpContext(new RetrievePolicyOpContext(callback, this)); | |
| 204 } | |
| 205 | |
| 206 void SignedSettingsHelperImpl::AddOpContext(OpContext* context) { | |
| 207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 208 CHECK(context); | |
| 209 | |
| 210 pending_contexts_.push_back(context); | |
| 211 if (pending_contexts_.size() == 1) | |
| 212 context->Execute(); | |
| 213 } | |
| 214 | |
| 215 void SignedSettingsHelperImpl::ClearAll() { | |
| 216 for (size_t i = 0; i < pending_contexts_.size(); ++i) { | |
| 217 pending_contexts_[i]->set_delegate(NULL); | |
| 218 pending_contexts_[i]->Cancel(); | |
| 219 } | |
| 220 pending_contexts_.clear(); | |
| 221 } | |
| 222 | |
| 223 void SignedSettingsHelperImpl::OnOpCreated(OpContext* context) { | |
| 224 if (test_delegate_) | |
| 225 test_delegate_->OnOpCreated(context->op()); | |
| 226 } | |
| 227 | |
| 228 void SignedSettingsHelperImpl::OnOpStarted(OpContext* context) { | |
| 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 230 | |
| 231 if (test_delegate_) | |
| 232 test_delegate_->OnOpStarted(context->op()); | |
| 233 } | |
| 234 | |
| 235 void SignedSettingsHelperImpl::OnOpCompleted(OpContext* context) { | |
| 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 237 DCHECK(pending_contexts_.front() == context); | |
| 238 | |
| 239 pending_contexts_.erase(pending_contexts_.begin()); | |
| 240 if (!pending_contexts_.empty()) | |
| 241 pending_contexts_.front()->Execute(); | |
| 242 | |
| 243 if (test_delegate_) | |
| 244 test_delegate_->OnOpCompleted(context->op()); | |
| 245 } | |
| 246 | |
| 247 SignedSettingsHelper* SignedSettingsHelper::Get() { | |
| 248 return g_signed_settings_helper_impl.Pointer(); | |
| 249 } | |
| 250 | |
| 251 } // namespace chromeos | |
| OLD | NEW |