| OLD | NEW |
| 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 Loading... |
| 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) {} | 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) {} |
| 62 | 83 |
| 63 CronetBidirectionalStreamAdapter::~CronetBidirectionalStreamAdapter() { | 84 CronetBidirectionalStreamAdapter::~CronetBidirectionalStreamAdapter() { |
| 64 DCHECK(context_->IsOnNetworkThread()); | 85 DCHECK(context_->IsOnNetworkThread()); |
| 65 } | 86 } |
| 66 | 87 |
| 67 jint CronetBidirectionalStreamAdapter::Start( | 88 jint CronetBidirectionalStreamAdapter::Start( |
| 68 JNIEnv* env, | 89 JNIEnv* env, |
| 69 const JavaParamRef<jobject>& jcaller, | 90 const base::android::JavaParamRef<jobject>& jcaller, |
| 70 const JavaParamRef<jstring>& jurl, | 91 const base::android::JavaParamRef<jstring>& jurl, |
| 71 jint jpriority, | 92 jint jpriority, |
| 72 const JavaParamRef<jstring>& jmethod, | 93 const base::android::JavaParamRef<jstring>& jmethod, |
| 73 const JavaParamRef<jobjectArray>& jheaders, | 94 const base::android::JavaParamRef<jobjectArray>& jheaders, |
| 74 jboolean jend_of_stream) { | 95 jboolean jend_of_stream) { |
| 75 // Prepare request info here to be able to return the error. | 96 // Prepare request info here to be able to return the error. |
| 76 scoped_ptr<net::BidirectionalStreamRequestInfo> request_info( | 97 scoped_ptr<net::BidirectionalStreamRequestInfo> request_info( |
| 77 new net::BidirectionalStreamRequestInfo()); | 98 new net::BidirectionalStreamRequestInfo()); |
| 78 request_info->url = GURL(ConvertJavaStringToUTF8(env, jurl)); | 99 request_info->url = GURL(ConvertJavaStringToUTF8(env, jurl)); |
| 79 request_info->priority = static_cast<net::RequestPriority>(jpriority); | 100 request_info->priority = static_cast<net::RequestPriority>(jpriority); |
| 80 // Http method is a token, just as header name. | 101 // Http method is a token, just as header name. |
| 81 request_info->method = ConvertJavaStringToUTF8(env, jmethod); | 102 request_info->method = ConvertJavaStringToUTF8(env, jmethod); |
| 82 if (!net::HttpUtil::IsValidHeaderName(request_info->method)) | 103 if (!net::HttpUtil::IsValidHeaderName(request_info->method)) |
| 83 return -1; | 104 return -1; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 97 | 118 |
| 98 context_->PostTaskToNetworkThread( | 119 context_->PostTaskToNetworkThread( |
| 99 FROM_HERE, | 120 FROM_HERE, |
| 100 base::Bind(&CronetBidirectionalStreamAdapter::StartOnNetworkThread, | 121 base::Bind(&CronetBidirectionalStreamAdapter::StartOnNetworkThread, |
| 101 base::Unretained(this), base::Passed(&request_info))); | 122 base::Unretained(this), base::Passed(&request_info))); |
| 102 return 0; | 123 return 0; |
| 103 } | 124 } |
| 104 | 125 |
| 105 jboolean CronetBidirectionalStreamAdapter::ReadData( | 126 jboolean CronetBidirectionalStreamAdapter::ReadData( |
| 106 JNIEnv* env, | 127 JNIEnv* env, |
| 107 const JavaParamRef<jobject>& jcaller, | 128 const base::android::JavaParamRef<jobject>& jcaller, |
| 108 const JavaParamRef<jobject>& jbyte_buffer, | 129 const base::android::JavaParamRef<jobject>& jbyte_buffer, |
| 109 jint jposition, | 130 jint jposition, |
| 110 jint jlimit) { | 131 jint jlimit) { |
| 111 DCHECK_LT(jposition, jlimit); | 132 DCHECK_LT(jposition, jlimit); |
| 112 | 133 |
| 113 void* data = env->GetDirectBufferAddress(jbyte_buffer); | 134 void* data = env->GetDirectBufferAddress(jbyte_buffer); |
| 114 if (!data) | 135 if (!data) |
| 115 return JNI_FALSE; | 136 return JNI_FALSE; |
| 116 | 137 |
| 117 scoped_refptr<IOBufferWithByteBuffer> read_buffer( | 138 scoped_refptr<IOBufferWithByteBuffer> read_buffer( |
| 118 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); | 139 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); |
| 119 | 140 |
| 120 int remaining_capacity = jlimit - jposition; | 141 int remaining_capacity = jlimit - jposition; |
| 121 | 142 |
| 122 context_->PostTaskToNetworkThread( | 143 context_->PostTaskToNetworkThread( |
| 123 FROM_HERE, | 144 FROM_HERE, |
| 124 base::Bind(&CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread, | 145 base::Bind(&CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread, |
| 125 base::Unretained(this), read_buffer, remaining_capacity)); | 146 base::Unretained(this), read_buffer, remaining_capacity)); |
| 126 return JNI_TRUE; | 147 return JNI_TRUE; |
| 127 } | 148 } |
| 128 | 149 |
| 129 jboolean CronetBidirectionalStreamAdapter::WriteData( | 150 jboolean CronetBidirectionalStreamAdapter::WriteData( |
| 130 JNIEnv* env, | 151 JNIEnv* env, |
| 131 const JavaParamRef<jobject>& jcaller, | 152 const base::android::JavaParamRef<jobject>& jcaller, |
| 132 const JavaParamRef<jobject>& jbyte_buffer, | 153 const base::android::JavaParamRef<jobject>& jbyte_buffer, |
| 133 jint jposition, | 154 jint jposition, |
| 134 jint jlimit, | 155 jint jlimit, |
| 135 jboolean jend_of_stream) { | 156 jboolean jend_of_stream) { |
| 136 DCHECK_LE(jposition, jlimit); | 157 DCHECK_LE(jposition, jlimit); |
| 137 | 158 |
| 138 void* data = env->GetDirectBufferAddress(jbyte_buffer); | 159 void* data = env->GetDirectBufferAddress(jbyte_buffer); |
| 139 if (!data) | 160 if (!data) |
| 140 return JNI_FALSE; | 161 return JNI_FALSE; |
| 141 | 162 |
| 142 scoped_refptr<IOBufferWithByteBuffer> write_buffer( | 163 scoped_refptr<IOBufferWithByteBuffer> write_buffer( |
| 143 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); | 164 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); |
| 144 | 165 |
| 145 int remaining_capacity = jlimit - jposition; | |
| 146 | |
| 147 context_->PostTaskToNetworkThread( | 166 context_->PostTaskToNetworkThread( |
| 148 FROM_HERE, | 167 FROM_HERE, |
| 149 base::Bind(&CronetBidirectionalStreamAdapter::WriteDataOnNetworkThread, | 168 base::Bind(&CronetBidirectionalStreamAdapter::WriteDataOnNetworkThread, |
| 150 base::Unretained(this), write_buffer, remaining_capacity, | 169 base::Unretained(this), write_buffer, jend_of_stream)); |
| 151 jend_of_stream)); | 170 return JNI_TRUE; |
| 171 } |
| 172 |
| 173 jboolean CronetBidirectionalStreamAdapter::WritevData( |
| 174 JNIEnv* env, |
| 175 const base::android::JavaParamRef<jobject>& jcaller, |
| 176 const base::android::JavaParamRef<jobjectArray>& jbyte_buffers, |
| 177 const base::android::JavaParamRef<jintArray>& jbyte_buffers_pos, |
| 178 const base::android::JavaParamRef<jintArray>& jbyte_buffers_limit, |
| 179 jboolean jend_of_stream) { |
| 180 size_t buffers_array_size = SafeGetArrayLength(env, jbyte_buffers.obj()); |
| 181 size_t pos_array_size = SafeGetArrayLength(env, jbyte_buffers.obj()); |
| 182 size_t limit_array_size = SafeGetArrayLength(env, jbyte_buffers.obj()); |
| 183 if (buffers_array_size != pos_array_size || |
| 184 pos_array_size != limit_array_size || |
| 185 buffers_array_size != limit_array_size) { |
| 186 DLOG(ERROR) << "Illegal arguments."; |
| 187 return JNI_FALSE; |
| 188 } |
| 189 |
| 190 IOByteBufferList buffers; |
| 191 for (size_t i = 0; i < buffers_array_size; ++i) { |
| 192 ScopedJavaLocalRef<jobject> jbuffer( |
| 193 env, env->GetObjectArrayElement(jbyte_buffers, i)); |
| 194 void* data = env->GetDirectBufferAddress(jbuffer.obj()); |
| 195 if (!data) |
| 196 return JNI_FALSE; |
| 197 jint pos; |
| 198 env->GetIntArrayRegion(jbyte_buffers_pos.obj(), i, 1, &pos); |
| 199 jint limit; |
| 200 env->GetIntArrayRegion(jbyte_buffers_limit.obj(), i, 1, &limit); |
| 201 DCHECK_LE(pos, limit); |
| 202 scoped_refptr<IOBufferWithByteBuffer> write_buffer( |
| 203 new IOBufferWithByteBuffer( |
| 204 env, base::android::JavaParamRef<jobject>(env, jbuffer.Release()), |
| 205 data, pos, limit)); |
| 206 buffers.push_back(write_buffer); |
| 207 } |
| 208 context_->PostTaskToNetworkThread( |
| 209 FROM_HERE, |
| 210 base::Bind(&CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread, |
| 211 base::Unretained(this), buffers, jend_of_stream)); |
| 212 |
| 152 return JNI_TRUE; | 213 return JNI_TRUE; |
| 153 } | 214 } |
| 154 | 215 |
| 155 void CronetBidirectionalStreamAdapter::Destroy( | 216 void CronetBidirectionalStreamAdapter::Destroy( |
| 156 JNIEnv* env, | 217 JNIEnv* env, |
| 157 const JavaParamRef<jobject>& jcaller, | 218 const base::android::JavaParamRef<jobject>& jcaller, |
| 158 jboolean jsend_on_canceled) { | 219 jboolean jsend_on_canceled) { |
| 159 // Destroy could be called from any thread, including network thread (if | 220 // Destroy could be called from any thread, including network thread (if |
| 160 // posting task to executor throws an exception), but is posted, so |this| | 221 // 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 | 222 // 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 | 223 // within a synchronized java block that guarantees no future posts to the |
| 163 // network thread with the adapter pointer. | 224 // network thread with the adapter pointer. |
| 164 context_->PostTaskToNetworkThread( | 225 context_->PostTaskToNetworkThread( |
| 165 FROM_HERE, | 226 FROM_HERE, |
| 166 base::Bind(&CronetBidirectionalStreamAdapter::DestroyOnNetworkThread, | 227 base::Bind(&CronetBidirectionalStreamAdapter::DestroyOnNetworkThread, |
| 167 base::Unretained(this), jsend_on_canceled)); | 228 base::Unretained(this), jsend_on_canceled)); |
| 168 } | 229 } |
| 169 | 230 |
| 170 void CronetBidirectionalStreamAdapter::OnHeadersSent() { | 231 void CronetBidirectionalStreamAdapter::OnStreamReady() { |
| 171 DCHECK(context_->IsOnNetworkThread()); | 232 DCHECK(context_->IsOnNetworkThread()); |
| 172 JNIEnv* env = base::android::AttachCurrentThread(); | 233 JNIEnv* env = base::android::AttachCurrentThread(); |
| 173 cronet::Java_CronetBidirectionalStream_onRequestHeadersSent(env, | 234 cronet::Java_CronetBidirectionalStream_onStreamReady(env, owner_.obj()); |
| 174 owner_.obj()); | |
| 175 } | 235 } |
| 176 | 236 |
| 177 void CronetBidirectionalStreamAdapter::OnHeadersReceived( | 237 void CronetBidirectionalStreamAdapter::OnHeadersReceived( |
| 178 const net::SpdyHeaderBlock& response_headers) { | 238 const net::SpdyHeaderBlock& response_headers) { |
| 179 DCHECK(context_->IsOnNetworkThread()); | 239 DCHECK(context_->IsOnNetworkThread()); |
| 180 JNIEnv* env = base::android::AttachCurrentThread(); | 240 JNIEnv* env = base::android::AttachCurrentThread(); |
| 181 // Get http status code from response headers. | 241 // Get http status code from response headers. |
| 182 jint http_status_code = 0; | 242 jint http_status_code = 0; |
| 183 const auto http_status_header = response_headers.find(":status"); | 243 const auto http_status_header = response_headers.find(":status"); |
| 184 if (http_status_header != response_headers.end()) | 244 if (http_status_header != response_headers.end()) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 211 read_buffer_->initial_position(), read_buffer_->initial_limit(), | 271 read_buffer_->initial_position(), read_buffer_->initial_limit(), |
| 212 bidi_stream_->GetTotalReceivedBytes()); | 272 bidi_stream_->GetTotalReceivedBytes()); |
| 213 // Free the read buffer. This lets the Java ByteBuffer be freed, if the | 273 // Free the read buffer. This lets the Java ByteBuffer be freed, if the |
| 214 // embedder releases it, too. | 274 // embedder releases it, too. |
| 215 read_buffer_ = nullptr; | 275 read_buffer_ = nullptr; |
| 216 } | 276 } |
| 217 | 277 |
| 218 void CronetBidirectionalStreamAdapter::OnDataSent() { | 278 void CronetBidirectionalStreamAdapter::OnDataSent() { |
| 219 DCHECK(context_->IsOnNetworkThread()); | 279 DCHECK(context_->IsOnNetworkThread()); |
| 220 JNIEnv* env = base::android::AttachCurrentThread(); | 280 JNIEnv* env = base::android::AttachCurrentThread(); |
| 221 cronet::Java_CronetBidirectionalStream_onWriteCompleted( | 281 if (!disable_auto_flush_) { |
| 222 env, owner_.obj(), write_buffer_->byte_buffer(), | 282 cronet::Java_CronetBidirectionalStream_onWriteCompleted( |
| 223 write_buffer_->initial_position(), write_buffer_->initial_limit()); | 283 env, owner_.obj(), write_buffer_->byte_buffer(), |
| 224 // Free the write buffer. This lets the Java ByteBuffer be freed, if the | 284 write_buffer_->initial_position(), write_buffer_->initial_limit(), |
| 225 // embedder releases it, too. | 285 write_end_of_stream_); |
| 226 write_buffer_ = nullptr; | 286 // Free the write buffer. This lets the Java ByteBuffer be freed, if the |
| 287 // embedder releases it, too. |
| 288 write_buffer_ = nullptr; |
| 289 } else { |
| 290 DCHECK(!write_buffer_list_.empty()); |
| 291 base::android::ScopedJavaLocalRef<jclass> byte_buffer_clazz( |
| 292 env, env->GetObjectClass(write_buffer_list_[0]->byte_buffer())); |
| 293 size_t size = write_buffer_list_.size(); |
| 294 jobjectArray jbuffers = |
| 295 env->NewObjectArray(size, byte_buffer_clazz.obj(), NULL); |
| 296 base::android::CheckException(env); |
| 297 std::vector<int> initial_positions; |
| 298 std::vector<int> initial_limits; |
| 299 for (size_t i = 0; i < size; ++i) { |
| 300 env->SetObjectArrayElement(jbuffers, i, |
| 301 write_buffer_list_[i]->byte_buffer()); |
| 302 initial_positions.push_back(write_buffer_list_[i]->initial_position()); |
| 303 initial_limits.push_back(write_buffer_list_[i]->initial_limit()); |
| 304 } |
| 305 ScopedJavaLocalRef<jintArray> jinitial_positions = |
| 306 base::android::ToJavaIntArray(env, initial_positions); |
| 307 ScopedJavaLocalRef<jintArray> jinitial_limits = |
| 308 base::android::ToJavaIntArray(env, initial_limits); |
| 309 // Call into Java. |
| 310 cronet::Java_CronetBidirectionalStream_onWritevCompleted( |
| 311 env, owner_.obj(), jbuffers, jinitial_positions.obj(), |
| 312 jinitial_limits.obj(), write_end_of_stream_); |
| 313 // Free the write buffers. This lets the Java ByteBuffer be freed, if the |
| 314 // embedder releases it, too. |
| 315 write_buffer_list_.clear(); |
| 316 } |
| 227 } | 317 } |
| 228 | 318 |
| 229 void CronetBidirectionalStreamAdapter::OnTrailersReceived( | 319 void CronetBidirectionalStreamAdapter::OnTrailersReceived( |
| 230 const net::SpdyHeaderBlock& response_trailers) { | 320 const net::SpdyHeaderBlock& response_trailers) { |
| 231 DCHECK(context_->IsOnNetworkThread()); | 321 DCHECK(context_->IsOnNetworkThread()); |
| 232 JNIEnv* env = base::android::AttachCurrentThread(); | 322 JNIEnv* env = base::android::AttachCurrentThread(); |
| 233 cronet::Java_CronetBidirectionalStream_onResponseTrailersReceived( | 323 cronet::Java_CronetBidirectionalStream_onResponseTrailersReceived( |
| 234 env, owner_.obj(), GetHeadersArray(env, response_trailers).obj()); | 324 env, owner_.obj(), GetHeadersArray(env, response_trailers).obj()); |
| 235 } | 325 } |
| 236 | 326 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 248 DCHECK(context_->IsOnNetworkThread()); | 338 DCHECK(context_->IsOnNetworkThread()); |
| 249 DCHECK(!bidi_stream_); | 339 DCHECK(!bidi_stream_); |
| 250 request_info->extra_headers.SetHeaderIfMissing( | 340 request_info->extra_headers.SetHeaderIfMissing( |
| 251 net::HttpRequestHeaders::kUserAgent, context_->GetURLRequestContext() | 341 net::HttpRequestHeaders::kUserAgent, context_->GetURLRequestContext() |
| 252 ->http_user_agent_settings() | 342 ->http_user_agent_settings() |
| 253 ->GetUserAgent()); | 343 ->GetUserAgent()); |
| 254 bidi_stream_.reset(new net::BidirectionalStream( | 344 bidi_stream_.reset(new net::BidirectionalStream( |
| 255 std::move(request_info), context_->GetURLRequestContext() | 345 std::move(request_info), context_->GetURLRequestContext() |
| 256 ->http_transaction_factory() | 346 ->http_transaction_factory() |
| 257 ->GetSession(), | 347 ->GetSession(), |
| 258 this)); | 348 disable_auto_flush_, this)); |
| 259 } | 349 } |
| 260 | 350 |
| 261 void CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread( | 351 void CronetBidirectionalStreamAdapter::ReadDataOnNetworkThread( |
| 262 scoped_refptr<IOBufferWithByteBuffer> read_buffer, | 352 scoped_refptr<IOBufferWithByteBuffer> read_buffer, |
| 263 int buffer_size) { | 353 int buffer_size) { |
| 264 DCHECK(context_->IsOnNetworkThread()); | 354 DCHECK(context_->IsOnNetworkThread()); |
| 265 DCHECK(read_buffer); | 355 DCHECK(read_buffer); |
| 266 DCHECK(!read_buffer_); | 356 DCHECK(!read_buffer_); |
| 267 | 357 |
| 268 read_buffer_ = read_buffer; | 358 read_buffer_ = read_buffer; |
| 269 | 359 |
| 270 int bytes_read = bidi_stream_->ReadData(read_buffer_.get(), buffer_size); | 360 int bytes_read = bidi_stream_->ReadData(read_buffer_.get(), buffer_size); |
| 271 // If IO is pending, wait for the BidirectionalStream to call OnDataRead. | 361 // If IO is pending, wait for the BidirectionalStream to call OnDataRead. |
| 272 if (bytes_read == net::ERR_IO_PENDING) | 362 if (bytes_read == net::ERR_IO_PENDING) |
| 273 return; | 363 return; |
| 274 | 364 |
| 275 if (bytes_read < 0) { | 365 if (bytes_read < 0) { |
| 276 OnFailed(bytes_read); | 366 OnFailed(bytes_read); |
| 277 return; | 367 return; |
| 278 } | 368 } |
| 279 OnDataRead(bytes_read); | 369 OnDataRead(bytes_read); |
| 280 } | 370 } |
| 281 | 371 |
| 282 void CronetBidirectionalStreamAdapter::WriteDataOnNetworkThread( | 372 void CronetBidirectionalStreamAdapter::WriteDataOnNetworkThread( |
| 283 scoped_refptr<IOBufferWithByteBuffer> write_buffer, | 373 scoped_refptr<IOBufferWithByteBuffer> write_buffer, |
| 284 int buffer_size, | |
| 285 bool end_of_stream) { | 374 bool end_of_stream) { |
| 286 DCHECK(context_->IsOnNetworkThread()); | 375 DCHECK(context_->IsOnNetworkThread()); |
| 287 DCHECK(write_buffer); | 376 DCHECK(write_buffer); |
| 288 DCHECK(!write_buffer_); | 377 DCHECK(!write_buffer_); |
| 378 DCHECK(!write_end_of_stream_); |
| 289 | 379 |
| 380 write_end_of_stream_ = end_of_stream; |
| 290 write_buffer_ = write_buffer; | 381 write_buffer_ = write_buffer; |
| 382 int buffer_size = |
| 383 write_buffer->initial_limit() - write_buffer->initial_position(); |
| 291 bidi_stream_->SendData(write_buffer_.get(), buffer_size, end_of_stream); | 384 bidi_stream_->SendData(write_buffer_.get(), buffer_size, end_of_stream); |
| 292 } | 385 } |
| 293 | 386 |
| 387 void CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread( |
| 388 const IOByteBufferList& write_buffer_list, |
| 389 bool end_of_stream) { |
| 390 DCHECK(context_->IsOnNetworkThread()); |
| 391 DCHECK(!write_buffer_); |
| 392 DCHECK(write_buffer_list_.empty()); |
| 393 DCHECK(!write_buffer_list.empty()); |
| 394 DCHECK(!write_end_of_stream_); |
| 395 |
| 396 write_end_of_stream_ = end_of_stream; |
| 397 std::vector<net::IOBuffer*> buffers; |
| 398 std::vector<int> lengths; |
| 399 for (const auto& buffer : write_buffer_list) { |
| 400 write_buffer_list_.push_back(buffer); |
| 401 buffers.push_back(buffer.get()); |
| 402 lengths.push_back(buffer->initial_limit() - buffer->initial_position()); |
| 403 } |
| 404 bidi_stream_->SendvData(buffers, lengths, end_of_stream); |
| 405 } |
| 406 |
| 294 void CronetBidirectionalStreamAdapter::DestroyOnNetworkThread( | 407 void CronetBidirectionalStreamAdapter::DestroyOnNetworkThread( |
| 295 bool send_on_canceled) { | 408 bool send_on_canceled) { |
| 296 DCHECK(context_->IsOnNetworkThread()); | 409 DCHECK(context_->IsOnNetworkThread()); |
| 297 if (send_on_canceled) { | 410 if (send_on_canceled) { |
| 298 JNIEnv* env = base::android::AttachCurrentThread(); | 411 JNIEnv* env = base::android::AttachCurrentThread(); |
| 299 cronet::Java_CronetBidirectionalStream_onCanceled(env, owner_.obj()); | 412 cronet::Java_CronetBidirectionalStream_onCanceled(env, owner_.obj()); |
| 300 } | 413 } |
| 301 delete this; | 414 delete this; |
| 302 } | 415 } |
| 303 | 416 |
| 304 base::android::ScopedJavaLocalRef<jobjectArray> | 417 base::android::ScopedJavaLocalRef<jobjectArray> |
| 305 CronetBidirectionalStreamAdapter::GetHeadersArray( | 418 CronetBidirectionalStreamAdapter::GetHeadersArray( |
| 306 JNIEnv* env, | 419 JNIEnv* env, |
| 307 const net::SpdyHeaderBlock& header_block) { | 420 const net::SpdyHeaderBlock& header_block) { |
| 308 DCHECK(context_->IsOnNetworkThread()); | 421 DCHECK(context_->IsOnNetworkThread()); |
| 309 | 422 |
| 310 std::vector<std::string> headers; | 423 std::vector<std::string> headers; |
| 311 for (const auto& header : header_block) { | 424 for (const auto& header : header_block) { |
| 312 headers.push_back(header.first.as_string()); | 425 headers.push_back(header.first.as_string()); |
| 313 headers.push_back(header.second.as_string()); | 426 headers.push_back(header.second.as_string()); |
| 314 } | 427 } |
| 315 return base::android::ToJavaArrayOfStrings(env, headers); | 428 return base::android::ToJavaArrayOfStrings(env, headers); |
| 316 } | 429 } |
| 317 | 430 |
| 318 } // namespace cronet | 431 } // namespace cronet |
| OLD | NEW |