blob: 79397642d5070bf449d2d14219910f9ed5863069 [file] [log] [blame]
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/httpclient/http_client_bridge.h"
#include "base/android/callback_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "chrome/browser/android/httpclient/http_client.h"
#include "chrome/browser/android/httpclient/jni_headers/SimpleHttpClient_jni.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "url/android/gurl_android.h"
#include "url/gurl.h"
using base::android::ConvertJavaStringToUTF8;
using base::android::JavaParamRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
namespace httpclient {
// static
jlong JNI_SimpleHttpClient_Init(JNIEnv* env,
const JavaParamRef<jobject>& j_profile) {
return reinterpret_cast<intptr_t>(new HttpClientBridge(j_profile));
}
HttpClientBridge::HttpClientBridge(const JavaParamRef<jobject>& j_profile) {
Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
DCHECK(profile);
http_client_ = std::make_unique<HttpClient>(profile->GetURLLoaderFactory());
}
HttpClientBridge::~HttpClientBridge() = default;
void HttpClientBridge::Destroy(JNIEnv* env) {
delete this;
}
void HttpClientBridge::SendNetworkRequest(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_gurl,
const base::android::JavaParamRef<jstring>& j_request_type,
const base::android::JavaParamRef<jbyteArray>& j_body,
const base::android::JavaParamRef<jobjectArray>& j_header_keys,
const base::android::JavaParamRef<jobjectArray>& j_header_values,
jint j_network_annotation_hashcode,
const base::android::JavaParamRef<jobject>& j_callback) {
DCHECK(j_gurl);
std::unique_ptr<GURL> gurl = url::GURLAndroid::ToNativeGURL(env, j_gurl);
DCHECK(gurl->is_valid());
std::vector<uint8_t> request_body;
base::android::JavaByteArrayToByteVector(env, j_body, &request_body);
std::vector<std::string> header_keys;
base::android::AppendJavaStringArrayToStringVector(env, j_header_keys,
&header_keys);
std::vector<std::string> header_values;
base::android::AppendJavaStringArrayToStringVector(env, j_header_values,
&header_values);
net::NetworkTrafficAnnotationTag tag =
net::NetworkTrafficAnnotationTag::FromJavaAnnotation(
j_network_annotation_hashcode);
// base::Unretained is safe because we are an immortal singleton.
HttpClient::ResponseCallback callback =
base::BindOnce(&HttpClientBridge::OnResult, base::Unretained(this),
ScopedJavaGlobalRef<jobject>(env, j_callback));
// base::Unretained is safe because we are an immortal singleton.
// Post on the UI thread because HttpClient needs to be called on the UI
// thread.
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(&HttpClient::Send, base::Unretained(http_client_.get()),
*gurl, ConvertJavaStringToUTF8(env, j_request_type),
std::move(request_body), std::move(header_keys),
std::move(header_values), tag, std::move(callback)));
}
void HttpClientBridge::OnResult(
const ScopedJavaGlobalRef<jobject>& j_callback,
int32_t http_code,
int32_t net_error_code,
std::vector<uint8_t>&& response_bytes,
std::vector<std::string>&& response_header_keys,
std::vector<std::string>&& response_header_values) {
JNIEnv* env = base::android::AttachCurrentThread();
ScopedJavaLocalRef<jbyteArray> j_response_bytes =
base::android::ToJavaByteArray(env, response_bytes);
ScopedJavaLocalRef<jobjectArray> j_response_header_keys =
base::android::ToJavaArrayOfStrings(env, response_header_keys);
ScopedJavaLocalRef<jobjectArray> j_response_header_values =
base::android::ToJavaArrayOfStrings(env, response_header_values);
ScopedJavaLocalRef<jobject> j_http_response =
Java_SimpleHttpClient_createHttpResponse(
env, http_code, net_error_code, j_response_bytes,
j_response_header_keys, j_response_header_values);
base::android::RunObjectCallbackAndroid(j_callback, j_http_response);
}
} // namespace httpclient