Chromium Code Reviews| OLD | NEW | 
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "upload_data_stream_handler.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/android/jni_android.h" | |
| 10 #include "base/android/jni_string.h" | |
| 11 #include "base/android/scoped_java_ref.h" | |
| 12 #include "base/bind.h" | |
| 13 #include "base/macros.h" | |
| 14 #include "base/memory/ref_counted.h" | |
| 15 #include "base/message_loop/message_loop_proxy.h" | |
| 16 #include "base/threading/thread.h" | |
| 17 #include "components/cronet/android/cronet_upload_data_stream_adapter.h" | |
| 18 #include "jni/UploadDataStreamHandler_jni.h" | |
| 19 #include "net/base/io_buffer.h" | |
| 20 #include "net/base/net_errors.h" | |
| 21 #include "net/base/upload_data_stream.h" | |
| 22 | |
| 23 namespace cronet { | |
| 24 | |
| 25 namespace { | |
| 26 | |
| 27 static const size_t kReadBufferSize = 32768; | |
| 28 | |
| 29 /** | |
| 30 * This class sets up the JNI for Java tests to invoke methods on the native | |
| 31 * CronetUploadDataStreamAdapter. | |
| 32 */ | |
| 33 class UploadDataStreamHandler { | |
| 34 public: | |
| 35 UploadDataStreamHandler(CronetUploadDataStreamAdapter* adapter, | |
| 36 JNIEnv* env, | |
| 37 jobject jupload_data_stream_handler); | |
| 38 | |
| 39 ~UploadDataStreamHandler(); | |
| 40 | |
| 41 // Destroys |network_thread_| created by this class. | |
| 42 void Destroy(); | |
| 43 | |
| 44 // Posts a task to |network_thread_| to call the corresponding method of | |
| 45 // CronetUploadDataStreamAdapter on |adapter_|. | |
| 46 | |
| 47 void Init(); | |
| 48 void Read(); | |
| 49 void Reset(); | |
| 50 | |
| 51 // Posts a task to |network_thread_| to check whether init complete callback | |
| 52 // has been invoked by net::UploadDataStream, and notifies the Java side of | |
| 53 // the result. | |
| 54 void CheckInitCallbackNotInvoked(); | |
| 55 // Posts a task to |network_thread_| to check whether read complete callback | |
| 56 // has been invoked by net::UploadDataStream, and notifies the Java side of | |
| 57 // the result. | |
| 58 void CheckReadCallbackNotInvoked(); | |
| 59 | |
| 60 private: | |
| 61 // Complete callbacks that are passed to the |adapter_|. | |
| 62 void OnInitCompleted(int res); | |
| 63 void OnReadCompleted(int res); | |
| 64 | |
| 65 // Helper methods that run corresponding task on |network_thread_|. | |
| 66 | |
| 67 void InitOnNetworkThread(); | |
| 68 void ReadOnNetworkThread(); | |
| 69 void ResetOnNetworkThread(); | |
| 70 void CheckInitCallbackNotInvokedOnNetworkThread(); | |
| 71 void CheckReadCallbackNotInvokedOnNetworkThread(); | |
| 72 | |
| 73 // Notify the Java UploadDataStreamHandler that read has completed. | |
| 74 void NotifyJavaReadCompleted(); | |
| 75 | |
| 76 // True if |OnInitCompleted| callback has been invoked. It is set to false | |
| 77 // when init or reset is called again. Created on a Java thread, but are only | |
| 78 // accessed from |network_thread_|. | |
| 79 bool init_callback_invoked_; | |
| 80 // True if |OnReadCompleted| callback has been invoked. It is set to false | |
| 81 // when init or reset is called again. Created on a Java thread, but are only | |
| 82 // accessed from |network_thread_|. | |
| 83 bool read_callback_invoked_; | |
| 84 // Indicates the number of bytes read. It is reset to 0 when init, reset, or | |
| 85 // read is called again. Created on a Java thread, but are only accessed from | |
| 86 // |network_thread_|. | |
| 87 int bytes_read_; | |
| 88 | |
| 89 // Created and destroyed on the same Java thread. This is where methods of | |
| 90 // CronetUploadDataStreamAdapter run on. | |
| 91 scoped_ptr<base::Thread> network_thread_; | |
| 92 // Created on a Java thread. Accessed only on |network_thread_|. | |
| 93 scoped_ptr<CronetUploadDataStreamAdapter> adapter_; | |
| 94 // Created and accessed only on |network_thread_|. | |
| 95 scoped_refptr<net::IOBufferWithSize> read_buffer_; | |
| 96 // A Java reference pointer for calling methods on the Java | |
| 97 // UploadDataStreamHandler object. Initialized during construction. | |
| 98 base::android::ScopedJavaGlobalRef<jobject> jupload_data_stream_handler_; | |
| 99 | |
| 100 DISALLOW_COPY_AND_ASSIGN(UploadDataStreamHandler); | |
| 101 }; | |
| 102 | |
| 103 UploadDataStreamHandler::UploadDataStreamHandler( | |
| 104 CronetUploadDataStreamAdapter* adapter, | |
| 105 JNIEnv* env, | |
| 106 jobject jupload_data_stream_handler) | |
| 107 : init_callback_invoked_(false), | |
| 108 read_callback_invoked_(false), | |
| 109 bytes_read_(0), | |
| 110 network_thread_(new base::Thread("network")), | |
| 111 adapter_(adapter) { | |
| 112 base::Thread::Options options; | |
| 113 options.message_loop_type = base::MessageLoop::TYPE_IO; | |
| 114 network_thread_->StartWithOptions(options); | |
| 115 jupload_data_stream_handler_.Reset(env, jupload_data_stream_handler); | |
| 116 } | |
| 117 | |
| 118 UploadDataStreamHandler::~UploadDataStreamHandler() { | |
| 119 } | |
| 120 | |
| 121 void UploadDataStreamHandler::Destroy() { | |
| 122 DCHECK(!network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 123 // Stick network_thread_ in a local, so |this| may be destroyed from the | |
| 124 // network thread before the network thread is destroyed. | |
| 125 scoped_ptr<base::Thread> network_thread = network_thread_.Pass(); | |
| 126 network_thread->task_runner()->DeleteSoon(FROM_HERE, this); | |
| 127 // Deleting thread stops it after all tasks are completed. | |
| 128 network_thread.reset(); | |
| 129 } | |
| 130 | |
| 131 void UploadDataStreamHandler::OnInitCompleted(int res) { | |
| 132 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 133 init_callback_invoked_ = true; | |
| 134 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 135 cronet::Java_UploadDataStreamHandler_onInitCompleted( | |
| 136 env, jupload_data_stream_handler_.obj(), res); | |
| 137 } | |
| 138 | |
| 139 void UploadDataStreamHandler::OnReadCompleted(int res) { | |
| 140 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 141 read_callback_invoked_ = true; | |
| 142 bytes_read_ = res; | |
| 143 NotifyJavaReadCompleted(); | |
| 144 } | |
| 145 | |
| 146 void UploadDataStreamHandler::Init() { | |
| 147 DCHECK(!network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 148 network_thread_->task_runner()->PostTask( | |
| 149 FROM_HERE, base::Bind(&UploadDataStreamHandler::InitOnNetworkThread, | |
| 150 base::Unretained(this))); | |
| 151 } | |
| 152 | |
| 153 void UploadDataStreamHandler::Read() { | |
| 154 DCHECK(!network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 155 network_thread_->task_runner()->PostTask( | |
| 156 FROM_HERE, base::Bind(&UploadDataStreamHandler::ReadOnNetworkThread, | |
| 157 base::Unretained(this))); | |
| 158 } | |
| 159 | |
| 160 void UploadDataStreamHandler::Reset() { | |
| 161 DCHECK(!network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 162 network_thread_->task_runner()->PostTask( | |
| 163 FROM_HERE, base::Bind(&UploadDataStreamHandler::ResetOnNetworkThread, | |
| 164 base::Unretained(this))); | |
| 165 } | |
| 166 | |
| 167 void UploadDataStreamHandler::CheckInitCallbackNotInvoked() { | |
| 168 DCHECK(!network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 169 network_thread_->task_runner()->PostTask( | |
| 170 FROM_HERE, | |
| 171 base::Bind( | |
| 172 &UploadDataStreamHandler::CheckInitCallbackNotInvokedOnNetworkThread, | |
| 173 base::Unretained(this))); | |
| 174 } | |
| 175 | |
| 176 void UploadDataStreamHandler::CheckReadCallbackNotInvoked() { | |
| 177 DCHECK(!network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 178 network_thread_->task_runner()->PostTask( | |
| 179 FROM_HERE, | |
| 180 base::Bind( | |
| 181 &UploadDataStreamHandler::CheckReadCallbackNotInvokedOnNetworkThread, | |
| 182 base::Unretained(this))); | |
| 183 } | |
| 184 | |
| 185 void UploadDataStreamHandler::InitOnNetworkThread() { | |
| 186 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 187 init_callback_invoked_ = false; | |
| 188 read_buffer_ = nullptr; | |
| 189 bytes_read_ = 0; | |
| 190 int res = adapter_->Init(base::Bind(&UploadDataStreamHandler::OnInitCompleted, | |
| 191 base::Unretained(this))); | |
| 192 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 193 cronet::Java_UploadDataStreamHandler_onInitCalled( | |
| 194 env, jupload_data_stream_handler_.obj(), res); | |
| 195 | |
| 196 if (res == net::OK) { | |
| 197 cronet::Java_UploadDataStreamHandler_onInitCompleted( | |
| 198 env, jupload_data_stream_handler_.obj(), res); | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 void UploadDataStreamHandler::ReadOnNetworkThread() { | |
| 203 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 204 read_callback_invoked_ = false; | |
| 205 if (!read_buffer_.get()) | |
| 206 read_buffer_ = new net::IOBufferWithSize(kReadBufferSize); | |
| 207 | |
| 208 int bytes_read = | |
| 209 adapter_->Read(read_buffer_.get(), kReadBufferSize, | |
| 210 base::Bind(&UploadDataStreamHandler::OnReadCompleted, | |
| 211 base::Unretained(this))); | |
| 212 if (bytes_read == net::OK) { | |
| 213 bytes_read_ = bytes_read; | |
| 214 NotifyJavaReadCompleted(); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 void UploadDataStreamHandler::ResetOnNetworkThread() { | |
| 219 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 220 init_callback_invoked_ = false; | |
| 221 read_callback_invoked_ = false; | |
| 222 read_buffer_ = nullptr; | |
| 223 bytes_read_ = 0; | |
| 224 adapter_->Reset(); | |
| 225 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 226 cronet::Java_UploadDataStreamHandler_onResetCompleted( | |
| 227 env, jupload_data_stream_handler_.obj()); | |
| 228 } | |
| 229 | |
| 230 void UploadDataStreamHandler::CheckInitCallbackNotInvokedOnNetworkThread() { | |
| 231 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 232 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 233 cronet::Java_UploadDataStreamHandler_onCheckInitCallbackNotInvoked( | |
| 234 env, jupload_data_stream_handler_.obj(), !init_callback_invoked_); | |
| 235 } | |
| 236 | |
| 237 void UploadDataStreamHandler::CheckReadCallbackNotInvokedOnNetworkThread() { | |
| 238 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 239 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 240 cronet::Java_UploadDataStreamHandler_onCheckReadCallbackNotInvoked( | |
| 241 env, jupload_data_stream_handler_.obj(), !read_callback_invoked_); | |
| 242 } | |
| 243 | |
| 244 void UploadDataStreamHandler::NotifyJavaReadCompleted() { | |
| 245 DCHECK(network_thread_->task_runner()->BelongsToCurrentThread()); | |
| 246 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 247 std::string data_read = ""; | |
| 248 if (read_buffer_.get() && bytes_read_ > 0) | |
| 249 data_read = std::string(read_buffer_->data(), bytes_read_); | |
| 250 cronet::Java_UploadDataStreamHandler_onReadCompleted( | |
| 251 env, jupload_data_stream_handler_.obj(), bytes_read_, | |
| 252 base::android::ConvertUTF8ToJavaString(env, data_read).Release()); | |
| 253 } | |
| 254 | |
| 255 } // namespace | |
| 256 | |
| 257 static void Init(JNIEnv* env, | |
| 258 jclass jcaller, | |
| 259 jlong jupload_data_stream_handler) { | |
| 260 UploadDataStreamHandler* handler = | |
| 261 reinterpret_cast<UploadDataStreamHandler*>(jupload_data_stream_handler); | |
| 262 DCHECK(handler); | |
| 263 handler->Init(); | |
| 264 } | |
| 265 | |
| 266 static void Read(JNIEnv* env, | |
| 267 jclass jcaller, | |
| 268 jlong jupload_data_stream_handler) { | |
| 269 UploadDataStreamHandler* handler = | |
| 270 reinterpret_cast<UploadDataStreamHandler*>(jupload_data_stream_handler); | |
| 271 DCHECK(handler); | |
| 272 handler->Read(); | |
| 273 } | |
| 274 | |
| 275 static void Reset(JNIEnv* env, | |
| 276 jclass jcaller, | |
| 277 jlong jupload_data_stream_handler) { | |
| 278 UploadDataStreamHandler* handler = | |
| 279 reinterpret_cast<UploadDataStreamHandler*>(jupload_data_stream_handler); | |
| 280 DCHECK(handler); | |
| 281 handler->Reset(); | |
| 282 } | |
| 283 | |
| 284 static void CheckInitCallbackNotInvoked(JNIEnv* env, | |
| 285 jclass jcaller, | |
| 286 jlong jupload_data_stream_handler) { | |
| 287 UploadDataStreamHandler* handler = | |
| 288 reinterpret_cast<UploadDataStreamHandler*>(jupload_data_stream_handler); | |
| 289 DCHECK(handler); | |
| 290 handler->CheckInitCallbackNotInvoked(); | |
| 
 
pauljensen
2015/02/12 17:15:40
These functions seem like another good place to us
 
xunjieli
2015/02/12 20:56:28
Done.
 
 | |
| 291 } | |
| 292 | |
| 293 static void CheckReadCallbackNotInvoked(JNIEnv* env, | |
| 294 jclass jcaller, | |
| 295 jlong jupload_data_stream_handler) { | |
| 296 UploadDataStreamHandler* handler = | |
| 297 reinterpret_cast<UploadDataStreamHandler*>(jupload_data_stream_handler); | |
| 298 DCHECK(handler); | |
| 299 handler->CheckReadCallbackNotInvoked(); | |
| 300 } | |
| 301 | |
| 302 static jlong CreateUploadDataStreamHandler(JNIEnv* env, | |
| 303 jobject jupload_data_stream_handler, | |
| 304 jlong jupload_data_stream_adapter) { | |
| 305 CronetUploadDataStreamAdapter* adapter = | |
| 306 reinterpret_cast<CronetUploadDataStreamAdapter*>( | |
| 307 jupload_data_stream_adapter); | |
| 308 UploadDataStreamHandler* handler = | |
| 309 new UploadDataStreamHandler(adapter, env, jupload_data_stream_handler); | |
| 310 return reinterpret_cast<jlong>(handler); | |
| 311 } | |
| 312 | |
| 313 static void Destroy(JNIEnv* env, | |
| 314 jclass jcaller, | |
| 315 jlong jupload_data_stream_handler) { | |
| 316 UploadDataStreamHandler* handler = | |
| 317 reinterpret_cast<UploadDataStreamHandler*>(jupload_data_stream_handler); | |
| 318 DCHECK(handler); | |
| 319 handler->Destroy(); | |
| 320 } | |
| 321 | |
| 322 bool UploadDataStreamHandlerRegisterJni(JNIEnv* env) { | |
| 323 return RegisterNativesImpl(env); | |
| 324 } | |
| 325 | |
| 326 } // namespace cronet | |
| OLD | NEW |