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

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

Issue 849903002: [Cronet] Upload support for async APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed unnecessary argument Created 5 years, 10 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
(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 "components/cronet/android/cronet_upload_data_stream.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/callback_helpers.h"
14 #include "base/location.h"
15 #include "base/logging.h"
16 #include "base/macros.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/message_loop/message_loop_proxy.h"
20 #include "components/cronet/android/cronet_upload_data_stream_adapter.h"
21 #include "components/cronet/android/cronet_url_request_adapter.h"
22 #include "jni/CronetUploadDataStream_jni.h"
23 #include "net/base/io_buffer.h"
24 #include "net/base/upload_data_stream.h"
25
26 using base::android::ConvertUTF8ToJavaString;
27
28 namespace cronet {
29
30 namespace {
31
32 // The Delegate holds onto a reference to the IOBuffer that is currently being
33 // written to in Java, so may not be deleted until any read operation in Java
34 // has completed.
35 //
36 // The Delegate is owned by the Java CronetUploadDataStream, and also owns a
37 // reference to it. The Delegate is only destroyed after the URLRequest
38 // destroys the adapter and the CronetUploadDataStream has no operation pending,
39 // at which point it also releases its reference to the CronetUploadDataStream.
40 //
41 // Failures don't go through the delegate, but directly to the Java request
42 // object, since normally reads aren't allowed to fail during an upload.
43 class CronetUploadDataStreamDelegate
44 : public CronetUploadDataStreamAdapter::Delegate {
45 public:
46 CronetUploadDataStreamDelegate(JNIEnv* env, jobject jupload_data_stream);
47 ~CronetUploadDataStreamDelegate() override {}
48
49 // CronetUploadDataStreamAdapter::Delegate implementation. Called on network
50 // thread.
51 void InitializeOnNetworkThread(
52 base::WeakPtr<CronetUploadDataStreamAdapter> adapter) override;
53 void Read(net::IOBuffer* buffer, int buf_len) override;
54 void Rewind() override;
55 void OnAdapterDestroyed() override;
56
57 // Callbacks from Java, called on some Java thread.
58 void OnReadSucceeded(int bytes_read, bool final_chunk);
59 void OnRewindSucceeded();
60
61 private:
62 // Initialized on construction, effectively constant.
63 base::android::ScopedJavaGlobalRef<jobject> jupload_data_stream_;
64
65 // These are initialized in InitializeOnNetworkThread, so are safe to access
66 // during Java callbacks, which all happen after initialization.
67 scoped_refptr<base::MessageLoopProxy> network_message_loop_;
mef 2015/02/06 19:46:09 can this be base::SingleThreadTaskRunner?
xunjieli 2015/02/06 20:48:29 Done. Looked at other cronet code, I think we shou
68 base::WeakPtr<CronetUploadDataStreamAdapter> adapter_;
69
70 // Used to keep the read buffer alive until the callback from Java has been
71 // received.
72 scoped_refptr<net::IOBuffer> buffer_;
73
74 DISALLOW_COPY_AND_ASSIGN(CronetUploadDataStreamDelegate);
75 };
76
77 CronetUploadDataStreamDelegate::CronetUploadDataStreamDelegate(
78 JNIEnv* env,
79 jobject jupload_data_stream) {
80 jupload_data_stream_.Reset(env, jupload_data_stream);
81 }
82
83 void CronetUploadDataStreamDelegate::InitializeOnNetworkThread(
84 base::WeakPtr<CronetUploadDataStreamAdapter> adapter) {
85 DCHECK(!adapter_);
86 DCHECK(!network_message_loop_.get());
87
88 adapter_ = adapter;
89 network_message_loop_ = base::MessageLoopProxy::current();
90 DCHECK(network_message_loop_);
91 }
92
93 void CronetUploadDataStreamDelegate::Read(net::IOBuffer* buffer, int buf_len) {
94 DCHECK(adapter_);
95 DCHECK(network_message_loop_);
96 DCHECK(network_message_loop_->BelongsToCurrentThread());
97 DCHECK_GT(buf_len, 0);
98 DCHECK(!buffer_.get());
99 buffer_ = buffer;
100
101 // TODO(mmenke): Consider preserving the java buffer across reads, when the
102 // IOBuffer's data pointer and its length are unchanged.
103 JNIEnv* env = base::android::AttachCurrentThread();
104 base::android::ScopedJavaLocalRef<jobject> java_buffer(
105 env, env->NewDirectByteBuffer(buffer->data(), buf_len));
106 Java_CronetUploadDataStream_readData(env, jupload_data_stream_.obj(),
107 java_buffer.obj());
108 }
109
110 void CronetUploadDataStreamDelegate::Rewind() {
111 DCHECK(adapter_);
112 DCHECK(network_message_loop_->BelongsToCurrentThread());
113
114 JNIEnv* env = base::android::AttachCurrentThread();
115 Java_CronetUploadDataStream_rewind(env, jupload_data_stream_.obj());
116 }
117
118 void CronetUploadDataStreamDelegate::OnAdapterDestroyed() {
119 DCHECK(adapter_);
120 DCHECK(network_message_loop_->BelongsToCurrentThread());
121
122 JNIEnv* env = base::android::AttachCurrentThread();
123 Java_CronetUploadDataStream_onAdapterDestroyed(env,
124 jupload_data_stream_.obj());
125 }
126
127 void CronetUploadDataStreamDelegate::OnReadSucceeded(int bytes_read,
128 bool final_chunk) {
129 DCHECK(!network_message_loop_->BelongsToCurrentThread());
130 DCHECK(bytes_read > 0 || (final_chunk && bytes_read == 0));
131
132 buffer_ = nullptr;
133 DCHECK(network_message_loop_->PostTask(
134 FROM_HERE, base::Bind(&CronetUploadDataStreamAdapter::OnReadSuccess,
135 adapter_, bytes_read, final_chunk)));
136 }
137
138 void CronetUploadDataStreamDelegate::OnRewindSucceeded() {
139 DCHECK(!network_message_loop_->BelongsToCurrentThread());
140
141 network_message_loop_->PostTask(
142 FROM_HERE,
143 base::Bind(&CronetUploadDataStreamAdapter::OnRewindSuccess, adapter_));
144 }
145
146 } // namespace
147
148 // Explicitly register static JNI functions.
149 bool CronetUploadDataStreamRegisterJni(JNIEnv* env) {
150 return RegisterNativesImpl(env);
151 }
152
153 static jlong AttachUploadDataToRequest(JNIEnv* env,
154 jobject jupload_data_stream,
155 jlong jcronet_url_request_adapter,
156 jlong jlength) {
157 CronetURLRequestAdapter* request_adapter =
158 reinterpret_cast<CronetURLRequestAdapter*>(jcronet_url_request_adapter);
159 DCHECK(request_adapter != nullptr);
160
161 CronetUploadDataStreamDelegate* delegate =
162 new CronetUploadDataStreamDelegate(env, jupload_data_stream);
163
164 scoped_ptr<CronetUploadDataStreamAdapter> upload_adapter(
165 new CronetUploadDataStreamAdapter(delegate, jlength));
166
167 request_adapter->SetUpload(upload_adapter.Pass());
168
169 return reinterpret_cast<jlong>(delegate);
170 }
171
172 static jlong CreateDelegateForTesting(JNIEnv* env,
173 jobject jupload_data_stream) {
174 CronetUploadDataStreamDelegate* delegate =
175 new CronetUploadDataStreamDelegate(env, jupload_data_stream);
176 return reinterpret_cast<jlong>(delegate);
177 }
178
179 static jlong CreateAdapterForTesting(JNIEnv* env,
180 jobject jupload_data_stream,
181 jlong jlength,
182 jlong jdelegate) {
183 CronetUploadDataStreamDelegate* delegate =
184 reinterpret_cast<CronetUploadDataStreamDelegate*>(jdelegate);
185 CronetUploadDataStreamAdapter* upload_adapter =
186 new CronetUploadDataStreamAdapter(delegate, jlength);
187 return reinterpret_cast<jlong>(upload_adapter);
188 }
189
190 static void OnReadSucceeded(JNIEnv* env,
191 jobject jcaller,
192 jlong jupload_data_stream_delegate,
193 jint bytes_read,
194 jboolean final_chunk) {
195 CronetUploadDataStreamDelegate* delegate =
196 reinterpret_cast<CronetUploadDataStreamDelegate*>(
197 jupload_data_stream_delegate);
198 DCHECK(delegate != nullptr);
199
200 delegate->OnReadSucceeded(bytes_read, final_chunk);
201 }
202
203 static void OnRewindSucceeded(JNIEnv* env,
204 jobject jcaller,
205 jlong jupload_data_stream_delegate) {
206 CronetUploadDataStreamDelegate* delegate =
207 reinterpret_cast<CronetUploadDataStreamDelegate*>(
208 jupload_data_stream_delegate);
209 DCHECK(delegate != nullptr);
210
211 delegate->OnRewindSucceeded();
212 }
213
214 static void DestroyDelegate(JNIEnv* env,
215 jclass jcronet_url_request_adapter,
216 jlong jupload_data_stream_delegate) {
217 CronetUploadDataStreamDelegate* delegate =
218 reinterpret_cast<CronetUploadDataStreamDelegate*>(
219 jupload_data_stream_delegate);
220 DCHECK(delegate != nullptr);
221 delete delegate;
222 }
223
224 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698