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/template_url.h"
16 #include "components/search_engines/template_url_prepopulate_data.h"
17 #include "components/search_engines/template_url_service.h"
18 #include "components/search_engines/util.h"
19 #include "jni/TemplateUrlService_jni.h"
20 #include "net/base/url_util.h"
24 Profile
* GetOriginalProfile() {
25 return ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
30 TemplateUrlServiceAndroid::TemplateUrlServiceAndroid(JNIEnv
* env
,
32 : weak_java_obj_(env
, obj
),
33 template_url_service_(
34 TemplateURLServiceFactory::GetForProfile(GetOriginalProfile())) {
35 template_url_subscription_
=
36 template_url_service_
->RegisterOnLoadedCallback(
37 base::Bind(&TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded
,
38 base::Unretained(this)));
41 TemplateUrlServiceAndroid::~TemplateUrlServiceAndroid() {
44 void TemplateUrlServiceAndroid::Load(JNIEnv
* env
, jobject obj
) {
45 template_url_service_
->Load();
48 void TemplateUrlServiceAndroid::SetUserSelectedDefaultSearchProvider(
51 jint selected_index
) {
52 std::vector
<TemplateURL
*> template_urls
=
53 template_url_service_
->GetTemplateURLs();
54 size_t selected_index_size_t
= static_cast<size_t>(selected_index
);
55 DCHECK_LT(selected_index_size_t
, template_urls
.size()) <<
56 "Wrong index for search engine";
58 TemplateURL
* template_url
= template_urls
[selected_index_size_t
];
59 DCHECK_GT(template_url
->prepopulate_id(), 0) <<
60 "Tried to select non-prepopulated search engine";
61 template_url_service_
->SetUserSelectedDefaultSearchProvider(template_url
);
64 jint
TemplateUrlServiceAndroid::GetDefaultSearchProvider(JNIEnv
* env
,
66 std::vector
<TemplateURL
*> template_urls
=
67 template_url_service_
->GetTemplateURLs();
68 TemplateURL
* default_search_provider
=
69 template_url_service_
->GetDefaultSearchProvider();
70 for (size_t i
= 0; i
< template_urls
.size(); ++i
) {
71 if (default_search_provider
== template_urls
[i
])
77 jboolean
TemplateUrlServiceAndroid::IsLoaded(JNIEnv
* env
, jobject obj
) {
78 return template_url_service_
->loaded();
81 jint
TemplateUrlServiceAndroid::GetTemplateUrlCount(JNIEnv
* env
, jobject obj
) {
82 return template_url_service_
->GetTemplateURLs().size();
85 jboolean
TemplateUrlServiceAndroid::IsSearchProviderManaged(JNIEnv
* env
,
87 return template_url_service_
->is_default_search_managed();
90 jboolean
TemplateUrlServiceAndroid::IsSearchByImageAvailable(JNIEnv
* env
,
92 const TemplateURL
* default_search_provider
=
93 template_url_service_
->GetDefaultSearchProvider();
94 return default_search_provider
&&
95 !default_search_provider
->image_url().empty() &&
96 default_search_provider
->image_url_ref().IsValid(
97 template_url_service_
->search_terms_data());
100 jboolean
TemplateUrlServiceAndroid::IsDefaultSearchEngineGoogle(JNIEnv
* env
,
102 TemplateURL
* default_search_provider
=
103 template_url_service_
->GetDefaultSearchProvider();
104 return default_search_provider
&&
105 default_search_provider
->url_ref().HasGoogleBaseURLs(
106 template_url_service_
->search_terms_data());
109 base::android::ScopedJavaLocalRef
<jobject
>
110 TemplateUrlServiceAndroid::GetPrepopulatedTemplateUrlAt(JNIEnv
* env
,
113 TemplateURL
* template_url
= template_url_service_
->GetTemplateURLs()[index
];
114 if (!IsPrepopulatedTemplate(template_url
) &&
115 !template_url
->created_by_policy())
116 return ScopedJavaLocalRef
<jobject
>();
118 return Java_TemplateUrl_create(
121 base::android::ConvertUTF16ToJavaString(
122 env
, template_url
->short_name()).obj(),
123 base::android::ConvertUTF16ToJavaString(
124 env
, template_url
->keyword()).obj());
127 bool TemplateUrlServiceAndroid::IsPrepopulatedTemplate(TemplateURL
* url
) {
128 return url
->prepopulate_id() > 0;
131 void TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded() {
132 template_url_subscription_
.reset();
133 JNIEnv
* env
= base::android::AttachCurrentThread();
134 if (weak_java_obj_
.get(env
).is_null())
137 Java_TemplateUrlService_templateUrlServiceLoaded(
138 env
, weak_java_obj_
.get(env
).obj());
141 base::android::ScopedJavaLocalRef
<jstring
>
142 TemplateUrlServiceAndroid::GetUrlForSearchQuery(JNIEnv
* env
,
145 const TemplateURL
* default_provider
=
146 template_url_service_
->GetDefaultSearchProvider();
148 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
151 if (default_provider
&&
152 default_provider
->url_ref().SupportsReplacement(
153 template_url_service_
->search_terms_data()) &&
155 url
= default_provider
->url_ref().ReplaceSearchTerms(
156 TemplateURLRef::SearchTermsArgs(query
),
157 template_url_service_
->search_terms_data());
160 return base::android::ConvertUTF8ToJavaString(env
, url
);
163 base::android::ScopedJavaLocalRef
<jstring
>
164 TemplateUrlServiceAndroid::GetUrlForVoiceSearchQuery(JNIEnv
* env
,
167 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
170 if (!query
.empty()) {
171 GURL
gurl(GetDefaultSearchURLForSearchTerms(template_url_service_
, query
));
172 if (google_util::IsGoogleSearchUrl(gurl
))
173 gurl
= net::AppendQueryParameter(gurl
, "inm", "vs");
177 return base::android::ConvertUTF8ToJavaString(env
, url
);
180 base::android::ScopedJavaLocalRef
<jstring
>
181 TemplateUrlServiceAndroid::ReplaceSearchTermsInUrl(JNIEnv
* env
,
184 jstring jcurrent_url
) {
185 TemplateURL
* default_provider
=
186 template_url_service_
->GetDefaultSearchProvider();
188 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
189 GURL
current_url(base::android::ConvertJavaStringToUTF16(env
, jcurrent_url
));
190 GURL
destination_url(current_url
);
191 if (default_provider
&& !query
.empty()) {
192 bool refined_query
= default_provider
->ReplaceSearchTermsInURL(
193 current_url
, TemplateURLRef::SearchTermsArgs(query
),
194 template_url_service_
->search_terms_data(), &destination_url
);
196 return base::android::ConvertUTF8ToJavaString(
197 env
, destination_url
.spec());
199 return base::android::ScopedJavaLocalRef
<jstring
>(env
, NULL
);
202 base::android::ScopedJavaLocalRef
<jstring
>
203 TemplateUrlServiceAndroid::GetUrlForContextualSearchQuery(
207 jstring jalternate_term
) {
208 base::string16
query(base::android::ConvertJavaStringToUTF16(env
, jquery
));
211 if (!query
.empty()) {
212 GURL
gurl(GetDefaultSearchURLForSearchTerms(template_url_service_
, query
));
213 if (google_util::IsGoogleSearchUrl(gurl
)) {
214 gurl
= net::AppendQueryParameter(gurl
, "ctxs", "2");
215 // Indicate that the search page is being prefetched.
216 gurl
= net::AppendQueryParameter(gurl
, "pf", "c");
218 if (jalternate_term
) {
219 std::string
alternate_term(
220 base::android::ConvertJavaStringToUTF8(env
, jalternate_term
));
221 if (!alternate_term
.empty()) {
222 gurl
= net::AppendQueryParameter(
223 gurl
, "ctxsl_alternate_term", alternate_term
);
230 return base::android::ConvertUTF8ToJavaString(env
, url
);
233 static jlong
Init(JNIEnv
* env
, jobject obj
) {
234 TemplateUrlServiceAndroid
* template_url_service_android
=
235 new TemplateUrlServiceAndroid(env
, obj
);
236 return reinterpret_cast<intptr_t>(template_url_service_android
);
240 bool TemplateUrlServiceAndroid::Register(JNIEnv
* env
) {
241 return RegisterNativesImpl(env
);