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

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: Addressed Misha and Paul's comments 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.
mmenke 2015/02/02 18:35:13 I thought I'd hooked this up, but doesn't look lik
xunjieli 2015/02/02 19:12:25 Done.
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 position, int limit, 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_;
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 position,
128 int limit,
129 bool final_chunk) {
130 DCHECK(!network_message_loop_->BelongsToCurrentThread());
131 DCHECK_LE(position, limit);
132 DCHECK(position < limit || final_chunk);
133
134 int bytes_read = limit - position;
135
136 // Move data to the start of the buffer, if needed.
137 // TODO(mmenke): Is this really needed?
138 if (position != 0)
139 memmove(buffer_->data(), buffer_->data() + position, bytes_read);
140
141 buffer_ = nullptr;
142 DCHECK(network_message_loop_->PostTask(
143 FROM_HERE, base::Bind(&CronetUploadDataStreamAdapter::OnReadSuccess,
144 adapter_, bytes_read, final_chunk)));
145 }
146
147 void CronetUploadDataStreamDelegate::OnRewindSucceeded() {
148 DCHECK(!network_message_loop_->BelongsToCurrentThread());
149
150 network_message_loop_->PostTask(
151 FROM_HERE,
152 base::Bind(&CronetUploadDataStreamAdapter::OnRewindSuccess, adapter_));
153 }
154
155 } // namespace
156
157 // Explicitly register static JNI functions.
158 bool CronetUploadDataStreamRegisterJni(JNIEnv* env) {
159 return RegisterNativesImpl(env);
160 }
161
162 static jlong AttachUploadDataToRequest(JNIEnv* env,
163 jobject jupload_data_stream,
164 jlong jcronet_url_request_adapter,
165 jlong jlength) {
166 CronetURLRequestAdapter* request_adapter =
167 reinterpret_cast<CronetURLRequestAdapter*>(jcronet_url_request_adapter);
168 DCHECK(request_adapter != nullptr);
169
170 CronetUploadDataStreamDelegate* delegate =
171 new CronetUploadDataStreamDelegate(env, jupload_data_stream);
172
173 scoped_ptr<CronetUploadDataStreamAdapter> upload_adapter(
174 new CronetUploadDataStreamAdapter(delegate, jlength));
175
176 request_adapter->SetUpload(upload_adapter.Pass());
177
178 return reinterpret_cast<jlong>(delegate);
179 }
180
181 static jlong CreateDelegateForTesting(JNIEnv* env,
182 jobject jupload_data_stream) {
183 CronetUploadDataStreamDelegate* delegate =
184 new CronetUploadDataStreamDelegate(env, jupload_data_stream);
185 return reinterpret_cast<jlong>(delegate);
186 }
187
188 static jlong CreateAdapterForTesting(JNIEnv* env,
189 jobject jupload_data_stream,
190 jlong jlength,
191 jlong jdelegate) {
192 CronetUploadDataStreamDelegate* delegate =
193 reinterpret_cast<CronetUploadDataStreamDelegate*>(jdelegate);
194 CronetUploadDataStreamAdapter* upload_adapter =
195 new CronetUploadDataStreamAdapter(delegate, jlength);
196 return reinterpret_cast<jlong>(upload_adapter);
197 }
198
199 static void OnReadSucceeded(JNIEnv* env,
200 jobject jcaller,
201 jlong jupload_data_stream_delegate,
202 jint position,
203 jint limit,
204 jboolean final_chunk) {
205 CronetUploadDataStreamDelegate* delegate =
206 reinterpret_cast<CronetUploadDataStreamDelegate*>(
207 jupload_data_stream_delegate);
208 DCHECK(delegate != nullptr);
209
210 delegate->OnReadSucceeded(position, limit, final_chunk);
211 }
212
213 static void OnRewindSucceeded(JNIEnv* env,
214 jobject jcaller,
215 jlong jupload_data_stream_delegate) {
216 CronetUploadDataStreamDelegate* delegate =
217 reinterpret_cast<CronetUploadDataStreamDelegate*>(
218 jupload_data_stream_delegate);
219 DCHECK(delegate != nullptr);
220
221 delegate->OnRewindSucceeded();
222 }
223
224 static void DestroyDelegate(JNIEnv* env,
225 jclass jcronet_url_request_adapter,
226 jlong jupload_data_stream_delegate) {
227 CronetUploadDataStreamDelegate* delegate =
228 reinterpret_cast<CronetUploadDataStreamDelegate*>(
229 jupload_data_stream_delegate);
230 DCHECK(delegate != nullptr);
231 delete delegate;
232 }
233
234 } // namespace cronet
OLDNEW
« no previous file with comments | « components/cronet/android/cronet_upload_data_stream.h ('k') | components/cronet/android/cronet_upload_data_stream_adapter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698