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

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

Issue 2737343002: [Offline Pages] Allow BackgroundLoader to track network bytes using prerenderer hook-in. (Closed)
Patch Set: mark background contents code as android-only 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/supports_user_data.h"
8 #include "base/sys_info.h" 9 #include "base/sys_info.h"
9 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h" 10 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
10 #include "chrome/browser/android/offline_pages/offliner_helper.h" 11 #include "chrome/browser/android/offline_pages/offliner_helper.h"
11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
12 #include "components/offline_pages/core/background/save_page_request.h" 13 #include "components/offline_pages/core/background/save_page_request.h"
13 #include "components/offline_pages/core/client_namespace_constants.h" 14 #include "components/offline_pages/core/client_namespace_constants.h"
14 #include "components/offline_pages/core/offline_page_model.h" 15 #include "components/offline_pages/core/offline_page_model.h"
15 #include "content/public/browser/browser_context.h" 16 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/navigation_handle.h" 17 #include "content/public/browser/navigation_handle.h"
17 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents.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 const char kOfflinerDataKey[] = "offliner-key";
Dmitry Titov 2017/03/11 01:10:28 An even better variant of this is to do that: con
chili 2017/03/13 20:41:56 Done. I extended WebContentsUserData, which has in
25
26 class OfflinerData : public base::SupportsUserData::Data {
27 public:
28 explicit OfflinerData(BackgroundLoaderOffliner* offliner) {
29 offliner_ = offliner;
30 }
31 BackgroundLoaderOffliner* offliner() { return offliner_; }
32
33 private:
34 BackgroundLoaderOffliner* offliner_;
dewittj 2017/03/11 01:05:13 Please write a comment explaining the reason that
Dmitry Titov 2017/03/11 01:10:28 Would be nice to add a comment to describe why the
chili 2017/03/13 20:41:56 Done.
chili 2017/03/13 20:41:56 Done.
35 };
36
23 } // namespace 37 } // namespace
24 38
25 BackgroundLoaderOffliner::BackgroundLoaderOffliner( 39 BackgroundLoaderOffliner::BackgroundLoaderOffliner(
26 content::BrowserContext* browser_context, 40 content::BrowserContext* browser_context,
27 const OfflinerPolicy* policy, 41 const OfflinerPolicy* policy,
28 OfflinePageModel* offline_page_model) 42 OfflinePageModel* offline_page_model)
29 : browser_context_(browser_context), 43 : browser_context_(browser_context),
30 offline_page_model_(offline_page_model), 44 offline_page_model_(offline_page_model),
31 is_low_end_device_(base::SysInfo::IsLowEndDevice()), 45 is_low_end_device_(base::SysInfo::IsLowEndDevice()),
32 save_state_(NONE), 46 save_state_(NONE),
33 page_load_state_(SUCCESS), 47 page_load_state_(SUCCESS),
34 page_delay_ms_(kOfflinePageDelayMs), 48 page_delay_ms_(kOfflinePageDelayMs),
49 network_bytes_(0LL),
35 weak_ptr_factory_(this) { 50 weak_ptr_factory_(this) {
36 DCHECK(offline_page_model_); 51 DCHECK(offline_page_model_);
37 DCHECK(browser_context_); 52 DCHECK(browser_context_);
38 } 53 }
39 54
40 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {} 55 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {}
41 56
42 // TODO(dimich): Invoke progress_callback as appropriate. 57 // static
58 BackgroundLoaderOffliner* BackgroundLoaderOffliner::FromWebContents(
59 content::WebContents* contents) {
60 OfflinerData* data =
61 static_cast<OfflinerData*>(contents->GetUserData(kOfflinerDataKey));
62 if (data)
63 return data->offliner();
64 return nullptr;
65 }
66
43 bool BackgroundLoaderOffliner::LoadAndSave( 67 bool BackgroundLoaderOffliner::LoadAndSave(
44 const SavePageRequest& request, 68 const SavePageRequest& request,
45 const CompletionCallback& completion_callback, 69 const CompletionCallback& completion_callback,
46 const ProgressCallback& progress_callback) { 70 const ProgressCallback& progress_callback) {
47 DCHECK(completion_callback); 71 DCHECK(completion_callback);
48 DCHECK(progress_callback); 72 DCHECK(progress_callback);
49 73
50 if (pending_request_) { 74 if (pending_request_) {
51 DVLOG(1) << "Already have pending request"; 75 DVLOG(1) << "Already have pending request";
52 return false; 76 return false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 126
103 if (!loader_) 127 if (!loader_)
104 ResetState(); 128 ResetState();
105 129
106 // Invalidate ptrs for all delayed/saving tasks. 130 // Invalidate ptrs for all delayed/saving tasks.
107 weak_ptr_factory_.InvalidateWeakPtrs(); 131 weak_ptr_factory_.InvalidateWeakPtrs();
108 132
109 // Track copy of pending request. 133 // Track copy of pending request.
110 pending_request_.reset(new SavePageRequest(request)); 134 pending_request_.reset(new SavePageRequest(request));
111 completion_callback_ = completion_callback; 135 completion_callback_ = completion_callback;
136 progress_callback_ = progress_callback;
112 137
113 // Listen for app foreground/background change. 138 // Listen for app foreground/background change.
114 app_listener_.reset(new base::android::ApplicationStatusListener( 139 app_listener_.reset(new base::android::ApplicationStatusListener(
115 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange, 140 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange,
116 weak_ptr_factory_.GetWeakPtr()))); 141 weak_ptr_factory_.GetWeakPtr())));
117 142
118 // Load page attempt. 143 // Load page attempt.
119 loader_.get()->LoadPage(request.url()); 144 loader_.get()->LoadPage(request.url());
120 145
121 return true; 146 return true;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 if (navigation_handle->HasCommitted() && 268 if (navigation_handle->HasCommitted() &&
244 !navigation_handle->IsSameDocument()) { 269 !navigation_handle->IsSameDocument()) {
245 weak_ptr_factory_.InvalidateWeakPtrs(); 270 weak_ptr_factory_.InvalidateWeakPtrs();
246 } 271 }
247 } 272 }
248 273
249 void BackgroundLoaderOffliner::SetPageDelayForTest(long delay_ms) { 274 void BackgroundLoaderOffliner::SetPageDelayForTest(long delay_ms) {
250 page_delay_ms_ = delay_ms; 275 page_delay_ms_ = delay_ms;
251 } 276 }
252 277
278 void BackgroundLoaderOffliner::OnNetworkBytesChanged(int64_t bytes) {
279 if (pending_request_ && save_state_ != SAVING) {
280 network_bytes_ += bytes;
281 SavePageRequest request(*pending_request_.get());
dewittj 2017/03/13 17:38:20 Last I remember, .get() is not required to derefer
chili 2017/03/13 20:41:56 Done.
282 progress_callback_.Run(request, network_bytes_);
283 }
284 }
285
253 void BackgroundLoaderOffliner::SavePage() { 286 void BackgroundLoaderOffliner::SavePage() {
254 if (!pending_request_.get()) { 287 if (!pending_request_.get()) {
255 DVLOG(1) << "Pending request was cleared during delay."; 288 DVLOG(1) << "Pending request was cleared during delay.";
256 return; 289 return;
257 } 290 }
258 291
259 SavePageRequest request(*pending_request_.get()); 292 SavePageRequest request(*pending_request_.get());
260 // If there was an error navigating to page, return loading failed. 293 // If there was an error navigating to page, return loading failed.
261 if (page_load_state_ != SUCCESS) { 294 if (page_load_state_ != SUCCESS) {
262 Offliner::RequestStatus status; 295 Offliner::RequestStatus status;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 save_status = RequestStatus::SAVED; 360 save_status = RequestStatus::SAVED;
328 else 361 else
329 save_status = RequestStatus::SAVE_FAILED; 362 save_status = RequestStatus::SAVE_FAILED;
330 363
331 completion_callback_.Run(request, save_status); 364 completion_callback_.Run(request, save_status);
332 } 365 }
333 366
334 void BackgroundLoaderOffliner::ResetState() { 367 void BackgroundLoaderOffliner::ResetState() {
335 pending_request_.reset(); 368 pending_request_.reset();
336 page_load_state_ = SUCCESS; 369 page_load_state_ = SUCCESS;
370 network_bytes_ = 0LL;
337 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners. 371 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners.
338 // We reset the loader and observer after completion so loaders 372 // We reset the loader and observer after completion so loaders
339 // will not be re-used across different requests/tries. This is a temporary 373 // will not be re-used across different requests/tries. This is a temporary
340 // solution while there exists assumptions about the number of offliners 374 // solution while there exists assumptions about the number of offliners
341 // there are. 375 // there are.
342 loader_.reset( 376 loader_.reset(
343 new background_loader::BackgroundLoaderContents(browser_context_)); 377 new background_loader::BackgroundLoaderContents(browser_context_));
344 content::WebContentsObserver::Observe(loader_.get()->web_contents()); 378 content::WebContentsObserver::Observe(loader_.get()->web_contents());
379 std::unique_ptr<OfflinerData> offliner_data(new OfflinerData(this));
380 loader_.get()->web_contents()->SetUserData(kOfflinerDataKey,
dewittj 2017/03/11 01:05:13 nit: combine this (loader_.get()->web_contents())
chili 2017/03/13 20:41:56 Done.
381 std::move(offliner_data));
345 } 382 }
346 383
347 void BackgroundLoaderOffliner::OnApplicationStateChange( 384 void BackgroundLoaderOffliner::OnApplicationStateChange(
348 base::android::ApplicationState application_state) { 385 base::android::ApplicationState application_state) {
349 if (pending_request_ && is_low_end_device_ && 386 if (pending_request_ && is_low_end_device_ &&
350 application_state == 387 application_state ==
351 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { 388 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
352 DVLOG(1) << "App became active, canceling current offlining request"; 389 DVLOG(1) << "App became active, canceling current offlining request";
353 SavePageRequest* request = pending_request_.get(); 390 SavePageRequest* request = pending_request_.get();
354 // This works because Bind will make a copy of request, and we 391 // This works because Bind will make a copy of request, and we
355 // should not have to worry about reset being called before cancel callback. 392 // should not have to worry about reset being called before cancel callback.
356 Cancel(base::Bind( 393 Cancel(base::Bind(
357 &BackgroundLoaderOffliner::HandleApplicationStateChangeCancel, 394 &BackgroundLoaderOffliner::HandleApplicationStateChangeCancel,
358 weak_ptr_factory_.GetWeakPtr(), *request)); 395 weak_ptr_factory_.GetWeakPtr(), *request));
359 } 396 }
360 } 397 }
361 398
362 void BackgroundLoaderOffliner::HandleApplicationStateChangeCancel( 399 void BackgroundLoaderOffliner::HandleApplicationStateChangeCancel(
363 const SavePageRequest& request, 400 const SavePageRequest& request,
364 int64_t offline_id) { 401 int64_t offline_id) {
365 // If for some reason the request was reset during while waiting for callback 402 // If for some reason the request was reset during while waiting for callback
366 // ignore the completion callback. 403 // ignore the completion callback.
367 if (pending_request_ && pending_request_->request_id() != offline_id) 404 if (pending_request_ && pending_request_->request_id() != offline_id)
368 return; 405 return;
369 completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED); 406 completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED);
370 } 407 }
371 } // namespace offline_pages 408 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698