| // Copyright (c) 2013 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/search_engines/template_url_service_android.h" |
| |
| #include <stddef.h> |
| |
| #include "base/android/jni_string.h" |
| #include "base/bind.h" |
| #include "base/format_macros.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| #include "components/google/core/browser/google_util.h" |
| #include "components/search_engines/search_terms_data.h" |
| #include "components/search_engines/template_url.h" |
| #include "components/search_engines/template_url_prepopulate_data.h" |
| #include "components/search_engines/template_url_service.h" |
| #include "components/search_engines/util.h" |
| #include "jni/TemplateUrlService_jni.h" |
| #include "net/base/url_util.h" |
| |
| using base::android::JavaParamRef; |
| using base::android::ScopedJavaLocalRef; |
| |
| namespace { |
| |
| Profile* GetOriginalProfile() { |
| return ProfileManager::GetActiveUserProfile()->GetOriginalProfile(); |
| } |
| |
| } // namespace |
| |
| TemplateUrlServiceAndroid::TemplateUrlServiceAndroid(JNIEnv* env, |
| jobject obj) |
| : weak_java_obj_(env, obj), |
| template_url_service_( |
| TemplateURLServiceFactory::GetForProfile(GetOriginalProfile())) { |
| template_url_subscription_ = |
| template_url_service_->RegisterOnLoadedCallback( |
| base::Bind(&TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded, |
| base::Unretained(this))); |
| template_url_service_->AddObserver(this); |
| } |
| |
| TemplateUrlServiceAndroid::~TemplateUrlServiceAndroid() { |
| template_url_service_->RemoveObserver(this); |
| } |
| |
| void TemplateUrlServiceAndroid::Load(JNIEnv* env, |
| const JavaParamRef<jobject>& obj) { |
| template_url_service_->Load(); |
| } |
| |
| void TemplateUrlServiceAndroid::SetUserSelectedDefaultSearchProvider( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| jint selected_index) { |
| std::vector<TemplateURL*> template_urls = |
| template_url_service_->GetTemplateURLs(); |
| size_t selected_index_size_t = static_cast<size_t>(selected_index); |
| DCHECK_LT(selected_index_size_t, template_urls.size()) << |
| "Wrong index for search engine"; |
| |
| TemplateURL* template_url = template_urls[selected_index_size_t]; |
| template_url_service_->SetUserSelectedDefaultSearchProvider(template_url); |
| } |
| |
| jint TemplateUrlServiceAndroid::GetDefaultSearchProvider( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj) { |
| std::vector<TemplateURL*> template_urls = |
| template_url_service_->GetTemplateURLs(); |
| TemplateURL* default_search_provider = |
| template_url_service_->GetDefaultSearchProvider(); |
| for (size_t i = 0; i < template_urls.size(); ++i) { |
| if (default_search_provider == template_urls[i]) |
| return i; |
| } |
| return -1; |
| } |
| |
| jboolean TemplateUrlServiceAndroid::IsLoaded(JNIEnv* env, |
| const JavaParamRef<jobject>& obj) { |
| return template_url_service_->loaded(); |
| } |
| |
| jint TemplateUrlServiceAndroid::GetTemplateUrlCount( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj) { |
| return template_url_service_->GetTemplateURLs().size(); |
| } |
| |
| jboolean TemplateUrlServiceAndroid::IsSearchProviderManaged( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj) { |
| return template_url_service_->is_default_search_managed(); |
| } |
| |
| jboolean TemplateUrlServiceAndroid::IsSearchByImageAvailable( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj) { |
| const TemplateURL* default_search_provider = |
| template_url_service_->GetDefaultSearchProvider(); |
| return default_search_provider && |
| !default_search_provider->image_url().empty() && |
| default_search_provider->image_url_ref().IsValid( |
| template_url_service_->search_terms_data()); |
| } |
| |
| jboolean TemplateUrlServiceAndroid::IsDefaultSearchEngineGoogle( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj) { |
| TemplateURL* default_search_provider = |
| template_url_service_->GetDefaultSearchProvider(); |
| return default_search_provider && |
| default_search_provider->url_ref().HasGoogleBaseURLs( |
| template_url_service_->search_terms_data()); |
| } |
| |
| base::android::ScopedJavaLocalRef<jobject> |
| TemplateUrlServiceAndroid::GetTemplateUrlAt(JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| jint index) { |
| TemplateURL* template_url = template_url_service_->GetTemplateURLs()[index]; |
| return Java_TemplateUrl_create( |
| env, index, |
| base::android::ConvertUTF16ToJavaString(env, template_url->short_name()), |
| IsPrepopulatedTemplate(template_url) || |
| template_url->created_by_policy()); |
| } |
| |
| bool TemplateUrlServiceAndroid::IsPrepopulatedTemplate(TemplateURL* url) { |
| return url->prepopulate_id() > 0; |
| } |
| |
| void TemplateUrlServiceAndroid::OnTemplateURLServiceLoaded() { |
| template_url_subscription_.reset(); |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| if (weak_java_obj_.get(env).is_null()) |
| return; |
| |
| Java_TemplateUrlService_templateUrlServiceLoaded(env, |
| weak_java_obj_.get(env)); |
| } |
| |
| void TemplateUrlServiceAndroid::OnTemplateURLServiceChanged() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| if (weak_java_obj_.get(env).is_null()) |
| return; |
| |
| Java_TemplateUrlService_onTemplateURLServiceChanged(env, |
| weak_java_obj_.get(env)); |
| } |
| |
| base::android::ScopedJavaLocalRef<jstring> |
| TemplateUrlServiceAndroid::GetUrlForSearchQuery( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| const JavaParamRef<jstring>& jquery) { |
| const TemplateURL* default_provider = |
| template_url_service_->GetDefaultSearchProvider(); |
| |
| base::string16 query(base::android::ConvertJavaStringToUTF16(env, jquery)); |
| |
| std::string url; |
| if (default_provider && |
| default_provider->url_ref().SupportsReplacement( |
| template_url_service_->search_terms_data()) && |
| !query.empty()) { |
| url = default_provider->url_ref().ReplaceSearchTerms( |
| TemplateURLRef::SearchTermsArgs(query), |
| template_url_service_->search_terms_data()); |
| } |
| |
| return base::android::ConvertUTF8ToJavaString(env, url); |
| } |
| |
| base::android::ScopedJavaLocalRef<jstring> |
| TemplateUrlServiceAndroid::GetUrlForVoiceSearchQuery( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| const JavaParamRef<jstring>& jquery) { |
| base::string16 query(base::android::ConvertJavaStringToUTF16(env, jquery)); |
| std::string url; |
| |
| if (!query.empty()) { |
| GURL gurl(GetDefaultSearchURLForSearchTerms(template_url_service_, query)); |
| if (google_util::IsGoogleSearchUrl(gurl)) |
| gurl = net::AppendQueryParameter(gurl, "inm", "vs"); |
| url = gurl.spec(); |
| } |
| |
| return base::android::ConvertUTF8ToJavaString(env, url); |
| } |
| |
| base::android::ScopedJavaLocalRef<jstring> |
| TemplateUrlServiceAndroid::ReplaceSearchTermsInUrl( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| const JavaParamRef<jstring>& jquery, |
| const JavaParamRef<jstring>& jcurrent_url) { |
| TemplateURL* default_provider = |
| template_url_service_->GetDefaultSearchProvider(); |
| |
| base::string16 query(base::android::ConvertJavaStringToUTF16(env, jquery)); |
| GURL current_url(base::android::ConvertJavaStringToUTF16(env, jcurrent_url)); |
| GURL destination_url(current_url); |
| if (default_provider && !query.empty()) { |
| bool refined_query = default_provider->ReplaceSearchTermsInURL( |
| current_url, TemplateURLRef::SearchTermsArgs(query), |
| template_url_service_->search_terms_data(), &destination_url); |
| if (refined_query) |
| return base::android::ConvertUTF8ToJavaString( |
| env, destination_url.spec()); |
| } |
| return base::android::ScopedJavaLocalRef<jstring>(env, NULL); |
| } |
| |
| base::android::ScopedJavaLocalRef<jstring> |
| TemplateUrlServiceAndroid::GetUrlForContextualSearchQuery( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| const JavaParamRef<jstring>& jquery, |
| const JavaParamRef<jstring>& jalternate_term, |
| jboolean jshould_prefetch, |
| const JavaParamRef<jstring>& jprotocol_version) { |
| base::string16 query(base::android::ConvertJavaStringToUTF16(env, jquery)); |
| std::string url; |
| |
| if (!query.empty()) { |
| GURL gurl(GetDefaultSearchURLForSearchTerms(template_url_service_, query)); |
| if (google_util::IsGoogleSearchUrl(gurl)) { |
| std::string protocol_version( |
| base::android::ConvertJavaStringToUTF8(env, jprotocol_version)); |
| gurl = net::AppendQueryParameter(gurl, "ctxs", protocol_version); |
| if (jshould_prefetch) { |
| // Indicate that the search page is being prefetched. |
| gurl = net::AppendQueryParameter(gurl, "pf", "c"); |
| } |
| |
| if (jalternate_term) { |
| std::string alternate_term( |
| base::android::ConvertJavaStringToUTF8(env, jalternate_term)); |
| if (!alternate_term.empty()) { |
| gurl = net::AppendQueryParameter( |
| gurl, "ctxsl_alternate_term", alternate_term); |
| } |
| } |
| } |
| url = gurl.spec(); |
| } |
| |
| return base::android::ConvertUTF8ToJavaString(env, url); |
| } |
| |
| base::android::ScopedJavaLocalRef<jstring> |
| TemplateUrlServiceAndroid::GetSearchEngineUrlFromTemplateUrl( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| jint index) { |
| TemplateURL* template_url = template_url_service_->GetTemplateURLs()[index]; |
| std::string url(template_url->url_ref().ReplaceSearchTerms( |
| TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("query")), |
| template_url_service_->search_terms_data())); |
| return base::android::ConvertUTF8ToJavaString(env, url); |
| } |
| |
| static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| TemplateUrlServiceAndroid* template_url_service_android = |
| new TemplateUrlServiceAndroid(env, obj); |
| return reinterpret_cast<intptr_t>(template_url_service_android); |
| } |
| |
| // static |
| bool TemplateUrlServiceAndroid::Register(JNIEnv* env) { |
| return RegisterNativesImpl(env); |
| } |