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/format_macros.h"
9#include "base/strings/stringprintf.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/chrome_notification_types.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/browser/search_engines/search_terms_data.h"
15#include "chrome/browser/search_engines/template_url.h"
16#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
17#include "chrome/browser/search_engines/template_url_service.h"
18#include "chrome/browser/search_engines/template_url_service_factory.h"
19#include "content/public/browser/notification_source.h"
20#include "jni/TemplateUrlService_jni.h"
21
22using base::android::ConvertUTF16ToJavaString;
23
24namespace {
25
26Profile* GetOriginalProfile() {
27  return g_browser_process->profile_manager()->GetDefaultProfile()->
28      GetOriginalProfile();
29}
30
31}  // namespace
32
33TemplateUrlServiceAndroid::TemplateUrlServiceAndroid(JNIEnv* env,
34                                                     jobject obj)
35    : weak_java_obj_(env, obj),
36      template_url_service_(
37          TemplateURLServiceFactory::GetForProfile(GetOriginalProfile())) {
38  registrar_.Add(this,
39                 chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
40                 content::Source<TemplateURLService>(template_url_service_));
41}
42
43TemplateUrlServiceAndroid::~TemplateUrlServiceAndroid() {
44}
45
46void TemplateUrlServiceAndroid::Observe(
47    int type,
48    const content::NotificationSource& source,
49    const content::NotificationDetails& details) {
50  DCHECK_EQ(chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED, type);
51  JNIEnv* env = base::android::AttachCurrentThread();
52  if (weak_java_obj_.get(env).is_null())
53    return;
54
55  Java_TemplateUrlService_templateUrlServiceLoaded(env,
56      weak_java_obj_.get(env).obj());
57}
58
59void TemplateUrlServiceAndroid::Load(JNIEnv* env, jobject obj) {
60  template_url_service_->Load();
61}
62
63void TemplateUrlServiceAndroid::SetDefaultSearchProvider(JNIEnv* env,
64                                                         jobject obj,
65                                                         jint selected_index) {
66  std::vector<TemplateURL*> template_urls =
67      template_url_service_->GetTemplateURLs();
68  size_t selected_index_size_t = static_cast<size_t>(selected_index);
69  DCHECK_LT(selected_index_size_t, template_urls.size()) <<
70      "Wrong index for search engine";
71
72  TemplateURL* template_url = template_urls[selected_index_size_t];
73  DCHECK_GT(template_url->prepopulate_id(), 0) <<
74      "Tried to select non-prepopulated search engine";
75  template_url_service_->SetDefaultSearchProvider(template_url);
76}
77
78jint TemplateUrlServiceAndroid::GetDefaultSearchProvider(JNIEnv* env,
79                                                         jobject obj) {
80  std::vector<TemplateURL*> template_urls =
81      template_url_service_->GetTemplateURLs();
82  TemplateURL* default_search_provider =
83      template_url_service_->GetDefaultSearchProvider();
84  for (size_t i = 0; i < template_urls.size(); ++i) {
85    if (default_search_provider == template_urls[i])
86      return i;
87  }
88  return -1;
89}
90
91jboolean TemplateUrlServiceAndroid::IsLoaded(JNIEnv* env, jobject obj) {
92  return template_url_service_->loaded();
93}
94
95jint TemplateUrlServiceAndroid::GetTemplateUrlCount(JNIEnv* env, jobject obj) {
96  return template_url_service_->GetTemplateURLs().size();
97}
98
99jboolean TemplateUrlServiceAndroid::IsSearchProviderManaged(JNIEnv* env,
100                                                            jobject obj) {
101  return template_url_service_->is_default_search_managed();
102}
103
104jboolean TemplateUrlServiceAndroid::IsSearchByImageAvailable(JNIEnv* env,
105                                                             jobject obj) {
106  const TemplateURL* default_search_provider =
107      template_url_service_->GetDefaultSearchProvider();
108  return default_search_provider &&
109      !default_search_provider->image_url().empty() &&
110      default_search_provider->image_url_ref().IsValid();
111}
112
113jboolean TemplateUrlServiceAndroid::IsDefaultSearchEngineGoogle(JNIEnv* env,
114                                                                jobject obj) {
115  TemplateURL* default_search_provider =
116      template_url_service_->GetDefaultSearchProvider();
117  return default_search_provider &&
118      default_search_provider->url_ref().HasGoogleBaseURLs();
119}
120
121base::android::ScopedJavaLocalRef<jobject>
122TemplateUrlServiceAndroid::GetPrepopulatedTemplateUrlAt(JNIEnv* env,
123                                                        jobject obj,
124                                                        jint index) {
125  TemplateURL* template_url = template_url_service_->GetTemplateURLs()[index];
126  if (!IsPrepopulatedTemplate(template_url) &&
127      !template_url->created_by_policy())
128   return ScopedJavaLocalRef<jobject>();
129
130  return Java_TemplateUrl_create(
131      env,
132      index,
133      ConvertUTF16ToJavaString(env, template_url->short_name()).obj(),
134      ConvertUTF16ToJavaString(env, template_url->keyword()).obj());
135}
136
137bool TemplateUrlServiceAndroid::IsPrepopulatedTemplate(TemplateURL* url) {
138  return url->prepopulate_id() > 0;
139}
140
141static jint Init(JNIEnv* env, jobject obj) {
142  TemplateUrlServiceAndroid* template_url_service_android =
143      new TemplateUrlServiceAndroid(env, obj);
144  return reinterpret_cast<jint>(template_url_service_android);
145}
146
147// static
148bool TemplateUrlServiceAndroid::Register(JNIEnv* env) {
149  return RegisterNativesImpl(env);
150}
151