template_url_service_android.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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.
4
5#include "chrome/browser/search_engines/template_url_service_android.h"
6
7#include "base/android/jni_string.h"
8#include "base/bind.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"
21
22using base::android::ConvertJavaStringToUTF16;
23using base::android::ConvertUTF16ToJavaString;
24using base::android::ConvertUTF8ToJavaString;
25
26namespace {
27
28Profile* GetOriginalProfile() {
29  return ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
30}
31
32}  // namespace
33
34TemplateUrlServiceAndroid::TemplateUrlServiceAndroid(JNIEnv* env,
35                                                     jobject obj)
36    : weak_java_obj_(env, obj),
37      template_url_service_(
38          TemplateURLServiceFactory::GetForProfile(GetOriginalProfile())) {
39  template_url_subscription_ =
40      template_url_service_->RegisterOnLoadedCallback(
41          base::Bind(&TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded,
42                     base::Unretained(this)));
43}
44
45TemplateUrlServiceAndroid::~TemplateUrlServiceAndroid() {
46}
47
48void TemplateUrlServiceAndroid::Load(JNIEnv* env, jobject obj) {
49  template_url_service_->Load();
50}
51
52void TemplateUrlServiceAndroid::SetUserSelectedDefaultSearchProvider(
53    JNIEnv* env,
54    jobject obj,
55    jint selected_index) {
56  std::vector<TemplateURL*> template_urls =
57      template_url_service_->GetTemplateURLs();
58  size_t selected_index_size_t = static_cast<size_t>(selected_index);
59  DCHECK_LT(selected_index_size_t, template_urls.size()) <<
60      "Wrong index for search engine";
61
62  TemplateURL* template_url = template_urls[selected_index_size_t];
63  DCHECK_GT(template_url->prepopulate_id(), 0) <<
64      "Tried to select non-prepopulated search engine";
65  template_url_service_->SetUserSelectedDefaultSearchProvider(template_url);
66}
67
68jint TemplateUrlServiceAndroid::GetDefaultSearchProvider(JNIEnv* env,
69                                                         jobject obj) {
70  std::vector<TemplateURL*> template_urls =
71      template_url_service_->GetTemplateURLs();
72  TemplateURL* default_search_provider =
73      template_url_service_->GetDefaultSearchProvider();
74  for (size_t i = 0; i < template_urls.size(); ++i) {
75    if (default_search_provider == template_urls[i])
76      return i;
77  }
78  return -1;
79}
80
81jboolean TemplateUrlServiceAndroid::IsLoaded(JNIEnv* env, jobject obj) {
82  return template_url_service_->loaded();
83}
84
85jint TemplateUrlServiceAndroid::GetTemplateUrlCount(JNIEnv* env, jobject obj) {
86  return template_url_service_->GetTemplateURLs().size();
87}
88
89jboolean TemplateUrlServiceAndroid::IsSearchProviderManaged(JNIEnv* env,
90                                                            jobject obj) {
91  return template_url_service_->is_default_search_managed();
92}
93
94jboolean TemplateUrlServiceAndroid::IsSearchByImageAvailable(JNIEnv* env,
95                                                             jobject obj) {
96  const TemplateURL* default_search_provider =
97      template_url_service_->GetDefaultSearchProvider();
98  return default_search_provider &&
99      !default_search_provider->image_url().empty() &&
100      default_search_provider->image_url_ref().IsValid(
101          template_url_service_->search_terms_data());
102}
103
104jboolean TemplateUrlServiceAndroid::IsDefaultSearchEngineGoogle(JNIEnv* env,
105                                                                jobject obj) {
106  TemplateURL* default_search_provider =
107      template_url_service_->GetDefaultSearchProvider();
108  return default_search_provider &&
109      default_search_provider->url_ref().HasGoogleBaseURLs(
110          template_url_service_->search_terms_data());
111}
112
113base::android::ScopedJavaLocalRef<jobject>
114TemplateUrlServiceAndroid::GetPrepopulatedTemplateUrlAt(JNIEnv* env,
115                                                        jobject obj,
116                                                        jint index) {
117  TemplateURL* template_url = template_url_service_->GetTemplateURLs()[index];
118  if (!IsPrepopulatedTemplate(template_url) &&
119      !template_url->created_by_policy())
120   return ScopedJavaLocalRef<jobject>();
121
122  return Java_TemplateUrl_create(
123      env,
124      index,
125      ConvertUTF16ToJavaString(env, template_url->short_name()).obj(),
126      ConvertUTF16ToJavaString(env, template_url->keyword()).obj());
127}
128
129bool TemplateUrlServiceAndroid::IsPrepopulatedTemplate(TemplateURL* url) {
130  return url->prepopulate_id() > 0;
131}
132
133void TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded() {
134  template_url_subscription_.reset();
135  JNIEnv* env = base::android::AttachCurrentThread();
136  if (weak_java_obj_.get(env).is_null())
137    return;
138
139  Java_TemplateUrlService_templateUrlServiceLoaded(
140      env, weak_java_obj_.get(env).obj());
141}
142
143base::android::ScopedJavaLocalRef<jstring>
144TemplateUrlServiceAndroid::GetUrlForSearchQuery(JNIEnv* env,
145                                                jobject obj,
146                                                jstring jquery) {
147  const TemplateURL* default_provider =
148      template_url_service_->GetDefaultSearchProvider();
149
150  base::string16 query(ConvertJavaStringToUTF16(env, jquery));
151
152  std::string url;
153  if (default_provider &&
154      default_provider->url_ref().SupportsReplacement(
155          template_url_service_->search_terms_data()) &&
156      !query.empty()) {
157    url = default_provider->url_ref().ReplaceSearchTerms(
158        TemplateURLRef::SearchTermsArgs(query),
159        template_url_service_->search_terms_data());
160  }
161
162  return ConvertUTF8ToJavaString(env, url);
163}
164
165base::android::ScopedJavaLocalRef<jstring>
166TemplateUrlServiceAndroid::GetUrlForVoiceSearchQuery(JNIEnv* env,
167                                                     jobject obj,
168                                                     jstring jquery) {
169  base::string16 query(ConvertJavaStringToUTF16(env, jquery));
170  std::string url;
171
172  if (!query.empty()) {
173    GURL gurl(GetDefaultSearchURLForSearchTerms(template_url_service_, query));
174    if (google_util::IsGoogleSearchUrl(gurl))
175      gurl = net::AppendQueryParameter(gurl, "inm", "vs");
176    url = gurl.spec();
177  }
178
179  return ConvertUTF8ToJavaString(env, url);
180}
181
182base::android::ScopedJavaLocalRef<jstring>
183TemplateUrlServiceAndroid::ReplaceSearchTermsInUrl(JNIEnv* env,
184                                                   jobject obj,
185                                                   jstring jquery,
186                                                   jstring jcurrent_url) {
187  TemplateURL* default_provider =
188      template_url_service_->GetDefaultSearchProvider();
189
190  base::string16 query(ConvertJavaStringToUTF16(env, jquery));
191  GURL current_url(ConvertJavaStringToUTF16(env, jcurrent_url));
192  GURL destination_url(current_url);
193  if (default_provider && !query.empty()) {
194    bool refined_query = default_provider->ReplaceSearchTermsInURL(
195        current_url, TemplateURLRef::SearchTermsArgs(query),
196        template_url_service_->search_terms_data(), &destination_url);
197    if (refined_query)
198      return ConvertUTF8ToJavaString(env, destination_url.spec());
199  }
200  return base::android::ScopedJavaLocalRef<jstring>(env, NULL);
201}
202
203base::android::ScopedJavaLocalRef<jstring>
204TemplateUrlServiceAndroid::GetUrlForContextualSearchQuery(JNIEnv* env,
205                                                          jobject obj,
206                                                          jstring jquery) {
207  base::string16 query(ConvertJavaStringToUTF16(env, jquery));
208  std::string url;
209
210  if (!query.empty()) {
211    GURL gurl(GetDefaultSearchURLForSearchTerms(template_url_service_, query));
212    if (google_util::IsGoogleSearchUrl(gurl))
213      gurl = net::AppendQueryParameter(gurl, "ctxs", "1");
214    url = gurl.spec();
215  }
216
217  return ConvertUTF8ToJavaString(env, url);
218}
219
220static jlong Init(JNIEnv* env, jobject obj) {
221  TemplateUrlServiceAndroid* template_url_service_android =
222      new TemplateUrlServiceAndroid(env, obj);
223  return reinterpret_cast<intptr_t>(template_url_service_android);
224}
225
226// static
227bool TemplateUrlServiceAndroid::Register(JNIEnv* env) {
228  return RegisterNativesImpl(env);
229}
230