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

Side by Side Diff: components/cronet/android/cronet_bidirectional_stream_adapter.cc

Issue 1856073002: Coalesce small buffers in net::BidirectionalStream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix javadoc Created 4 years, 8 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "cronet_bidirectional_stream_adapter.h" 5 #include "cronet_bidirectional_stream_adapter.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 16 matching lines...) Expand all
27 #include "net/ssl/ssl_info.h" 27 #include "net/ssl/ssl_info.h"
28 #include "net/url_request/http_user_agent_settings.h" 28 #include "net/url_request/http_user_agent_settings.h"
29 #include "net/url_request/url_request_context.h" 29 #include "net/url_request/url_request_context.h"
30 #include "url/gurl.h" 30 #include "url/gurl.h"
31 31
32 using base::android::ConvertUTF8ToJavaString; 32 using base::android::ConvertUTF8ToJavaString;
33 using base::android::ConvertJavaStringToUTF8; 33 using base::android::ConvertJavaStringToUTF8;
34 34
35 namespace cronet { 35 namespace cronet {
36 36
37 namespace {
38
39 // As |GetArrayLength| makes no guarantees about the returned value (e.g., it
40 // may be -1 if |array| is not a valid Java array), provide a safe wrapper
41 // that always returns a valid, non-negative size.
42 template <typename JavaArrayType>
43 size_t SafeGetArrayLength(JNIEnv* env, JavaArrayType jarray) {
44 DCHECK(jarray);
45 jsize length = env->GetArrayLength(jarray);
46 DCHECK_GE(length, 0) << "Invalid array length: " << length;
47 return static_cast<size_t>(std::max(0, length));
48 }
49
50 } // namespace
51
37 static jlong CreateBidirectionalStream( 52 static jlong CreateBidirectionalStream(
38 JNIEnv* env, 53 JNIEnv* env,
39 const JavaParamRef<jobject>& jbidi_stream, 54 const base::android::JavaParamRef<jobject>& jbidi_stream,
40 jlong jurl_request_context_adapter) { 55 jlong jurl_request_context_adapter,
56 jboolean jdisable_auto_flush) {
41 CronetURLRequestContextAdapter* context_adapter = 57 CronetURLRequestContextAdapter* context_adapter =
42 reinterpret_cast<CronetURLRequestContextAdapter*>( 58 reinterpret_cast<CronetURLRequestContextAdapter*>(
43 jurl_request_context_adapter); 59 jurl_request_context_adapter);
44 DCHECK(context_adapter); 60 DCHECK(context_adapter);
45 61
46 CronetBidirectionalStreamAdapter* adapter = 62 CronetBidirectionalStreamAdapter* adapter =
47 new CronetBidirectionalStreamAdapter(context_adapter, env, jbidi_stream); 63 new CronetBidirectionalStreamAdapter(context_adapter, env, jbidi_stream,
64 jdisable_auto_flush);
48 65
49 return reinterpret_cast<jlong>(adapter); 66 return reinterpret_cast<jlong>(adapter);
50 } 67 }
51 68
52 // static 69 // static
53 bool CronetBidirectionalStreamAdapter::RegisterJni(JNIEnv* env) { 70 bool CronetBidirectionalStreamAdapter::RegisterJni(JNIEnv* env) {
54 return RegisterNativesImpl(env); 71 return RegisterNativesImpl(env);
55 } 72 }
56 73
57 CronetBidirectionalStreamAdapter::CronetBidirectionalStreamAdapter( 74 CronetBidirectionalStreamAdapter::CronetBidirectionalStreamAdapter(
58 CronetURLRequestContextAdapter* context, 75 CronetURLRequestContextAdapter* context,
59 JNIEnv* env, 76 JNIEnv* env,
60 const JavaParamRef<jobject>& jbidi_stream) 77 const base::android::JavaParamRef<jobject>& jbidi_stream,
61 : context_(context), owner_(env, jbidi_stream), stream_failed_(false) {} 78 bool disable_auto_flush)
79 : context_(context),
80 owner_(env, jbidi_stream),
81 disable_auto_flush_(disable_auto_flush),
82 write_end_of_stream_(false),
83 stream_failed_(false) {}
62 84
63 CronetBidirectionalStreamAdapter::~CronetBidirectionalStreamAdapter() { 85 CronetBidirectionalStreamAdapter::~CronetBidirectionalStreamAdapter() {
64 DCHECK(context_->IsOnNetworkThread()); 86 DCHECK(context_->IsOnNetworkThread());
65 } 87 }
66 88
67 jint CronetBidirectionalStreamAdapter::Start( 89 jint CronetBidirectionalStreamAdapter::Start(
68 JNIEnv* env, 90 JNIEnv* env,
69 const JavaParamRef<jobject>& jcaller, 91 const base::android::JavaParamRef<jobject>& jcaller,
70 const JavaParamRef<jstring>& jurl, 92 const base::android::JavaParamRef<jstring>& jurl,
71 jint jpriority, 93 jint jpriority,
72 const JavaParamRef<jstring>& jmethod, 94 const base::android::JavaParamRef<jstring>& jmethod,
73 const JavaParamRef<jobjectArray>& jheaders, 95 const base::android::JavaParamRef<jobjectArray>& jheaders,
74 jboolean jend_of_stream) { 96 jboolean jend_of_stream) {
75 // Prepare request info here to be able to return the error. 97 // Prepare request info here to be able to return the error.
76 std::unique_ptr<net::BidirectionalStreamRequestInfo> request_info( 98 std::unique_ptr<net::BidirectionalStreamRequestInfo> request_info(
77 new net::BidirectionalStreamRequestInfo()); 99 new net::BidirectionalStreamRequestInfo());
78 request_info->url = GURL(ConvertJavaStringToUTF8(env, jurl)); 100 request_info->url = GURL(ConvertJavaStringToUTF8(env, jurl));
79 request_info->priority = static_cast<net::RequestPriority>(jpriority); 101 request_info->priority = static_cast<net::RequestPriority>(jpriority);
80 // Http method is a token, just as header name. 102 // Http method is a token, just as header name.
81 request_info->method = ConvertJavaStringToUTF8(env, jmethod); 103 request_info->method = ConvertJavaStringToUTF8(env, jmethod);
82 if (!net::HttpUtil::IsValidHeaderName(request_info->method)) 104 if (!net::HttpUtil::IsValidHeaderName(request_info->method))
83 return -1; 105 return -1;
(...skipping 13 matching lines...) Expand all
97 119
98 context_->PostTaskToNetworkThread( 120 context_->PostTaskToNetworkThread(
99 FROM_HERE, 121 FROM_HERE,
100 base::Bind(&CronetBidirectionalStreamAdapter::StartOnNetworkThread, 122 base::Bind(&CronetBidirectionalStreamAdapter::StartOnNetworkThread,
101 base::Unretained(this), base::Passed(&request_info))); 123 base::Unretained(this), base::Passed(&request_info)));
102 return 0; 124 return 0;
103 } 125 }
104 126
105 jboolean CronetBidirectionalStreamAdapter::ReadData( 127 jboolean CronetBidirectionalStreamAdapter::ReadData(
106 JNIEnv* env, 128 JNIEnv* env,
107 const JavaParamRef<jobject>& jcaller, 129 const base::android::JavaParamRef<jobject>& jcaller,
108 const JavaParamRef<jobject>& jbyte_buffer, 130 const base::android::JavaParamRef<jobject>& jbyte_buffer,
109 jint jposition, 131 jint jposition,
110 jint jlimit) { 132 jint jlimit) {
111 DCHECK_LT(jposition, jlimit); 133 DCHECK_LT(jposition, jlimit);
112 134
113 void* data = env->GetDirectBufferAddress(jbyte_buffer); 135 void* data = env->GetDirectBufferAddress(jbyte_buffer);
114 if (!data) 136 if (!data)
115 return JNI_FALSE; 137 return JNI_FALSE;
116 138
117 scoped_refptr<IOBufferWithByteBuffer> read_buffer( 139 scoped_refptr<IOBufferWithByteBuffer> read_buffer(
118 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); 140 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit));
119 141
120 int remaining_capacity = jlimit - jposition; 142 int remaining_capacity = jlimit - jposition;
121 143
122 context_->PostTaskToNetworkThread( 144 context_->PostTaskToNetworkThread(
123 FROM_HERE, 145 FROM_HERE,
124 base::Bind(&CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread, 146 base::Bind(&CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread,
125 base::Unretained(this), read_buffer, remaining_capacity)); 147 base::Unretained(this), read_buffer, remaining_capacity));
126 return JNI_TRUE; 148 return JNI_TRUE;
127 } 149 }
128 150
129 jboolean CronetBidirectionalStreamAdapter::WriteData( 151 jboolean CronetBidirectionalStreamAdapter::WritevData(
130 JNIEnv* env, 152 JNIEnv* env,
131 const JavaParamRef<jobject>& jcaller, 153 const base::android::JavaParamRef<jobject>& jcaller,
132 const JavaParamRef<jobject>& jbyte_buffer, 154 const base::android::JavaParamRef<jobjectArray>& jbyte_buffers,
133 jint jposition, 155 const base::android::JavaParamRef<jintArray>& jbyte_buffers_pos,
134 jint jlimit, 156 const base::android::JavaParamRef<jintArray>& jbyte_buffers_limit,
135 jboolean jend_of_stream) { 157 jboolean jend_of_stream) {
136 DCHECK_LE(jposition, jlimit); 158 size_t buffers_array_size = SafeGetArrayLength(env, jbyte_buffers.obj());
159 size_t pos_array_size = SafeGetArrayLength(env, jbyte_buffers.obj());
160 size_t limit_array_size = SafeGetArrayLength(env, jbyte_buffers.obj());
161 if (buffers_array_size != pos_array_size ||
162 buffers_array_size != limit_array_size) {
163 DLOG(ERROR) << "Illegal arguments.";
164 return JNI_FALSE;
165 }
137 166
138 void* data = env->GetDirectBufferAddress(jbyte_buffer); 167 IOByteBufferList buffers;
139 if (!data) 168 for (size_t i = 0; i < buffers_array_size; ++i) {
140 return JNI_FALSE; 169 ScopedJavaLocalRef<jobject> jbuffer(
141 170 env, env->GetObjectArrayElement(jbyte_buffers, i));
142 scoped_refptr<IOBufferWithByteBuffer> write_buffer( 171 void* data = env->GetDirectBufferAddress(jbuffer.obj());
143 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); 172 if (!data)
144 173 return JNI_FALSE;
145 int remaining_capacity = jlimit - jposition; 174 jint pos;
146 175 env->GetIntArrayRegion(jbyte_buffers_pos.obj(), i, 1, &pos);
176 jint limit;
177 env->GetIntArrayRegion(jbyte_buffers_limit.obj(), i, 1, &limit);
178 DCHECK_LE(pos, limit);
179 scoped_refptr<IOBufferWithByteBuffer> write_buffer(
180 new IOBufferWithByteBuffer(
181 env, base::android::JavaParamRef<jobject>(env, jbuffer.Release()),
182 data, pos, limit));
183 buffers.push_back(write_buffer);
184 }
147 context_->PostTaskToNetworkThread( 185 context_->PostTaskToNetworkThread(
148 FROM_HERE, 186 FROM_HERE,
149 base::Bind(&CronetBidirectionalStreamAdapter::WriteDataOnNetworkThread, 187 base::Bind(&CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread,
150 base::Unretained(this), write_buffer, remaining_capacity, 188 base::Unretained(this), buffers, jend_of_stream));
151 jend_of_stream)); 189
152 return JNI_TRUE; 190 return JNI_TRUE;
153 } 191 }
154 192
155 void CronetBidirectionalStreamAdapter::Destroy( 193 void CronetBidirectionalStreamAdapter::Destroy(
156 JNIEnv* env, 194 JNIEnv* env,
157 const JavaParamRef<jobject>& jcaller, 195 const base::android::JavaParamRef<jobject>& jcaller,
158 jboolean jsend_on_canceled) { 196 jboolean jsend_on_canceled) {
159 // Destroy could be called from any thread, including network thread (if 197 // Destroy could be called from any thread, including network thread (if
160 // posting task to executor throws an exception), but is posted, so |this| 198 // posting task to executor throws an exception), but is posted, so |this|
161 // is valid until calling task is complete. Destroy() is always called from 199 // is valid until calling task is complete. Destroy() is always called from
162 // within a synchronized java block that guarantees no future posts to the 200 // within a synchronized java block that guarantees no future posts to the
163 // network thread with the adapter pointer. 201 // network thread with the adapter pointer.
164 context_->PostTaskToNetworkThread( 202 context_->PostTaskToNetworkThread(
165 FROM_HERE, 203 FROM_HERE,
166 base::Bind(&CronetBidirectionalStreamAdapter::DestroyOnNetworkThread, 204 base::Bind(&CronetBidirectionalStreamAdapter::DestroyOnNetworkThread,
167 base::Unretained(this), jsend_on_canceled)); 205 base::Unretained(this), jsend_on_canceled));
168 } 206 }
169 207
170 void CronetBidirectionalStreamAdapter::OnHeadersSent() { 208 void CronetBidirectionalStreamAdapter::OnStreamReady() {
171 DCHECK(context_->IsOnNetworkThread()); 209 DCHECK(context_->IsOnNetworkThread());
172 JNIEnv* env = base::android::AttachCurrentThread(); 210 JNIEnv* env = base::android::AttachCurrentThread();
173 cronet::Java_CronetBidirectionalStream_onRequestHeadersSent(env, 211 cronet::Java_CronetBidirectionalStream_onStreamReady(env, owner_.obj());
174 owner_.obj());
175 } 212 }
176 213
177 void CronetBidirectionalStreamAdapter::OnHeadersReceived( 214 void CronetBidirectionalStreamAdapter::OnHeadersReceived(
178 const net::SpdyHeaderBlock& response_headers) { 215 const net::SpdyHeaderBlock& response_headers) {
179 DCHECK(context_->IsOnNetworkThread()); 216 DCHECK(context_->IsOnNetworkThread());
180 JNIEnv* env = base::android::AttachCurrentThread(); 217 JNIEnv* env = base::android::AttachCurrentThread();
181 // Get http status code from response headers. 218 // Get http status code from response headers.
182 jint http_status_code = 0; 219 jint http_status_code = 0;
183 const auto http_status_header = response_headers.find(":status"); 220 const auto http_status_header = response_headers.find(":status");
184 if (http_status_header != response_headers.end()) 221 if (http_status_header != response_headers.end())
(...skipping 25 matching lines...) Expand all
210 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read, 247 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read,
211 read_buffer_->initial_position(), read_buffer_->initial_limit(), 248 read_buffer_->initial_position(), read_buffer_->initial_limit(),
212 bidi_stream_->GetTotalReceivedBytes()); 249 bidi_stream_->GetTotalReceivedBytes());
213 // Free the read buffer. This lets the Java ByteBuffer be freed, if the 250 // Free the read buffer. This lets the Java ByteBuffer be freed, if the
214 // embedder releases it, too. 251 // embedder releases it, too.
215 read_buffer_ = nullptr; 252 read_buffer_ = nullptr;
216 } 253 }
217 254
218 void CronetBidirectionalStreamAdapter::OnDataSent() { 255 void CronetBidirectionalStreamAdapter::OnDataSent() {
219 DCHECK(context_->IsOnNetworkThread()); 256 DCHECK(context_->IsOnNetworkThread());
257 DCHECK(!write_buffer_list_.empty());
258
220 JNIEnv* env = base::android::AttachCurrentThread(); 259 JNIEnv* env = base::android::AttachCurrentThread();
221 cronet::Java_CronetBidirectionalStream_onWriteCompleted( 260 base::android::ScopedJavaLocalRef<jclass> byte_buffer_clazz(
222 env, owner_.obj(), write_buffer_->byte_buffer(), 261 env, env->GetObjectClass(write_buffer_list_[0]->byte_buffer()));
223 write_buffer_->initial_position(), write_buffer_->initial_limit()); 262 size_t size = write_buffer_list_.size();
224 // Free the write buffer. This lets the Java ByteBuffer be freed, if the 263 jobjectArray jbuffers =
264 env->NewObjectArray(size, byte_buffer_clazz.obj(), NULL);
265 base::android::CheckException(env);
266 std::vector<int> initial_positions;
267 std::vector<int> initial_limits;
268 for (size_t i = 0; i < size; ++i) {
269 env->SetObjectArrayElement(jbuffers, i,
270 write_buffer_list_[i]->byte_buffer());
271 initial_positions.push_back(write_buffer_list_[i]->initial_position());
272 initial_limits.push_back(write_buffer_list_[i]->initial_limit());
273 }
274 ScopedJavaLocalRef<jintArray> jinitial_positions =
275 base::android::ToJavaIntArray(env, initial_positions);
276 ScopedJavaLocalRef<jintArray> jinitial_limits =
277 base::android::ToJavaIntArray(env, initial_limits);
278 // Call into Java.
279 cronet::Java_CronetBidirectionalStream_onWritevCompleted(
280 env, owner_.obj(), jbuffers, jinitial_positions.obj(),
281 jinitial_limits.obj(), write_end_of_stream_);
282 // Free the write buffers. This lets the Java ByteBuffer be freed, if the
225 // embedder releases it, too. 283 // embedder releases it, too.
226 write_buffer_ = nullptr; 284 write_buffer_list_.clear();
227 } 285 }
228 286
229 void CronetBidirectionalStreamAdapter::OnTrailersReceived( 287 void CronetBidirectionalStreamAdapter::OnTrailersReceived(
230 const net::SpdyHeaderBlock& response_trailers) { 288 const net::SpdyHeaderBlock& response_trailers) {
231 DCHECK(context_->IsOnNetworkThread()); 289 DCHECK(context_->IsOnNetworkThread());
232 JNIEnv* env = base::android::AttachCurrentThread(); 290 JNIEnv* env = base::android::AttachCurrentThread();
233 cronet::Java_CronetBidirectionalStream_onResponseTrailersReceived( 291 cronet::Java_CronetBidirectionalStream_onResponseTrailersReceived(
234 env, owner_.obj(), GetHeadersArray(env, response_trailers).obj()); 292 env, owner_.obj(), GetHeadersArray(env, response_trailers).obj());
235 } 293 }
236 294
(...skipping 12 matching lines...) Expand all
249 DCHECK(context_->IsOnNetworkThread()); 307 DCHECK(context_->IsOnNetworkThread());
250 DCHECK(!bidi_stream_); 308 DCHECK(!bidi_stream_);
251 request_info->extra_headers.SetHeaderIfMissing( 309 request_info->extra_headers.SetHeaderIfMissing(
252 net::HttpRequestHeaders::kUserAgent, context_->GetURLRequestContext() 310 net::HttpRequestHeaders::kUserAgent, context_->GetURLRequestContext()
253 ->http_user_agent_settings() 311 ->http_user_agent_settings()
254 ->GetUserAgent()); 312 ->GetUserAgent());
255 bidi_stream_.reset(new net::BidirectionalStream( 313 bidi_stream_.reset(new net::BidirectionalStream(
256 std::move(request_info), context_->GetURLRequestContext() 314 std::move(request_info), context_->GetURLRequestContext()
257 ->http_transaction_factory() 315 ->http_transaction_factory()
258 ->GetSession(), 316 ->GetSession(),
259 this)); 317 disable_auto_flush_, this));
260 } 318 }
261 319
262 void CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread( 320 void CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread(
263 scoped_refptr<IOBufferWithByteBuffer> read_buffer, 321 scoped_refptr<IOBufferWithByteBuffer> read_buffer,
264 int buffer_size) { 322 int buffer_size) {
265 DCHECK(context_->IsOnNetworkThread()); 323 DCHECK(context_->IsOnNetworkThread());
266 DCHECK(read_buffer); 324 DCHECK(read_buffer);
267 DCHECK(!read_buffer_); 325 DCHECK(!read_buffer_);
268 326
269 read_buffer_ = read_buffer; 327 read_buffer_ = read_buffer;
270 328
271 int bytes_read = bidi_stream_->ReadData(read_buffer_.get(), buffer_size); 329 int bytes_read = bidi_stream_->ReadData(read_buffer_.get(), buffer_size);
272 // If IO is pending, wait for the BidirectionalStream to call OnDataRead. 330 // If IO is pending, wait for the BidirectionalStream to call OnDataRead.
273 if (bytes_read == net::ERR_IO_PENDING) 331 if (bytes_read == net::ERR_IO_PENDING)
274 return; 332 return;
275 333
276 if (bytes_read < 0) { 334 if (bytes_read < 0) {
277 OnFailed(bytes_read); 335 OnFailed(bytes_read);
278 return; 336 return;
279 } 337 }
280 OnDataRead(bytes_read); 338 OnDataRead(bytes_read);
281 } 339 }
282 340
283 void CronetBidirectionalStreamAdapter::WriteDataOnNetworkThread( 341 void CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread(
284 scoped_refptr<IOBufferWithByteBuffer> write_buffer, 342 const IOByteBufferList& write_buffer_list,
285 int buffer_size,
286 bool end_of_stream) { 343 bool end_of_stream) {
287 DCHECK(context_->IsOnNetworkThread()); 344 DCHECK(context_->IsOnNetworkThread());
288 DCHECK(write_buffer); 345 DCHECK(write_buffer_list_.empty());
289 DCHECK(!write_buffer_); 346 DCHECK(!write_buffer_list.empty());
347 DCHECK(!write_end_of_stream_);
290 348
291 if (stream_failed_) { 349 if (stream_failed_) {
292 // If stream failed between the time when WriteData is invoked and 350 // If stream failed between the time when WriteData is invoked and
293 // WriteDataOnNetworkThread is executed, do not call into |bidi_stream_| 351 // WriteDataOnNetworkThread is executed, do not call into |bidi_stream_|
294 // since the underlying stream might have been destroyed. Do not invoke 352 // since the underlying stream might have been destroyed. Do not invoke
295 // Java callback either, since onError is posted when |stream_failed_| is 353 // Java callback either, since onError is posted when |stream_failed_| is
296 // set to true. 354 // set to true.
297 return; 355 return;
298 } 356 }
299 write_buffer_ = write_buffer; 357
300 bidi_stream_->SendData(write_buffer_.get(), buffer_size, end_of_stream); 358 write_end_of_stream_ = end_of_stream;
359 std::vector<net::IOBuffer*> buffers;
360 std::vector<int> lengths;
361 for (const auto& buffer : write_buffer_list) {
362 write_buffer_list_.push_back(buffer);
363 buffers.push_back(buffer.get());
364 lengths.push_back(buffer->initial_limit() - buffer->initial_position());
365 }
366 if (buffers.size() == 1) {
367 bidi_stream_->SendData(buffers[0], lengths[0], end_of_stream);
368 } else {
369 bidi_stream_->SendvData(buffers, lengths, end_of_stream);
370 }
301 } 371 }
302 372
303 void CronetBidirectionalStreamAdapter::DestroyOnNetworkThread( 373 void CronetBidirectionalStreamAdapter::DestroyOnNetworkThread(
304 bool send_on_canceled) { 374 bool send_on_canceled) {
305 DCHECK(context_->IsOnNetworkThread()); 375 DCHECK(context_->IsOnNetworkThread());
306 if (send_on_canceled) { 376 if (send_on_canceled) {
307 JNIEnv* env = base::android::AttachCurrentThread(); 377 JNIEnv* env = base::android::AttachCurrentThread();
308 cronet::Java_CronetBidirectionalStream_onCanceled(env, owner_.obj()); 378 cronet::Java_CronetBidirectionalStream_onCanceled(env, owner_.obj());
309 } 379 }
310 delete this; 380 delete this;
311 } 381 }
312 382
313 base::android::ScopedJavaLocalRef<jobjectArray> 383 base::android::ScopedJavaLocalRef<jobjectArray>
314 CronetBidirectionalStreamAdapter::GetHeadersArray( 384 CronetBidirectionalStreamAdapter::GetHeadersArray(
315 JNIEnv* env, 385 JNIEnv* env,
316 const net::SpdyHeaderBlock& header_block) { 386 const net::SpdyHeaderBlock& header_block) {
317 DCHECK(context_->IsOnNetworkThread()); 387 DCHECK(context_->IsOnNetworkThread());
318 388
319 std::vector<std::string> headers; 389 std::vector<std::string> headers;
320 for (const auto& header : header_block) { 390 for (const auto& header : header_block) {
321 headers.push_back(header.first.as_string()); 391 headers.push_back(header.first.as_string());
322 headers.push_back(header.second.as_string()); 392 headers.push_back(header.second.as_string());
323 } 393 }
324 return base::android::ToJavaArrayOfStrings(env, headers); 394 return base::android::ToJavaArrayOfStrings(env, headers);
325 } 395 }
326 396
327 } // namespace cronet 397 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698