OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/policy/core/common/cloud/external_policy_data_fetcher.h" | 5 #include "components/policy/core/common/cloud/external_policy_data_fetcher.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 scoped_refptr<base::SequencedTaskRunner> task_runner, | 81 scoped_refptr<base::SequencedTaskRunner> task_runner, |
82 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | 82 scoped_refptr<base::SequencedTaskRunner> io_task_runner, |
83 const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend) | 83 const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend) |
84 : task_runner_(task_runner), | 84 : task_runner_(task_runner), |
85 io_task_runner_(io_task_runner), | 85 io_task_runner_(io_task_runner), |
86 backend_(backend), | 86 backend_(backend), |
87 weak_factory_(this) { | 87 weak_factory_(this) { |
88 } | 88 } |
89 | 89 |
90 ExternalPolicyDataFetcher::~ExternalPolicyDataFetcher() { | 90 ExternalPolicyDataFetcher::~ExternalPolicyDataFetcher() { |
91 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 91 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
92 for (JobSet::iterator it = jobs_.begin(); it != jobs_.end(); ++it) | 92 for (JobSet::iterator it = jobs_.begin(); it != jobs_.end(); ++it) |
93 CancelJob(*it); | 93 CancelJob(*it); |
94 } | 94 } |
95 | 95 |
96 ExternalPolicyDataFetcher::Job* ExternalPolicyDataFetcher::StartJob( | 96 ExternalPolicyDataFetcher::Job* ExternalPolicyDataFetcher::StartJob( |
97 const GURL& url, | 97 const GURL& url, |
98 int64_t max_size, | 98 int64_t max_size, |
99 const FetchCallback& callback) { | 99 const FetchCallback& callback) { |
100 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 100 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
101 Job* job = new Job( | 101 Job* job = new Job( |
102 url, max_size, | 102 url, max_size, |
103 base::Bind(&ForwardJobFinished, | 103 base::Bind(&ForwardJobFinished, |
104 task_runner_, | 104 task_runner_, |
105 base::Bind(&ExternalPolicyDataFetcher::OnJobFinished, | 105 base::Bind(&ExternalPolicyDataFetcher::OnJobFinished, |
106 weak_factory_.GetWeakPtr(), | 106 weak_factory_.GetWeakPtr(), |
107 callback))); | 107 callback))); |
108 jobs_.insert(job); | 108 jobs_.insert(job); |
109 io_task_runner_->PostTask( | 109 io_task_runner_->PostTask( |
110 FROM_HERE, | 110 FROM_HERE, |
111 base::Bind(&ExternalPolicyDataFetcherBackend::StartJob, backend_, job)); | 111 base::Bind(&ExternalPolicyDataFetcherBackend::StartJob, backend_, job)); |
112 return job; | 112 return job; |
113 } | 113 } |
114 | 114 |
115 void ExternalPolicyDataFetcher::CancelJob(Job* job) { | 115 void ExternalPolicyDataFetcher::CancelJob(Job* job) { |
116 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 116 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
117 DCHECK(jobs_.find(job) != jobs_.end()); | 117 DCHECK(jobs_.find(job) != jobs_.end()); |
118 jobs_.erase(job); | 118 jobs_.erase(job); |
119 // Post a task that will cancel the |job| in the |backend_|. The |job| is | 119 // Post a task that will cancel the |job| in the |backend_|. The |job| is |
120 // removed from |jobs_| immediately to indicate that it has been canceled but | 120 // removed from |jobs_| immediately to indicate that it has been canceled but |
121 // is not actually deleted until the cancelation has reached the |backend_| | 121 // is not actually deleted until the cancelation has reached the |backend_| |
122 // and a confirmation has been posted back. This ensures that no new job can | 122 // and a confirmation has been posted back. This ensures that no new job can |
123 // be allocated at the same address while an OnJobFinished() callback may | 123 // be allocated at the same address while an OnJobFinished() callback may |
124 // still be pending for the canceled |job|. | 124 // still be pending for the canceled |job|. |
125 io_task_runner_->PostTask( | 125 io_task_runner_->PostTask( |
126 FROM_HERE, | 126 FROM_HERE, |
127 base::Bind(&ExternalPolicyDataFetcherBackend::CancelJob, | 127 base::Bind(&ExternalPolicyDataFetcherBackend::CancelJob, |
128 backend_, | 128 backend_, |
129 job, | 129 job, |
130 base::Bind(&ForwardJobCanceled, | 130 base::Bind(&ForwardJobCanceled, |
131 task_runner_, | 131 task_runner_, |
132 base::Bind(&DoNothing, base::Owned(job))))); | 132 base::Bind(&DoNothing, base::Owned(job))))); |
133 } | 133 } |
134 | 134 |
135 void ExternalPolicyDataFetcher::OnJobFinished( | 135 void ExternalPolicyDataFetcher::OnJobFinished( |
136 const FetchCallback& callback, | 136 const FetchCallback& callback, |
137 Job* job, | 137 Job* job, |
138 Result result, | 138 Result result, |
139 std::unique_ptr<std::string> data) { | 139 std::unique_ptr<std::string> data) { |
140 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 140 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
141 JobSet::iterator it = jobs_.find(job); | 141 JobSet::iterator it = jobs_.find(job); |
142 if (it == jobs_.end()) { | 142 if (it == jobs_.end()) { |
143 // The |job| has been canceled and removed from |jobs_| already. This can | 143 // The |job| has been canceled and removed from |jobs_| already. This can |
144 // happen because the |backend_| runs on a different thread and a |job| may | 144 // happen because the |backend_| runs on a different thread and a |job| may |
145 // finish before the cancellation has reached that thread. | 145 // finish before the cancellation has reached that thread. |
146 return; | 146 return; |
147 } | 147 } |
148 callback.Run(result, std::move(data)); | 148 callback.Run(result, std::move(data)); |
149 jobs_.erase(it); | 149 jobs_.erase(it); |
150 delete job; | 150 delete job; |
151 } | 151 } |
152 | 152 |
153 struct ExternalPolicyDataFetcherBackend::FetcherAndJob { | 153 struct ExternalPolicyDataFetcherBackend::FetcherAndJob { |
154 std::unique_ptr<net::URLFetcher> fetcher; | 154 std::unique_ptr<net::URLFetcher> fetcher; |
155 ExternalPolicyDataFetcher::Job* job; | 155 ExternalPolicyDataFetcher::Job* job; |
156 }; | 156 }; |
157 | 157 |
158 ExternalPolicyDataFetcherBackend::ExternalPolicyDataFetcherBackend( | 158 ExternalPolicyDataFetcherBackend::ExternalPolicyDataFetcherBackend( |
159 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | 159 scoped_refptr<base::SequencedTaskRunner> io_task_runner, |
160 scoped_refptr<net::URLRequestContextGetter> request_context) | 160 scoped_refptr<net::URLRequestContextGetter> request_context) |
161 : io_task_runner_(io_task_runner), | 161 : io_task_runner_(io_task_runner), |
162 request_context_(request_context), | 162 request_context_(request_context), |
163 last_fetch_id_(-1), | 163 last_fetch_id_(-1), |
164 weak_factory_(this) { | 164 weak_factory_(this) { |
165 } | 165 } |
166 | 166 |
167 ExternalPolicyDataFetcherBackend::~ExternalPolicyDataFetcherBackend() { | 167 ExternalPolicyDataFetcherBackend::~ExternalPolicyDataFetcherBackend() { |
168 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 168 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
169 } | 169 } |
170 | 170 |
171 std::unique_ptr<ExternalPolicyDataFetcher> | 171 std::unique_ptr<ExternalPolicyDataFetcher> |
172 ExternalPolicyDataFetcherBackend::CreateFrontend( | 172 ExternalPolicyDataFetcherBackend::CreateFrontend( |
173 scoped_refptr<base::SequencedTaskRunner> task_runner) { | 173 scoped_refptr<base::SequencedTaskRunner> task_runner) { |
174 return base::MakeUnique<ExternalPolicyDataFetcher>( | 174 return base::MakeUnique<ExternalPolicyDataFetcher>( |
175 task_runner, io_task_runner_, weak_factory_.GetWeakPtr()); | 175 task_runner, io_task_runner_, weak_factory_.GetWeakPtr()); |
176 } | 176 } |
177 | 177 |
178 void ExternalPolicyDataFetcherBackend::StartJob( | 178 void ExternalPolicyDataFetcherBackend::StartJob( |
179 ExternalPolicyDataFetcher::Job* job) { | 179 ExternalPolicyDataFetcher::Job* job) { |
180 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 180 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
181 net::NetworkTrafficAnnotationTag traffic_annotation = | 181 net::NetworkTrafficAnnotationTag traffic_annotation = |
182 net::DefineNetworkTrafficAnnotation("external_policy_fetcher", R"( | 182 net::DefineNetworkTrafficAnnotation("external_policy_fetcher", R"( |
183 semantics { | 183 semantics { |
184 sender: "Cloud Policy" | 184 sender: "Cloud Policy" |
185 description: | 185 description: |
186 "Used to fetch policy for extensions, policy-controlled wallpaper, " | 186 "Used to fetch policy for extensions, policy-controlled wallpaper, " |
187 "and custom terms of service." | 187 "and custom terms of service." |
188 trigger: | 188 trigger: |
189 "Periodically loaded when a managed user is signed in to Chrome." | 189 "Periodically loaded when a managed user is signed in to Chrome." |
190 data: | 190 data: |
(...skipping 22 matching lines...) Expand all Loading... |
213 net::LOAD_DO_NOT_SEND_COOKIES | | 213 net::LOAD_DO_NOT_SEND_COOKIES | |
214 net::LOAD_DO_NOT_SEND_AUTH_DATA); | 214 net::LOAD_DO_NOT_SEND_AUTH_DATA); |
215 fetcher->SetAutomaticallyRetryOnNetworkChanges(3); | 215 fetcher->SetAutomaticallyRetryOnNetworkChanges(3); |
216 fetcher->Start(); | 216 fetcher->Start(); |
217 job_map_[fetcher] = {std::move(owned_fetcher), job}; | 217 job_map_[fetcher] = {std::move(owned_fetcher), job}; |
218 } | 218 } |
219 | 219 |
220 void ExternalPolicyDataFetcherBackend::CancelJob( | 220 void ExternalPolicyDataFetcherBackend::CancelJob( |
221 ExternalPolicyDataFetcher::Job* job, | 221 ExternalPolicyDataFetcher::Job* job, |
222 const base::Closure& callback) { | 222 const base::Closure& callback) { |
223 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 223 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
224 for (auto it = job_map_.begin(); it != job_map_.end();) { | 224 for (auto it = job_map_.begin(); it != job_map_.end();) { |
225 if (it->second.job == job) { | 225 if (it->second.job == job) { |
226 job_map_.erase(it++); | 226 job_map_.erase(it++); |
227 } else { | 227 } else { |
228 ++it; | 228 ++it; |
229 } | 229 } |
230 } | 230 } |
231 callback.Run(); | 231 callback.Run(); |
232 } | 232 } |
233 | 233 |
234 void ExternalPolicyDataFetcherBackend::OnURLFetchComplete( | 234 void ExternalPolicyDataFetcherBackend::OnURLFetchComplete( |
235 const net::URLFetcher* source) { | 235 const net::URLFetcher* source) { |
236 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 236 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
237 auto it = job_map_.find(const_cast<net::URLFetcher*>(source)); | 237 auto it = job_map_.find(const_cast<net::URLFetcher*>(source)); |
238 if (it == job_map_.end()) { | 238 if (it == job_map_.end()) { |
239 NOTREACHED(); | 239 NOTREACHED(); |
240 return; | 240 return; |
241 } | 241 } |
242 | 242 |
243 ExternalPolicyDataFetcher::Result result = ExternalPolicyDataFetcher::SUCCESS; | 243 ExternalPolicyDataFetcher::Result result = ExternalPolicyDataFetcher::SUCCESS; |
244 std::unique_ptr<std::string> data; | 244 std::unique_ptr<std::string> data; |
245 | 245 |
246 const net::URLRequestStatus status = it->first->GetStatus(); | 246 const net::URLRequestStatus status = it->first->GetStatus(); |
(...skipping 26 matching lines...) Expand all Loading... |
273 ExternalPolicyDataFetcher::Job* job = it->second.job; | 273 ExternalPolicyDataFetcher::Job* job = it->second.job; |
274 job_map_.erase(it); | 274 job_map_.erase(it); |
275 job->callback.Run(job, result, std::move(data)); | 275 job->callback.Run(job, result, std::move(data)); |
276 } | 276 } |
277 | 277 |
278 void ExternalPolicyDataFetcherBackend::OnURLFetchDownloadProgress( | 278 void ExternalPolicyDataFetcherBackend::OnURLFetchDownloadProgress( |
279 const net::URLFetcher* source, | 279 const net::URLFetcher* source, |
280 int64_t current, | 280 int64_t current, |
281 int64_t total, | 281 int64_t total, |
282 int64_t current_network_bytes) { | 282 int64_t current_network_bytes) { |
283 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 283 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
284 auto it = job_map_.find(source); | 284 auto it = job_map_.find(source); |
285 DCHECK(it != job_map_.end()); | 285 DCHECK(it != job_map_.end()); |
286 if (it == job_map_.end()) | 286 if (it == job_map_.end()) |
287 return; | 287 return; |
288 | 288 |
289 // Reject the data if it exceeds the size limit. The content length is in | 289 // Reject the data if it exceeds the size limit. The content length is in |
290 // |total|, and it may be -1 when not known. | 290 // |total|, and it may be -1 when not known. |
291 ExternalPolicyDataFetcher::Job* job = it->second.job; | 291 ExternalPolicyDataFetcher::Job* job = it->second.job; |
292 int64_t max_size = job->max_size; | 292 int64_t max_size = job->max_size; |
293 if (current > max_size || total > max_size) { | 293 if (current > max_size || total > max_size) { |
294 job_map_.erase(it); | 294 job_map_.erase(it); |
295 job->callback.Run(job, ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED, | 295 job->callback.Run(job, ExternalPolicyDataFetcher::MAX_SIZE_EXCEEDED, |
296 std::unique_ptr<std::string>()); | 296 std::unique_ptr<std::string>()); |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 } // namespace policy | 300 } // namespace policy |
OLD | NEW |