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

Side by Side Diff: content/child/url_loader_client_impl.cc

Issue 2591383003: Implement SetDefersLoading on content::URLLoaderClientImpl (Closed)
Patch Set: fix Created 3 years, 12 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 "content/child/url_loader_client_impl.h" 5 #include "content/child/url_loader_client_impl.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/single_thread_task_runner.h" 8 #include "base/single_thread_task_runner.h"
9 #include "content/child/resource_dispatcher.h" 9 #include "content/child/resource_dispatcher.h"
10 #include "content/child/url_response_body_consumer.h" 10 #include "content/child/url_response_body_consumer.h"
11 #include "content/common/resource_messages.h" 11 #include "content/common/resource_messages.h"
12 #include "mojo/public/cpp/bindings/associated_group.h" 12 #include "mojo/public/cpp/bindings/associated_group.h"
13 #include "net/url_request/redirect_info.h" 13 #include "net/url_request/redirect_info.h"
14 14
15 namespace content { 15 namespace content {
16 16
17 URLLoaderClientImpl::URLLoaderClientImpl( 17 URLLoaderClientImpl::URLLoaderClientImpl(
18 int request_id, 18 int request_id,
19 ResourceDispatcher* resource_dispatcher, 19 ResourceDispatcher* resource_dispatcher,
20 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 20 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
21 : binding_(this), 21 : binding_(this),
22 request_id_(request_id), 22 request_id_(request_id),
23 resource_dispatcher_(resource_dispatcher), 23 resource_dispatcher_(resource_dispatcher),
24 task_runner_(std::move(task_runner)) {} 24 task_runner_(std::move(task_runner)),
25 weak_factory_(this) {}
25 26
26 URLLoaderClientImpl::~URLLoaderClientImpl() { 27 URLLoaderClientImpl::~URLLoaderClientImpl() {
27 if (body_consumer_) 28 if (body_consumer_)
28 body_consumer_->Cancel(); 29 body_consumer_->Cancel();
29 } 30 }
30 31
31 void URLLoaderClientImpl::Bind( 32 void URLLoaderClientImpl::Bind(
32 mojom::URLLoaderClientAssociatedPtrInfo* client_ptr_info, 33 mojom::URLLoaderClientAssociatedPtrInfo* client_ptr_info,
33 mojo::AssociatedGroup* associated_group) { 34 mojo::AssociatedGroup* associated_group) {
34 binding_.Bind(client_ptr_info, associated_group); 35 binding_.Bind(client_ptr_info, associated_group);
35 } 36 }
36 37
38 void URLLoaderClientImpl::SetDefersLoading() {
39 is_deferred_ = true;
40 if (body_consumer_)
41 body_consumer_->SetDefersLoading();
42 }
43
44 void URLLoaderClientImpl::UnsetDefersLoading() {
45 is_deferred_ = false;
46 }
47
48 void URLLoaderClientImpl::FlushDeferredMessages() {
49 DCHECK(!is_deferred_);
50 std::vector<IPC::Message> messages;
51 messages.swap(deferred_messages_);
52 bool has_completion_message = false;
53 base::WeakPtr<URLLoaderClientImpl> weak_this = weak_factory_.GetWeakPtr();
54 // First, dispatch all messages excluding the followings:
55 // - response body (dispatched by |body_consumer_|)
56 // - transfer size change (dispatched later)
57 // - completion (dispatched by |body_consumer_| or dispatched later)
58 for (size_t index = 0; index < messages.size(); ++index) {
59 if (messages[index].type() == ResourceMsg_RequestComplete::ID) {
60 // The completion message arrives at the end of the message queue.
61 DCHECK(!has_completion_message);
62 DCHECK_EQ(index, messages.size() - 1);
63 has_completion_message = true;
64 break;
65 }
66 Dispatch(messages[index]);
67 if (!weak_this)
68 return;
69 if (is_deferred_) {
70 deferred_messages_.insert(deferred_messages_.begin(),
71 messages.begin() + index + 1, messages.end());
72 return;
73 }
74 }
75
76 // Dispatch the transfer size update.
77 if (accumulated_transfer_size_diff_during_deferred_ > 0) {
78 auto transfer_size_diff = accumulated_transfer_size_diff_during_deferred_;
79 accumulated_transfer_size_diff_during_deferred_ = 0;
80 resource_dispatcher_->OnTransferSizeUpdated(request_id_,
81 transfer_size_diff);
82 if (!weak_this)
83 return;
84 if (is_deferred_) {
85 if (has_completion_message)
86 deferred_messages_.emplace_back(std::move(messages.back()));
kinuko 2016/12/27 01:52:21 nit: can we add a comment (or documentary DCHECK)
yhirano 2016/12/27 07:32:54 Done.
87 return;
88 }
89 }
90
91 if (body_consumer_) {
92 // When we have |body_consumer_|, the completion message is dispatched by
93 // it, not by this object.
94 DCHECK(!has_completion_message);
95 // Dispatch the response body.
96 body_consumer_->UnsetDefersLoading();
97 return;
98 }
99
100 // Dispatch the completion message.
101 if (has_completion_message) {
102 DCHECK_GT(messages.size(), 0u);
103 DCHECK_EQ(messages.back().type(),
104 static_cast<uint32_t>(ResourceMsg_RequestComplete::ID));
105 Dispatch(messages.back());
106 }
107 }
108
37 void URLLoaderClientImpl::OnReceiveResponse( 109 void URLLoaderClientImpl::OnReceiveResponse(
38 const ResourceResponseHead& response_head, 110 const ResourceResponseHead& response_head,
39 mojom::DownloadedTempFilePtr downloaded_file) { 111 mojom::DownloadedTempFilePtr downloaded_file) {
40 has_received_response_ = true; 112 has_received_response_ = true;
41 if (body_consumer_) 113 if (body_consumer_)
42 body_consumer_->Start(); 114 body_consumer_->Start();
43 downloaded_file_ = std::move(downloaded_file); 115 downloaded_file_ = std::move(downloaded_file);
44 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head)); 116 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head));
45 } 117 }
46 118
47 void URLLoaderClientImpl::OnReceiveRedirect( 119 void URLLoaderClientImpl::OnReceiveRedirect(
48 const net::RedirectInfo& redirect_info, 120 const net::RedirectInfo& redirect_info,
49 const ResourceResponseHead& response_head) { 121 const ResourceResponseHead& response_head) {
50 DCHECK(!has_received_response_); 122 DCHECK(!has_received_response_);
51 DCHECK(!body_consumer_); 123 DCHECK(!body_consumer_);
52 Dispatch( 124 Dispatch(
53 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head)); 125 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head));
54 } 126 }
55 127
56 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len, 128 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len,
57 int64_t encoded_data_len) { 129 int64_t encoded_data_len) {
58 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len)); 130 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len));
59 } 131 }
60 132
61 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) { 133 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) {
62 resource_dispatcher_->OnTransferSizeUpdated(request_id_, 134 if (is_deferred_) {
63 transfer_size_diff); 135 accumulated_transfer_size_diff_during_deferred_ += transfer_size_diff;
136 } else {
137 resource_dispatcher_->OnTransferSizeUpdated(request_id_,
138 transfer_size_diff);
139 }
64 } 140 }
65 141
66 void URLLoaderClientImpl::OnStartLoadingResponseBody( 142 void URLLoaderClientImpl::OnStartLoadingResponseBody(
67 mojo::ScopedDataPipeConsumerHandle body) { 143 mojo::ScopedDataPipeConsumerHandle body) {
68 DCHECK(!body_consumer_); 144 DCHECK(!body_consumer_);
69 body_consumer_ = new URLResponseBodyConsumer( 145 body_consumer_ = new URLResponseBodyConsumer(
70 request_id_, resource_dispatcher_, std::move(body), task_runner_); 146 request_id_, resource_dispatcher_, std::move(body), task_runner_);
71 if (has_received_response_) 147 if (has_received_response_)
72 body_consumer_->Start(); 148 body_consumer_->Start();
149 if (is_deferred_)
150 body_consumer_->SetDefersLoading();
73 } 151 }
74 152
75 void URLLoaderClientImpl::OnComplete( 153 void URLLoaderClientImpl::OnComplete(
76 const ResourceRequestCompletionStatus& status) { 154 const ResourceRequestCompletionStatus& status) {
77 if (!body_consumer_) { 155 if (!body_consumer_) {
78 Dispatch(ResourceMsg_RequestComplete(request_id_, status)); 156 Dispatch(ResourceMsg_RequestComplete(request_id_, status));
79 return; 157 return;
80 } 158 }
81 body_consumer_->OnComplete(status); 159 body_consumer_->OnComplete(status);
82 } 160 }
83 161
84 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) { 162 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) {
85 resource_dispatcher_->OnMessageReceived(message); 163 if (is_deferred_) {
164 deferred_messages_.push_back(message);
165 } else if (deferred_messages_.size() > 0) {
166 deferred_messages_.push_back(message);
167 FlushDeferredMessages();
168 } else {
169 resource_dispatcher_->DispatchMessage(message);
170 }
86 } 171 }
87 172
88 } // namespace content 173 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698