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

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 DCHECK_GT(messages.size(), 0u);
87 DCHECK_EQ(messages.back().type(),
88 static_cast<uint32_t>(ResourceMsg_RequestComplete::ID));
89 deferred_messages_.emplace_back(std::move(messages.back()));
90 }
91 return;
92 }
93 }
94
95 if (body_consumer_) {
96 // When we have |body_consumer_|, the completion message is dispatched by
97 // it, not by this object.
98 DCHECK(!has_completion_message);
99 // Dispatch the response body.
100 body_consumer_->UnsetDefersLoading();
101 return;
102 }
103
104 // Dispatch the completion message.
105 if (has_completion_message) {
106 DCHECK_GT(messages.size(), 0u);
107 DCHECK_EQ(messages.back().type(),
108 static_cast<uint32_t>(ResourceMsg_RequestComplete::ID));
109 Dispatch(messages.back());
110 }
111 }
112
37 void URLLoaderClientImpl::OnReceiveResponse( 113 void URLLoaderClientImpl::OnReceiveResponse(
38 const ResourceResponseHead& response_head, 114 const ResourceResponseHead& response_head,
39 mojom::DownloadedTempFilePtr downloaded_file) { 115 mojom::DownloadedTempFilePtr downloaded_file) {
40 has_received_response_ = true; 116 has_received_response_ = true;
41 if (body_consumer_) 117 if (body_consumer_)
42 body_consumer_->Start(); 118 body_consumer_->Start();
43 downloaded_file_ = std::move(downloaded_file); 119 downloaded_file_ = std::move(downloaded_file);
44 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head)); 120 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head));
45 } 121 }
46 122
47 void URLLoaderClientImpl::OnReceiveRedirect( 123 void URLLoaderClientImpl::OnReceiveRedirect(
48 const net::RedirectInfo& redirect_info, 124 const net::RedirectInfo& redirect_info,
49 const ResourceResponseHead& response_head) { 125 const ResourceResponseHead& response_head) {
50 DCHECK(!has_received_response_); 126 DCHECK(!has_received_response_);
51 DCHECK(!body_consumer_); 127 DCHECK(!body_consumer_);
52 Dispatch( 128 Dispatch(
53 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head)); 129 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head));
54 } 130 }
55 131
56 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len, 132 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len,
57 int64_t encoded_data_len) { 133 int64_t encoded_data_len) {
58 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len)); 134 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len));
59 } 135 }
60 136
61 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) { 137 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) {
62 resource_dispatcher_->OnTransferSizeUpdated(request_id_, 138 if (is_deferred_) {
63 transfer_size_diff); 139 accumulated_transfer_size_diff_during_deferred_ += transfer_size_diff;
140 } else {
141 resource_dispatcher_->OnTransferSizeUpdated(request_id_,
142 transfer_size_diff);
143 }
64 } 144 }
65 145
66 void URLLoaderClientImpl::OnStartLoadingResponseBody( 146 void URLLoaderClientImpl::OnStartLoadingResponseBody(
67 mojo::ScopedDataPipeConsumerHandle body) { 147 mojo::ScopedDataPipeConsumerHandle body) {
68 DCHECK(!body_consumer_); 148 DCHECK(!body_consumer_);
69 body_consumer_ = new URLResponseBodyConsumer( 149 body_consumer_ = new URLResponseBodyConsumer(
70 request_id_, resource_dispatcher_, std::move(body), task_runner_); 150 request_id_, resource_dispatcher_, std::move(body), task_runner_);
71 if (has_received_response_) 151 if (has_received_response_)
72 body_consumer_->Start(); 152 body_consumer_->Start();
153 if (is_deferred_)
154 body_consumer_->SetDefersLoading();
73 } 155 }
74 156
75 void URLLoaderClientImpl::OnComplete( 157 void URLLoaderClientImpl::OnComplete(
76 const ResourceRequestCompletionStatus& status) { 158 const ResourceRequestCompletionStatus& status) {
77 if (!body_consumer_) { 159 if (!body_consumer_) {
78 Dispatch(ResourceMsg_RequestComplete(request_id_, status)); 160 Dispatch(ResourceMsg_RequestComplete(request_id_, status));
79 return; 161 return;
80 } 162 }
81 body_consumer_->OnComplete(status); 163 body_consumer_->OnComplete(status);
82 } 164 }
83 165
84 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) { 166 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) {
85 resource_dispatcher_->OnMessageReceived(message); 167 if (is_deferred_) {
168 deferred_messages_.push_back(message);
169 } else if (deferred_messages_.size() > 0) {
170 deferred_messages_.push_back(message);
171 FlushDeferredMessages();
172 } else {
173 resource_dispatcher_->DispatchMessage(message);
174 }
86 } 175 }
87 176
88 } // namespace content 177 } // namespace content
OLDNEW
« no previous file with comments | « content/child/url_loader_client_impl.h ('k') | content/child/url_loader_client_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698