1 // Copyright 2018 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 "components/offline_pages/core/background/offliner_client.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "components/offline_pages/core/background/save_page_request.h"
11
12 namespace offline_pages {
13
OfflinerClient(std::unique_ptr<Offliner> offliner,const Offliner::ProgressCallback & progress_callback)14 OfflinerClient::OfflinerClient(
15 std::unique_ptr<Offliner> offliner,
16 const Offliner::ProgressCallback& progress_callback)
17 : offliner_(std::move(offliner)), progress_callback_(progress_callback) {}
18
19 OfflinerClient::~OfflinerClient() = default;
20
LoadAndSave(const SavePageRequest & request,base::TimeDelta timeout,CompleteCallback complete_callback)21 bool OfflinerClient::LoadAndSave(const SavePageRequest& request,
22 base::TimeDelta timeout,
23 CompleteCallback complete_callback) {
24 if (Active())
25 return false;
26 if (!offliner_->LoadAndSave(request,
27 base::BindOnce(&OfflinerClient::OfflinerComplete,
28 base::Unretained(this)),
29 progress_callback_)) {
30 return false;
31 }
32 stopping_ = false;
33 active_request_ = std::make_unique<SavePageRequest>(request);
34 complete_callback_ = std::move(complete_callback);
35 watchdog_timer_.Start(FROM_HERE, timeout, this,
36 &OfflinerClient::HandleWatchdogTimeout);
37 return true;
38 }
39
Stop(Offliner::RequestStatus status)40 void OfflinerClient::Stop(Offliner::RequestStatus status) {
41 if (!active_request_ || stopping_)
42 return;
43 if (offliner_->Cancel(base::BindOnce(&OfflinerClient::CancelComplete,
44 base::Unretained(this), status))) {
45 stopping_ = true;
46 } else {
47 Finish(status);
48 }
49 }
50
HandleWatchdogTimeout()51 void OfflinerClient::HandleWatchdogTimeout() {
52 if (!active_request_ || stopping_)
53 return;
54 // Check if the offliner can finish up now.
55 if (offliner_->HandleTimeout(active_request_->request_id()))
56 return;
57 if (offliner_->Cancel(base::BindOnce(
58 &OfflinerClient::CancelComplete, base::Unretained(this),
59 Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT))) {
60 stopping_ = true;
61 } else {
62 Finish(Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT);
63 }
64 }
65
CancelComplete(Offliner::RequestStatus cancel_reason,const SavePageRequest & request)66 void OfflinerClient::CancelComplete(Offliner::RequestStatus cancel_reason,
67 const SavePageRequest& request) {
68 watchdog_timer_.Stop();
69 if (active_request_)
70 Finish(cancel_reason);
71 }
72
OfflinerComplete(const SavePageRequest & request,Offliner::RequestStatus status)73 void OfflinerClient::OfflinerComplete(const SavePageRequest& request,
74 Offliner::RequestStatus status) {
75 if (active_request_)
76 Finish(status);
77 watchdog_timer_.Stop();
78 }
79
Finish(Offliner::RequestStatus status)80 void OfflinerClient::Finish(Offliner::RequestStatus status) {
81 stopping_ = false;
82 std::unique_ptr<SavePageRequest> request = std::move(active_request_);
83 std::move(complete_callback_).Run(*request, status);
84 }
85
86 } // namespace offline_pages
87