Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: chrome/browser/android/offline_pages/background_loader_offliner.cc

Issue 2748053004: [Offline Pages] Allow BackgroundLoader to track network bytes using prerenderer hook-in. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "chrome/browser/android/offline_pages/background_loader_offliner.h" 5 #include "chrome/browser/android/offline_pages/background_loader_offliner.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "base/sys_info.h" 8 #include "base/sys_info.h"
9 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h" 9 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
10 #include "chrome/browser/android/offline_pages/offliner_helper.h" 10 #include "chrome/browser/android/offline_pages/offliner_helper.h"
11 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
12 #include "components/offline_pages/core/background/save_page_request.h" 12 #include "components/offline_pages/core/background/save_page_request.h"
13 #include "components/offline_pages/core/client_namespace_constants.h" 13 #include "components/offline_pages/core/client_namespace_constants.h"
14 #include "components/offline_pages/core/offline_page_model.h" 14 #include "components/offline_pages/core/offline_page_model.h"
15 #include "content/public/browser/browser_context.h" 15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/navigation_handle.h" 16 #include "content/public/browser/navigation_handle.h"
17 #include "content/public/browser/web_contents.h" 17 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_user_data.h"
18 19
19 namespace offline_pages { 20 namespace offline_pages {
20 21
21 namespace { 22 namespace {
22 long kOfflinePageDelayMs = 2000; 23 const long kOfflinePageDelayMs = 2000;
24
25 class OfflinerData : public content::WebContentsUserData<OfflinerData> {
26 public:
27 static void AddToWebContents(content::WebContents* webcontents,
28 BackgroundLoaderOffliner* offliner) {
29 DCHECK(offliner);
30 webcontents->SetUserData(UserDataKey(), std::unique_ptr<OfflinerData>(
31 new OfflinerData(offliner)));
32 }
33
34 explicit OfflinerData(BackgroundLoaderOffliner* offliner) {
35 offliner_ = offliner;
36 }
37 BackgroundLoaderOffliner* offliner() { return offliner_; }
38
39 private:
40 // The offliner that the WebContents is attached to. The offliner owns the
41 // Delegate which owns the WebContents that this data is attached to.
42 // Therefore, its lifetime should exceed that of the WebContents, so this
43 // should always be non-null.
44 BackgroundLoaderOffliner* offliner_;
45 };
46
23 } // namespace 47 } // namespace
24 48
25 BackgroundLoaderOffliner::BackgroundLoaderOffliner( 49 BackgroundLoaderOffliner::BackgroundLoaderOffliner(
26 content::BrowserContext* browser_context, 50 content::BrowserContext* browser_context,
27 const OfflinerPolicy* policy, 51 const OfflinerPolicy* policy,
28 OfflinePageModel* offline_page_model) 52 OfflinePageModel* offline_page_model)
29 : browser_context_(browser_context), 53 : browser_context_(browser_context),
30 offline_page_model_(offline_page_model), 54 offline_page_model_(offline_page_model),
31 is_low_end_device_(base::SysInfo::IsLowEndDevice()), 55 is_low_end_device_(base::SysInfo::IsLowEndDevice()),
32 save_state_(NONE), 56 save_state_(NONE),
33 page_load_state_(SUCCESS), 57 page_load_state_(SUCCESS),
34 page_delay_ms_(kOfflinePageDelayMs), 58 page_delay_ms_(kOfflinePageDelayMs),
59 network_bytes_(0LL),
35 weak_ptr_factory_(this) { 60 weak_ptr_factory_(this) {
36 DCHECK(offline_page_model_); 61 DCHECK(offline_page_model_);
37 DCHECK(browser_context_); 62 DCHECK(browser_context_);
38 } 63 }
39 64
40 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {} 65 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {}
41 66
42 // TODO(dimich): Invoke progress_callback as appropriate. 67 // static
68 BackgroundLoaderOffliner* BackgroundLoaderOffliner::FromWebContents(
69 content::WebContents* contents) {
70 OfflinerData* data = OfflinerData::FromWebContents(contents);
71 if (data)
72 return data->offliner();
73 return nullptr;
74 }
75
43 bool BackgroundLoaderOffliner::LoadAndSave( 76 bool BackgroundLoaderOffliner::LoadAndSave(
44 const SavePageRequest& request, 77 const SavePageRequest& request,
45 const CompletionCallback& completion_callback, 78 const CompletionCallback& completion_callback,
46 const ProgressCallback& progress_callback) { 79 const ProgressCallback& progress_callback) {
47 DCHECK(completion_callback); 80 DCHECK(completion_callback);
48 DCHECK(progress_callback); 81 DCHECK(progress_callback);
49 82
50 if (pending_request_) { 83 if (pending_request_) {
51 DVLOG(1) << "Already have pending request"; 84 DVLOG(1) << "Already have pending request";
52 return false; 85 return false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 135
103 if (!loader_) 136 if (!loader_)
104 ResetState(); 137 ResetState();
105 138
106 // Invalidate ptrs for all delayed/saving tasks. 139 // Invalidate ptrs for all delayed/saving tasks.
107 weak_ptr_factory_.InvalidateWeakPtrs(); 140 weak_ptr_factory_.InvalidateWeakPtrs();
108 141
109 // Track copy of pending request. 142 // Track copy of pending request.
110 pending_request_.reset(new SavePageRequest(request)); 143 pending_request_.reset(new SavePageRequest(request));
111 completion_callback_ = completion_callback; 144 completion_callback_ = completion_callback;
145 progress_callback_ = progress_callback;
112 146
113 // Listen for app foreground/background change. 147 // Listen for app foreground/background change.
114 app_listener_.reset(new base::android::ApplicationStatusListener( 148 app_listener_.reset(new base::android::ApplicationStatusListener(
115 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange, 149 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange,
116 weak_ptr_factory_.GetWeakPtr()))); 150 weak_ptr_factory_.GetWeakPtr())));
117 151
118 // Load page attempt. 152 // Load page attempt.
119 loader_.get()->LoadPage(request.url()); 153 loader_.get()->LoadPage(request.url());
120 154
121 return true; 155 return true;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 // - pushState/replaceState 272 // - pushState/replaceState
239 // - same page history navigation 273 // - same page history navigation
240 if (navigation_handle->HasCommitted() && !navigation_handle->IsSamePage()) 274 if (navigation_handle->HasCommitted() && !navigation_handle->IsSamePage())
241 weak_ptr_factory_.InvalidateWeakPtrs(); 275 weak_ptr_factory_.InvalidateWeakPtrs();
242 } 276 }
243 277
244 void BackgroundLoaderOffliner::SetPageDelayForTest(long delay_ms) { 278 void BackgroundLoaderOffliner::SetPageDelayForTest(long delay_ms) {
245 page_delay_ms_ = delay_ms; 279 page_delay_ms_ = delay_ms;
246 } 280 }
247 281
282 void BackgroundLoaderOffliner::OnNetworkBytesChanged(int64_t bytes) {
283 if (pending_request_ && save_state_ != SAVING) {
284 network_bytes_ += bytes;
285 progress_callback_.Run(*pending_request_, network_bytes_);
286 }
287 }
288
248 void BackgroundLoaderOffliner::SavePage() { 289 void BackgroundLoaderOffliner::SavePage() {
249 if (!pending_request_.get()) { 290 if (!pending_request_.get()) {
250 DVLOG(1) << "Pending request was cleared during delay."; 291 DVLOG(1) << "Pending request was cleared during delay.";
251 return; 292 return;
252 } 293 }
253 294
254 SavePageRequest request(*pending_request_.get()); 295 SavePageRequest request(*pending_request_.get());
255 // If there was an error navigating to page, return loading failed. 296 // If there was an error navigating to page, return loading failed.
256 if (page_load_state_ != SUCCESS) { 297 if (page_load_state_ != SUCCESS) {
257 Offliner::RequestStatus status = 298 Offliner::RequestStatus status =
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 save_status = RequestStatus::SAVED; 351 save_status = RequestStatus::SAVED;
311 else 352 else
312 save_status = RequestStatus::SAVE_FAILED; 353 save_status = RequestStatus::SAVE_FAILED;
313 354
314 completion_callback_.Run(request, save_status); 355 completion_callback_.Run(request, save_status);
315 } 356 }
316 357
317 void BackgroundLoaderOffliner::ResetState() { 358 void BackgroundLoaderOffliner::ResetState() {
318 pending_request_.reset(); 359 pending_request_.reset();
319 page_load_state_ = SUCCESS; 360 page_load_state_ = SUCCESS;
361 network_bytes_ = 0LL;
320 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners. 362 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners.
321 // We reset the loader and observer after completion so loaders 363 // We reset the loader and observer after completion so loaders
322 // will not be re-used across different requests/tries. This is a temporary 364 // will not be re-used across different requests/tries. This is a temporary
323 // solution while there exists assumptions about the number of offliners 365 // solution while there exists assumptions about the number of offliners
324 // there are. 366 // there are.
325 loader_.reset( 367 loader_.reset(
326 new background_loader::BackgroundLoaderContents(browser_context_)); 368 new background_loader::BackgroundLoaderContents(browser_context_));
327 content::WebContentsObserver::Observe(loader_.get()->web_contents()); 369 content::WebContents* contents = loader_->web_contents();
370 content::WebContentsObserver::Observe(contents);
371 OfflinerData::AddToWebContents(contents, this);
328 } 372 }
329 373
330 void BackgroundLoaderOffliner::OnApplicationStateChange( 374 void BackgroundLoaderOffliner::OnApplicationStateChange(
331 base::android::ApplicationState application_state) { 375 base::android::ApplicationState application_state) {
332 if (pending_request_ && is_low_end_device_ && 376 if (pending_request_ && is_low_end_device_ &&
333 application_state == 377 application_state ==
334 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { 378 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
335 DVLOG(1) << "App became active, canceling current offlining request"; 379 DVLOG(1) << "App became active, canceling current offlining request";
336 SavePageRequest* request = pending_request_.get(); 380 SavePageRequest* request = pending_request_.get();
337 // This works because Bind will make a copy of request, and we 381 // This works because Bind will make a copy of request, and we
338 // should not have to worry about reset being called before cancel callback. 382 // should not have to worry about reset being called before cancel callback.
339 Cancel(base::Bind( 383 Cancel(base::Bind(
340 &BackgroundLoaderOffliner::HandleApplicationStateChangeCancel, 384 &BackgroundLoaderOffliner::HandleApplicationStateChangeCancel,
341 weak_ptr_factory_.GetWeakPtr(), *request)); 385 weak_ptr_factory_.GetWeakPtr(), *request));
342 } 386 }
343 } 387 }
344 388
345 void BackgroundLoaderOffliner::HandleApplicationStateChangeCancel( 389 void BackgroundLoaderOffliner::HandleApplicationStateChangeCancel(
346 const SavePageRequest& request, 390 const SavePageRequest& request,
347 int64_t offline_id) { 391 int64_t offline_id) {
348 // If for some reason the request was reset during while waiting for callback 392 // If for some reason the request was reset during while waiting for callback
349 // ignore the completion callback. 393 // ignore the completion callback.
350 if (pending_request_ && pending_request_->request_id() != offline_id) 394 if (pending_request_ && pending_request_->request_id() != offline_id)
351 return; 395 return;
352 completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED); 396 completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED);
353 } 397 }
354 } // namespace offline_pages 398 } // namespace offline_pages
399
400 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinerData);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698