1 // Copyright 2015 The Chromium Authors
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_adapter.h"
6
7 #include <memory>
8 #include <string>
9 #include <utility>
10
11 #include "base/android/jni_android.h"
12 #include "base/android/jni_string.h"
13 #include "base/check_op.h"
14 #include "base/functional/bind.h"
15 #include "base/task/single_thread_task_runner.h"
16 #include "components/cronet/android/cronet_jni_headers/CronetUploadDataStream_jni.h"
17 #include "components/cronet/android/cronet_url_request_adapter.h"
18 #include "components/cronet/android/io_buffer_with_byte_buffer.h"
19
20 using base::android::JavaParamRef;
21
22 namespace cronet {
23
CronetUploadDataStreamAdapter(JNIEnv * env,jobject jupload_data_stream)24 CronetUploadDataStreamAdapter::CronetUploadDataStreamAdapter(
25 JNIEnv* env,
26 jobject jupload_data_stream) {
27 jupload_data_stream_.Reset(env, jupload_data_stream);
28 }
29
~CronetUploadDataStreamAdapter()30 CronetUploadDataStreamAdapter::~CronetUploadDataStreamAdapter() {
31 }
32
InitializeOnNetworkThread(base::WeakPtr<CronetUploadDataStream> upload_data_stream)33 void CronetUploadDataStreamAdapter::InitializeOnNetworkThread(
34 base::WeakPtr<CronetUploadDataStream> upload_data_stream) {
35 DCHECK(!upload_data_stream_);
36 DCHECK(!network_task_runner_.get());
37
38 upload_data_stream_ = upload_data_stream;
39 network_task_runner_ = base::SingleThreadTaskRunner::GetCurrentDefault();
40 DCHECK(network_task_runner_);
41 }
42
Read(scoped_refptr<net::IOBuffer> buffer,int buf_len)43 void CronetUploadDataStreamAdapter::Read(scoped_refptr<net::IOBuffer> buffer,
44 int buf_len) {
45 DCHECK(upload_data_stream_);
46 DCHECK(network_task_runner_);
47 DCHECK(network_task_runner_->BelongsToCurrentThread());
48 DCHECK_GT(buf_len, 0);
49
50 JNIEnv* env = base::android::AttachCurrentThread();
51 // Allow buffer reuse if |buffer| and |buf_len| are exactly the same as the
52 // ones used last time.
53 if (!(buffer_ && buffer_->io_buffer()->data() == buffer->data() &&
54 buffer_->io_buffer_len() == buf_len)) {
55 buffer_ = std::make_unique<ByteBufferWithIOBuffer>(env, std::move(buffer),
56 buf_len);
57 }
58 Java_CronetUploadDataStream_readData(env, jupload_data_stream_,
59 buffer_->byte_buffer());
60 }
61
Rewind()62 void CronetUploadDataStreamAdapter::Rewind() {
63 DCHECK(upload_data_stream_);
64 DCHECK(network_task_runner_->BelongsToCurrentThread());
65
66 JNIEnv* env = base::android::AttachCurrentThread();
67 Java_CronetUploadDataStream_rewind(env, jupload_data_stream_);
68 }
69
OnUploadDataStreamDestroyed()70 void CronetUploadDataStreamAdapter::OnUploadDataStreamDestroyed() {
71 // If CronetUploadDataStream::InitInternal was never called,
72 // |upload_data_stream_| and |network_task_runner_| will be NULL.
73 DCHECK(!network_task_runner_ ||
74 network_task_runner_->BelongsToCurrentThread());
75
76 JNIEnv* env = base::android::AttachCurrentThread();
77 Java_CronetUploadDataStream_onUploadDataStreamDestroyed(env,
78 jupload_data_stream_);
79 // |this| is invalid here since the Java call above effectively destroys it.
80 }
81
OnReadSucceeded(JNIEnv * env,const JavaParamRef<jobject> & jcaller,int bytes_read,bool final_chunk)82 void CronetUploadDataStreamAdapter::OnReadSucceeded(
83 JNIEnv* env,
84 const JavaParamRef<jobject>& jcaller,
85 int bytes_read,
86 bool final_chunk) {
87 DCHECK(bytes_read > 0 || (final_chunk && bytes_read == 0));
88
89 network_task_runner_->PostTask(
90 FROM_HERE, base::BindOnce(&CronetUploadDataStream::OnReadSuccess,
91 upload_data_stream_, bytes_read, final_chunk));
92 }
93
OnRewindSucceeded(JNIEnv * env,const JavaParamRef<jobject> & jcaller)94 void CronetUploadDataStreamAdapter::OnRewindSucceeded(
95 JNIEnv* env,
96 const JavaParamRef<jobject>& jcaller) {
97 network_task_runner_->PostTask(
98 FROM_HERE, base::BindOnce(&CronetUploadDataStream::OnRewindSuccess,
99 upload_data_stream_));
100 }
101
Destroy(JNIEnv * env)102 void CronetUploadDataStreamAdapter::Destroy(JNIEnv* env) {
103 delete this;
104 }
105
JNI_CronetUploadDataStream_AttachUploadDataToRequest(JNIEnv * env,const JavaParamRef<jobject> & jupload_data_stream,jlong jcronet_url_request_adapter,jlong jlength)106 static jlong JNI_CronetUploadDataStream_AttachUploadDataToRequest(
107 JNIEnv* env,
108 const JavaParamRef<jobject>& jupload_data_stream,
109 jlong jcronet_url_request_adapter,
110 jlong jlength) {
111 CronetURLRequestAdapter* request_adapter =
112 reinterpret_cast<CronetURLRequestAdapter*>(jcronet_url_request_adapter);
113 DCHECK(request_adapter != nullptr);
114
115 CronetUploadDataStreamAdapter* adapter =
116 new CronetUploadDataStreamAdapter(env, jupload_data_stream);
117
118 std::unique_ptr<CronetUploadDataStream> upload_data_stream(
119 new CronetUploadDataStream(adapter, jlength));
120
121 request_adapter->SetUpload(std::move(upload_data_stream));
122
123 return reinterpret_cast<jlong>(adapter);
124 }
125
JNI_CronetUploadDataStream_CreateAdapterForTesting(JNIEnv * env,const JavaParamRef<jobject> & jupload_data_stream)126 static jlong JNI_CronetUploadDataStream_CreateAdapterForTesting(
127 JNIEnv* env,
128 const JavaParamRef<jobject>& jupload_data_stream) {
129 CronetUploadDataStreamAdapter* adapter =
130 new CronetUploadDataStreamAdapter(env, jupload_data_stream);
131 return reinterpret_cast<jlong>(adapter);
132 }
133
JNI_CronetUploadDataStream_CreateUploadDataStreamForTesting(JNIEnv * env,const JavaParamRef<jobject> & jupload_data_stream,jlong jlength,jlong jadapter)134 static jlong JNI_CronetUploadDataStream_CreateUploadDataStreamForTesting(
135 JNIEnv* env,
136 const JavaParamRef<jobject>& jupload_data_stream,
137 jlong jlength,
138 jlong jadapter) {
139 CronetUploadDataStreamAdapter* adapter =
140 reinterpret_cast<CronetUploadDataStreamAdapter*>(jadapter);
141 CronetUploadDataStream* upload_data_stream =
142 new CronetUploadDataStream(adapter, jlength);
143 return reinterpret_cast<jlong>(upload_data_stream);
144 }
145
146 } // namespace cronet
147