1*6777b538SAndroid Build Coastguard Worker // Copyright 2019 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "url/android/gurl_android.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <cstdint>
8*6777b538SAndroid Build Coastguard Worker #include <string>
9*6777b538SAndroid Build Coastguard Worker #include <vector>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include "base/android/jni_android.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/android/jni_string.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "url/android/parsed_android.h"
18*6777b538SAndroid Build Coastguard Worker #include "url/third_party/mozilla/url_parse.h"
19*6777b538SAndroid Build Coastguard Worker #include "url/url_jni_headers/GURL_jni.h"
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker using jni_zero::AttachCurrentThread;
22*6777b538SAndroid Build Coastguard Worker using jni_zero::JavaParamRef;
23*6777b538SAndroid Build Coastguard Worker using jni_zero::JavaRef;
24*6777b538SAndroid Build Coastguard Worker using jni_zero::ScopedJavaLocalRef;
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker namespace jni_zero {
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker // Convert from java GURL.java pointer to native GURL object.
29*6777b538SAndroid Build Coastguard Worker template <>
COMPONENT_EXPORT(URL)30*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(URL)
31*6777b538SAndroid Build Coastguard Worker GURL FromJniType<GURL>(JNIEnv* env, const JavaRef<jobject>& j_gurl) {
32*6777b538SAndroid Build Coastguard Worker return url::GURLAndroid::ToNativeGURL(env, j_gurl);
33*6777b538SAndroid Build Coastguard Worker }
34*6777b538SAndroid Build Coastguard Worker
35*6777b538SAndroid Build Coastguard Worker // Convert from native GURL object to a GURL.java object pointer.
36*6777b538SAndroid Build Coastguard Worker template <>
COMPONENT_EXPORT(URL)37*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(URL)
38*6777b538SAndroid Build Coastguard Worker ScopedJavaLocalRef<jobject> ToJniType<GURL>(JNIEnv* env, const GURL& gurl) {
39*6777b538SAndroid Build Coastguard Worker return url::GURLAndroid::FromNativeGURL(env, gurl);
40*6777b538SAndroid Build Coastguard Worker }
41*6777b538SAndroid Build Coastguard Worker } // namespace jni_zero
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker namespace url {
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker namespace {
46*6777b538SAndroid Build Coastguard Worker
InitFromGURL(JNIEnv * env,const GURL & gurl,const JavaRef<jobject> & target)47*6777b538SAndroid Build Coastguard Worker static void InitFromGURL(JNIEnv* env,
48*6777b538SAndroid Build Coastguard Worker const GURL& gurl,
49*6777b538SAndroid Build Coastguard Worker const JavaRef<jobject>& target) {
50*6777b538SAndroid Build Coastguard Worker // Ensure that the spec only contains US-ASCII (single-byte characters) or the
51*6777b538SAndroid Build Coastguard Worker // parsed indices will be wrong as the indices are in bytes while Java Strings
52*6777b538SAndroid Build Coastguard Worker // are always 16-bit.
53*6777b538SAndroid Build Coastguard Worker DCHECK(base::IsStringASCII(gurl.possibly_invalid_spec()));
54*6777b538SAndroid Build Coastguard Worker Java_GURL_init(env, target, gurl.possibly_invalid_spec(), gurl.is_valid(),
55*6777b538SAndroid Build Coastguard Worker ParsedAndroid::InitFromParsed(
56*6777b538SAndroid Build Coastguard Worker env, gurl.parsed_for_possibly_invalid_spec()));
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker // As |GetArrayLength| makes no guarantees about the returned value (e.g., it
60*6777b538SAndroid Build Coastguard Worker // may be -1 if |array| is not a valid Java array), provide a safe wrapper
61*6777b538SAndroid Build Coastguard Worker // that always returns a valid, non-negative size.
62*6777b538SAndroid Build Coastguard Worker template <typename JavaArrayType>
SafeGetArrayLength(JNIEnv * env,const JavaRef<JavaArrayType> & jarray)63*6777b538SAndroid Build Coastguard Worker size_t SafeGetArrayLength(JNIEnv* env, const JavaRef<JavaArrayType>& jarray) {
64*6777b538SAndroid Build Coastguard Worker DCHECK(jarray);
65*6777b538SAndroid Build Coastguard Worker jsize length = env->GetArrayLength(jarray.obj());
66*6777b538SAndroid Build Coastguard Worker DCHECK_GE(length, 0) << "Invalid array length: " << length;
67*6777b538SAndroid Build Coastguard Worker return static_cast<size_t>(std::max(0, length));
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker
70*6777b538SAndroid Build Coastguard Worker } // namespace
71*6777b538SAndroid Build Coastguard Worker
72*6777b538SAndroid Build Coastguard Worker // static
ToNativeGURL(JNIEnv * env,const base::android::JavaRef<jobject> & j_gurl)73*6777b538SAndroid Build Coastguard Worker GURL GURLAndroid::ToNativeGURL(JNIEnv* env,
74*6777b538SAndroid Build Coastguard Worker const base::android::JavaRef<jobject>& j_gurl) {
75*6777b538SAndroid Build Coastguard Worker GURL ret;
76*6777b538SAndroid Build Coastguard Worker Parsed parsed;
77*6777b538SAndroid Build Coastguard Worker Java_GURL_toNativeGURL(env, j_gurl, reinterpret_cast<jlong>(&ret),
78*6777b538SAndroid Build Coastguard Worker reinterpret_cast<jlong>(&parsed));
79*6777b538SAndroid Build Coastguard Worker return ret;
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker // static
FromNativeGURL(JNIEnv * env,const GURL & gurl)83*6777b538SAndroid Build Coastguard Worker ScopedJavaLocalRef<jobject> GURLAndroid::FromNativeGURL(JNIEnv* env,
84*6777b538SAndroid Build Coastguard Worker const GURL& gurl) {
85*6777b538SAndroid Build Coastguard Worker ScopedJavaLocalRef<jobject> j_gurl = Java_GURL_Constructor(env);
86*6777b538SAndroid Build Coastguard Worker InitFromGURL(env, gurl, j_gurl);
87*6777b538SAndroid Build Coastguard Worker return j_gurl;
88*6777b538SAndroid Build Coastguard Worker }
89*6777b538SAndroid Build Coastguard Worker
90*6777b538SAndroid Build Coastguard Worker // static
EmptyGURL(JNIEnv * env)91*6777b538SAndroid Build Coastguard Worker ScopedJavaLocalRef<jobject> GURLAndroid::EmptyGURL(JNIEnv* env) {
92*6777b538SAndroid Build Coastguard Worker return Java_GURL_emptyGURL(env);
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker
JNI_GURL_GetOrigin(JNIEnv * env,GURL & gurl,const JavaParamRef<jobject> & target)95*6777b538SAndroid Build Coastguard Worker static void JNI_GURL_GetOrigin(JNIEnv* env,
96*6777b538SAndroid Build Coastguard Worker GURL& gurl,
97*6777b538SAndroid Build Coastguard Worker const JavaParamRef<jobject>& target) {
98*6777b538SAndroid Build Coastguard Worker InitFromGURL(env, gurl.DeprecatedGetOriginAsURL(), target);
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker
JNI_GURL_DomainIs(JNIEnv * env,GURL & gurl,std::string & domain)101*6777b538SAndroid Build Coastguard Worker static jboolean JNI_GURL_DomainIs(JNIEnv* env,
102*6777b538SAndroid Build Coastguard Worker GURL& gurl,
103*6777b538SAndroid Build Coastguard Worker std::string& domain) {
104*6777b538SAndroid Build Coastguard Worker return gurl.DomainIs(domain);
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker
JNI_GURL_Init(JNIEnv * env,std::string & spec,const base::android::JavaParamRef<jobject> & target)107*6777b538SAndroid Build Coastguard Worker static void JNI_GURL_Init(JNIEnv* env,
108*6777b538SAndroid Build Coastguard Worker std::string& spec,
109*6777b538SAndroid Build Coastguard Worker const base::android::JavaParamRef<jobject>& target) {
110*6777b538SAndroid Build Coastguard Worker auto gurl = GURL(spec);
111*6777b538SAndroid Build Coastguard Worker InitFromGURL(env, gurl, target);
112*6777b538SAndroid Build Coastguard Worker }
113*6777b538SAndroid Build Coastguard Worker
JNI_GURL_InitNative(JNIEnv * env,std::string & spec,jboolean is_valid,jlong native_gurl,jlong native_parsed)114*6777b538SAndroid Build Coastguard Worker static void JNI_GURL_InitNative(JNIEnv* env,
115*6777b538SAndroid Build Coastguard Worker std::string& spec,
116*6777b538SAndroid Build Coastguard Worker jboolean is_valid,
117*6777b538SAndroid Build Coastguard Worker jlong native_gurl,
118*6777b538SAndroid Build Coastguard Worker jlong native_parsed) {
119*6777b538SAndroid Build Coastguard Worker GURL* gurl = reinterpret_cast<GURL*>(native_gurl);
120*6777b538SAndroid Build Coastguard Worker Parsed* parsed = reinterpret_cast<Parsed*>(native_parsed);
121*6777b538SAndroid Build Coastguard Worker *gurl = GURL(spec, *parsed, is_valid);
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker
JNI_GURL_ReplaceComponents(JNIEnv * env,GURL & gurl,const JavaParamRef<jstring> & j_username_replacement,jboolean clear_username,const JavaParamRef<jstring> & j_password_replacement,jboolean clear_password,const JavaParamRef<jobject> & j_result)124*6777b538SAndroid Build Coastguard Worker static void JNI_GURL_ReplaceComponents(
125*6777b538SAndroid Build Coastguard Worker JNIEnv* env,
126*6777b538SAndroid Build Coastguard Worker GURL& gurl,
127*6777b538SAndroid Build Coastguard Worker const JavaParamRef<jstring>& j_username_replacement,
128*6777b538SAndroid Build Coastguard Worker jboolean clear_username,
129*6777b538SAndroid Build Coastguard Worker const JavaParamRef<jstring>& j_password_replacement,
130*6777b538SAndroid Build Coastguard Worker jboolean clear_password,
131*6777b538SAndroid Build Coastguard Worker const JavaParamRef<jobject>& j_result) {
132*6777b538SAndroid Build Coastguard Worker GURL::Replacements replacements;
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker // Replacement strings must remain in scope for ReplaceComponents().
135*6777b538SAndroid Build Coastguard Worker std::string username;
136*6777b538SAndroid Build Coastguard Worker std::string password;
137*6777b538SAndroid Build Coastguard Worker
138*6777b538SAndroid Build Coastguard Worker if (clear_username) {
139*6777b538SAndroid Build Coastguard Worker replacements.ClearUsername();
140*6777b538SAndroid Build Coastguard Worker } else if (j_username_replacement) {
141*6777b538SAndroid Build Coastguard Worker username =
142*6777b538SAndroid Build Coastguard Worker base::android::ConvertJavaStringToUTF8(env, j_username_replacement);
143*6777b538SAndroid Build Coastguard Worker replacements.SetUsernameStr(username);
144*6777b538SAndroid Build Coastguard Worker }
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Worker if (clear_password) {
147*6777b538SAndroid Build Coastguard Worker replacements.ClearPassword();
148*6777b538SAndroid Build Coastguard Worker } else if (j_password_replacement) {
149*6777b538SAndroid Build Coastguard Worker password =
150*6777b538SAndroid Build Coastguard Worker base::android::ConvertJavaStringToUTF8(env, j_password_replacement);
151*6777b538SAndroid Build Coastguard Worker replacements.SetPasswordStr(password);
152*6777b538SAndroid Build Coastguard Worker }
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Worker InitFromGURL(env, gurl.ReplaceComponents(replacements), j_result);
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard Worker } // namespace url
158