1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/cronet/android/test/cronet_test_util.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/message_loop/message_pump.h"
#include "base/message_loop/message_pump_type.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "components/cronet/android/cronet_context_adapter.h"
#include "components/cronet/android/cronet_url_request_adapter.h"
#include "components/cronet/cronet_context.h"
#include "components/cronet/cronet_url_request.h"
#include "net/http/http_server_properties.h"
#include "net/quic/quic_context.h"
#include "net/socket/socket_test_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
// Must come after all headers that specialize FromJniType() / ToJniType().
#include "components/cronet/android/cronet_test_apk_jni/CronetTestUtil_jni.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_tag.h"
namespace cronet {
namespace {
using ::base::MessagePump;
using ::base::MessagePumpType;
using ::base::android::JavaParamRef;
using ::base::sequence_manager::SequenceManager;
SequenceManager* g_sequence_manager = nullptr;
} // namespace
jint JNI_CronetTestUtil_GetLoadFlags(JNIEnv* env,
const jlong jurl_request_adapter) {
return TestUtil::GetURLRequest(jurl_request_adapter)->load_flags();
}
jboolean JNI_CronetTestUtil_URLRequestContextExistsForTesting(
JNIEnv* env,
jlong jcontext_adapter,
jlong jnetwork_handle) {
return TestUtil::GetURLRequestContexts(jcontext_adapter)
->contains(jnetwork_handle);
}
jni_zero::ScopedJavaLocalRef<jobjectArray>
JNI_CronetTestUtil_GetClientConnectionOptions(JNIEnv* env,
jlong jcontext_adapter) {
std::vector<std::string> quic_tags;
for (auto tag : TestUtil::GetDefaultURLRequestQuicParams(jcontext_adapter)
.client_connection_options) {
quic_tags.push_back(quic::QuicTagToString(tag));
}
return base::android::ToJavaArrayOfStrings(env, std::move(quic_tags));
}
jni_zero::ScopedJavaLocalRef<jobjectArray>
JNI_CronetTestUtil_GetConnectionOptions(JNIEnv* env, jlong jcontext_adapter) {
std::vector<std::string> quic_tags;
for (auto tag : TestUtil::GetDefaultURLRequestQuicParams(jcontext_adapter)
.connection_options) {
quic_tags.push_back(quic::QuicTagToString(tag));
}
return base::android::ToJavaArrayOfStrings(env, std::move(quic_tags));
}
// static
base::flat_map<net::handles::NetworkHandle,
std::unique_ptr<net::URLRequestContext>>*
TestUtil::GetURLRequestContexts(jlong jcontext_adapter) {
CronetContextAdapter* context_adapter =
reinterpret_cast<CronetContextAdapter*>(jcontext_adapter);
return &context_adapter->context_->network_tasks_->contexts_;
}
// static
scoped_refptr<base::SingleThreadTaskRunner> TestUtil::GetTaskRunner(
jlong jcontext_adapter) {
CronetContextAdapter* context_adapter =
reinterpret_cast<CronetContextAdapter*>(jcontext_adapter);
return context_adapter->context_->network_task_runner_;
}
// static
net::URLRequestContext* TestUtil::GetURLRequestContext(jlong jcontext_adapter) {
CronetContextAdapter* context_adapter =
reinterpret_cast<CronetContextAdapter*>(jcontext_adapter);
return context_adapter->context_->network_tasks_->default_context_;
}
net::QuicParams& TestUtil::GetDefaultURLRequestQuicParams(
jlong jcontext_adapter) {
net::URLRequestContext* context;
base::WaitableEvent callback_executed;
CronetContextAdapter& context_adapter =
*reinterpret_cast<CronetContextAdapter*>(jcontext_adapter);
RunAfterContextInit(jcontext_adapter, base::BindLambdaForTesting([&] {
context =
context_adapter.context_->GetURLRequestContext(
net::handles::kInvalidNetworkHandle);
callback_executed.Signal();
}));
callback_executed.Wait();
CHECK(context);
return *context->quic_context()->params();
}
// static
void TestUtil::RunAfterContextInitOnNetworkThread(jlong jcontext_adapter,
base::OnceClosure task) {
CronetContextAdapter* context_adapter =
reinterpret_cast<CronetContextAdapter*>(jcontext_adapter);
if (context_adapter->context_->network_tasks_
->is_default_context_initialized_) {
std::move(task).Run();
} else {
context_adapter->context_->network_tasks_->tasks_waiting_for_context_.push(
std::move(task));
}
}
// static
void TestUtil::RunAfterContextInit(jlong jcontext_adapter,
base::OnceClosure task) {
GetTaskRunner(jcontext_adapter)
->PostTask(FROM_HERE,
base::BindOnce(&TestUtil::RunAfterContextInitOnNetworkThread,
jcontext_adapter, std::move(task)));
}
// static
net::URLRequest* TestUtil::GetURLRequest(jlong jrequest_adapter) {
CronetURLRequestAdapter* request_adapter =
reinterpret_cast<CronetURLRequestAdapter*>(jrequest_adapter);
return request_adapter->request_->network_tasks_.url_request_.get();
}
static void PrepareNetworkThreadOnNetworkThread(jlong jcontext_adapter) {
g_sequence_manager =
base::sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
MessagePump::Create(MessagePumpType::IO),
SequenceManager::Settings::Builder()
.SetMessagePumpType(MessagePumpType::IO)
.Build())
.release();
g_sequence_manager->SetDefaultTaskRunner(
TestUtil::GetTaskRunner(jcontext_adapter));
}
// Tests need to call into libcronet.so code on libcronet.so threads.
// libcronet.so's threads are registered with static tables for MessageLoops
// and SingleThreadTaskRunners in libcronet.so, so libcronet_test.so
// functions that try and access these tables will find missing entries in
// the corresponding static tables in libcronet_test.so. Fix this by
// initializing a MessageLoop and SingleThreadTaskRunner in libcronet_test.so
// for these threads. Called from Java CronetTestUtil class.
void JNI_CronetTestUtil_PrepareNetworkThread(JNIEnv* env,
jlong jcontext_adapter) {
TestUtil::GetTaskRunner(jcontext_adapter)
->PostTask(FROM_HERE, base::BindOnce(&PrepareNetworkThreadOnNetworkThread,
jcontext_adapter));
}
static void CleanupNetworkThreadOnNetworkThread() {
DCHECK(g_sequence_manager);
delete g_sequence_manager;
g_sequence_manager = nullptr;
}
// Called from Java CronetTestUtil class.
void JNI_CronetTestUtil_CleanupNetworkThread(JNIEnv* env,
jlong jcontext_adapter) {
TestUtil::RunAfterContextInit(
jcontext_adapter, base::BindOnce(&CleanupNetworkThreadOnNetworkThread));
}
jboolean JNI_CronetTestUtil_CanGetTaggedBytes(JNIEnv* env) {
return net::CanGetTaggedBytes();
}
jlong JNI_CronetTestUtil_GetTaggedBytes(JNIEnv* env, jint jexpected_tag) {
return net::GetTaggedBytes(jexpected_tag);
}
} // namespace cronet
|