1 // Copyright (c) 2013 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.
5 #include "chrome/browser/search_engines/template_url_service_android.h"
7 #include "base/android/jni_string.h"
9 #include "base/format_macros.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/search_engines/template_url_service_factory.h"
14 #include "components/google/core/browser/google_util.h"
15 #include "components/search_engines/search_terms_data.h"
16 #include "components/search_engines/template_url.h"
17 #include "components/search_engines/template_url_prepopulate_data.h"
18 #include "components/search_engines/template_url_service.h"
19 #include "components/search_engines/util.h"
20 #include "jni/TemplateUrlService_jni.h"
21 #include "net/base/url_util.h"
25 Profile
* GetOriginalProfile() {
26 return ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
31 TemplateUrlServiceAndroid::TemplateUrlServiceAndroid(JNIEnv
* env
,
33 : weak_java_obj_(env
, obj
),
34 template_url_service_(
35 TemplateURLServiceFactory::GetForProfile(GetOriginalProfile())) {
36 template_url_subscription_
=
37 template_url_service_
->RegisterOnLoadedCallback(
38 base::Bind(&TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded
,
39 base::Unretained(this)));
40 template_url_service_
->AddObserver(this);
43 TemplateUrlServiceAndroid::~TemplateUrlServiceAndroid() {
44 template_url_service_
->RemoveObserver(this);
47 void TemplateUrlServiceAndroid::Load(JNIEnv
* env
, jobject obj
) {
48 template_url_service_
->Load();
51 void TemplateUrlServiceAndroid::SetUserSelectedDefaultSearchProvider(
54 jint selected_index
) {
55 std::vector
<TemplateURL
*> template_urls
=
56 template_url_service_
->GetTemplateURLs();
57 size_t selected_index_size_t
= static_cast<size_t>(selected_index
);
58 DCHECK_LT(selected_index_size_t
, template_urls
.size()) <<
59 "Wrong index for search engine";
61 TemplateURL
* template_url
= template_urls
[selected_index_size_t
];
62 DCHECK_GT(template_url
->prepopulate_id(), 0) <<
63 "Tried to select non-prepopulated search engine";
64 template_url_service_
->SetUserSelectedDefaultSearchProvider(template_url
);
67 jint
TemplateUrlServiceAndroid::GetDefaultSearchProvider(JNIEnv
* env
,
69 std::vector
<TemplateURL
*> template_urls
=
70 template_url_service_
->GetTemplateURLs();
71 TemplateURL
* default_search_provider
=
72 template_url_service_
->GetDefaultSearchProvider();
73 for (size_t i
= 0; i
< template_urls
.size(); ++i
) {
74 if (default_search_provider
== template_urls
[i
])
80 jboolean
TemplateUrlServiceAndroid::IsLoaded(JNIEnv
* env
, jobject obj
) {
81 return template_url_service_
->loaded();
84 jint
TemplateUrlServiceAndroid::GetTemplateUrlCount(JNIEnv
* env
, jobject obj
) {
85 return template_url_service_
->GetTemplateURLs().size();
88 jboolean
TemplateUrlServiceAndroid::IsSearchProviderManaged(JNIEnv
* env
,
90 return template_url_service_
->is_default_search_managed();
93 jboolean
TemplateUrlServiceAndroid::IsSearchByImageAvailable(JNIEnv
* env
,
95 const TemplateURL
* default_search_provider
=
96 template_url_service_
->GetDefaultSearchProvider();
97 return default_search_provider
&&
98 !default_search_provider
->image_url().empty() &&
99 default_search_provider
->image_url_ref().IsValid(
100 template_url_service_
->search_terms_data());
103 jboolean
TemplateUrlServiceAndroid::IsDefaultSearchEngineGoogle(JNIEnv
* env
,
105 TemplateURL
* default_search_provider
=
106 template_url_service_
->GetDefaultSearchProvider();
107 return default_search_provider
&&
108 default_search_provider
->url_ref().HasGoogleBaseURLs(
109 template_url_service_
->search_terms_data());
112 base::android::ScopedJavaLocalRef
<jobject
>
113 TemplateUrlServiceAndroid::GetPrepopulatedTemplateUrlAt(JNIEnv
* env
,
116 TemplateURL
* template_url
= template_url_service_
->GetTemplateURLs()[index
];
117 if (!IsPrepopulatedTemplate(template_url
) &&
118 !template_url
->created_by_policy())
119 return ScopedJavaLocalRef
<jobject
>();
121 return Java_TemplateUrl_create(
124 base::android::ConvertUTF16ToJavaString(
125 env
, template_url
->short_name()).obj(),
126 base::android::ConvertUTF16ToJavaString(
127 env
, template_url
->keyword()).obj());
130 bool TemplateUrlServiceAndroid::IsPrepopulatedTemplate(TemplateURL
* url
) {
131 return url
->prepopulate_id() > 0;
134 void TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded() {
135 template_url_subscription_
.reset();
136 JNIEnv
* env
= base::android::AttachCurrentThread();
137 if (weak_java_obj_
.get(env
).is_null())
140 Java_TemplateUrlService_templateUrlServiceLoaded(
141 env
, weak_java_obj_
.get(env
).obj());
144 void TemplateUrlServiceAndroid::OnTemplateURLServiceChanged() {
145 JNIEnv
* env
= base::android::AttachCurrentThread();
146 if (weak_java_obj_
.get(env
).is_null())
149 Java_TemplateUrlService_onTemplateURLServiceChanged(
150 env
, weak_java_obj_
.get(env
).obj());
153 base::android::ScopedJavaLocalRef
<jstring
>
154 TemplateUrlServiceAndroid::GetUrlForSearchQuery(JNIEnv
* env
,
157 const TemplateURL
* default_provider
=
158 template_url_service_
->GetDefaultSearchProvider();
160 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
163 if (default_provider
&&
164 default_provider
->url_ref().SupportsReplacement(
165 template_url_service_
->search_terms_data()) &&
167 url
= default_provider
->url_ref().ReplaceSearchTerms(
168 TemplateURLRef::SearchTermsArgs(query
),
169 template_url_service_
->search_terms_data());
172 return base::android::ConvertUTF8ToJavaString(env
, url
);
175 base::android::ScopedJavaLocalRef
<jstring
>
176 TemplateUrlServiceAndroid::GetUrlForVoiceSearchQuery(JNIEnv
* env
,
179 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
182 if (!query
.empty()) {
183 GURL
gurl(GetDefaultSearchURLForSearchTerms(template_url_service_
, query
));
184 if (google_util::IsGoogleSearchUrl(gurl
))
185 gurl
= net::AppendQueryParameter(gurl
, "inm", "vs");
189 return base::android::ConvertUTF8ToJavaString(env
, url
);
192 base::android::ScopedJavaLocalRef
<jstring
>
193 TemplateUrlServiceAndroid::ReplaceSearchTermsInUrl(JNIEnv
* env
,
196 jstring jcurrent_url
) {
197 TemplateURL
* default_provider
=
198 template_url_service_
->GetDefaultSearchProvider();
200 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
201 GURL
current_url(base::android::ConvertJavaStringToUTF16(env
, jcurrent_url
));
202 GURL
destination_url(current_url
);
203 if (default_provider
&& !query
.empty()) {
204 bool refined_query
= default_provider
->ReplaceSearchTermsInURL(
205 current_url
, TemplateURLRef::SearchTermsArgs(query
),
206 template_url_service_
->search_terms_data(), &destination_url
);
208 return base::android::ConvertUTF8ToJavaString(
209 env
, destination_url
.spec());
211 return base::android::ScopedJavaLocalRef
<jstring
>(env
, NULL
);
214 base::android::ScopedJavaLocalRef
<jstring
>
215 TemplateUrlServiceAndroid::GetUrlForContextualSearchQuery(
219 jstring jalternate_term
,
220 jboolean jshould_prefetch
) {
221 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
224 if (!query
.empty()) {
225 GURL
gurl(GetDefaultSearchURLForSearchTerms(template_url_service_
, query
));
226 if (google_util::IsGoogleSearchUrl(gurl
)) {
227 gurl
= net::AppendQueryParameter(gurl
, "ctxs", "2");
228 if (jshould_prefetch
) {
229 // Indicate that the search page is being prefetched.
230 gurl
= net::AppendQueryParameter(gurl
, "pf", "c");
233 if (jalternate_term
) {
234 std::string
alternate_term(
235 base::android::ConvertJavaStringToUTF8(env
, jalternate_term
));
236 if (!alternate_term
.empty()) {
237 gurl
= net::AppendQueryParameter(
238 gurl
, "ctxsl_alternate_term", alternate_term
);
245 return base::android::ConvertUTF8ToJavaString(env
, url
);
248 base::android::ScopedJavaLocalRef
<jstring
>
249 TemplateUrlServiceAndroid::GetSearchEngineUrlFromTemplateUrl(
253 TemplateURL
* template_url
= template_url_service_
->GetTemplateURLs()[index
];
254 std::string
url(template_url
->url_ref().ReplaceSearchTerms(
255 TemplateURLRef::SearchTermsArgs(
256 base::ASCIIToUTF16("query")), SearchTermsData(), nullptr));
257 return base::android::ConvertUTF8ToJavaString(env
, url
);
260 static jlong
Init(JNIEnv
* env
, jobject obj
) {
261 TemplateUrlServiceAndroid
* template_url_service_android
=
262 new TemplateUrlServiceAndroid(env
, obj
);
263 return reinterpret_cast<intptr_t>(template_url_service_android
);
267 bool TemplateUrlServiceAndroid::Register(JNIEnv
* env
) {
268 return RegisterNativesImpl(env
);