Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / android / contextualsearch / contextual_search_manager.cc
blob6ee66b6ff01ed7e522543f03d90c52116c802df3
1 // Copyright 2015 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/android/contextualsearch/contextual_search_manager.h"
7 #include <set>
9 #include "base/android/jni_string.h"
10 #include "base/callback.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/time/time.h"
13 #include "chrome/browser/android/contextualsearch/contextual_search_delegate.h"
14 #include "chrome/browser/android/tab_android.h"
15 #include "chrome/browser/history/history_service_factory.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/search_engines/template_url_service_factory.h"
18 #include "chrome/browser/ui/android/window_android_helper.h"
19 #include "components/history/core/browser/history_service.h"
20 #include "components/navigation_interception/intercept_navigation_delegate.h"
21 #include "components/variations/variations_associated_data.h"
22 #include "components/web_contents_delegate_android/web_contents_delegate_android.h"
23 #include "content/public/browser/android/content_view_core.h"
24 #include "content/public/browser/web_contents.h"
25 #include "jni/ContextualSearchManager_jni.h"
26 #include "net/url_request/url_fetcher_impl.h"
28 using content::ContentViewCore;
30 namespace {
32 const int kHistoryDeletionWindowSeconds = 2;
34 // Because we need a callback, this needs to exist.
35 void OnHistoryDeletionDone() {
38 } // namespace
40 // This class manages the native behavior of the Contextual Search feature.
41 // Instances of this class are owned by the Java ContextualSearchManager.
42 // Most of the work is actually done in an associated delegate to this class:
43 // the ContextualSearchDelegate.
44 ContextualSearchManager::ContextualSearchManager(JNIEnv* env, jobject obj) {
45 java_manager_.Reset(env, obj);
46 Java_ContextualSearchManager_setNativeManager(
47 env, obj, reinterpret_cast<intptr_t>(this));
48 Profile* profile = ProfileManager::GetActiveUserProfile();
49 delegate_.reset(new ContextualSearchDelegate(
50 profile->GetRequestContext(),
51 TemplateURLServiceFactory::GetForProfile(profile),
52 base::Bind(&ContextualSearchManager::OnSearchTermResolutionResponse,
53 base::Unretained(this)),
54 base::Bind(&ContextualSearchManager::OnSurroundingTextAvailable,
55 base::Unretained(this)),
56 base::Bind(&ContextualSearchManager::OnIcingSelectionAvailable,
57 base::Unretained(this))));
60 ContextualSearchManager::~ContextualSearchManager() {
61 JNIEnv* env = base::android::AttachCurrentThread();
62 Java_ContextualSearchManager_clearNativeManager(env, java_manager_.obj());
65 void ContextualSearchManager::Destroy(JNIEnv* env, jobject obj) { delete this; }
67 void ContextualSearchManager::StartSearchTermResolutionRequest(
68 JNIEnv* env,
69 jobject obj,
70 jstring j_selection,
71 jboolean j_use_resolved_search_term,
72 jobject j_base_content_view_core,
73 jboolean j_may_send_base_page_url) {
74 ContentViewCore* base_content_view_core =
75 ContentViewCore::GetNativeContentViewCore(env, j_base_content_view_core);
76 DCHECK(base_content_view_core);
77 std::string selection(
78 base::android::ConvertJavaStringToUTF8(env, j_selection));
79 bool use_resolved_search_term = j_use_resolved_search_term;
80 bool may_send_base_page_url = j_may_send_base_page_url;
81 // Calls back to OnSearchTermResolutionResponse.
82 delegate_->StartSearchTermResolutionRequest(
83 selection, use_resolved_search_term, base_content_view_core,
84 may_send_base_page_url);
87 void ContextualSearchManager::GatherSurroundingText(
88 JNIEnv* env,
89 jobject obj,
90 jstring j_selection,
91 jboolean j_use_resolved_search_term,
92 jobject j_base_content_view_core,
93 jboolean j_may_send_base_page_url) {
94 ContentViewCore* base_content_view_core =
95 ContentViewCore::GetNativeContentViewCore(env, j_base_content_view_core);
96 DCHECK(base_content_view_core);
97 std::string selection(
98 base::android::ConvertJavaStringToUTF8(env, j_selection));
99 bool use_resolved_search_term = j_use_resolved_search_term;
100 bool may_send_base_page_url = j_may_send_base_page_url;
101 delegate_->GatherAndSaveSurroundingText(selection, use_resolved_search_term,
102 base_content_view_core,
103 may_send_base_page_url);
106 void ContextualSearchManager::OnSearchTermResolutionResponse(
107 bool is_invalid,
108 int response_code,
109 const std::string& search_term,
110 const std::string& display_text,
111 const std::string& alternate_term,
112 bool prevent_preload,
113 int selection_start_adjust,
114 int selection_end_adjust) {
115 // Notify the Java UX of the result.
116 JNIEnv* env = base::android::AttachCurrentThread();
117 base::android::ScopedJavaLocalRef<jstring> j_search_term =
118 base::android::ConvertUTF8ToJavaString(env, search_term.c_str());
119 base::android::ScopedJavaLocalRef<jstring> j_display_text =
120 base::android::ConvertUTF8ToJavaString(env, display_text.c_str());
121 base::android::ScopedJavaLocalRef<jstring> j_alternate_term =
122 base::android::ConvertUTF8ToJavaString(env, alternate_term.c_str());
123 Java_ContextualSearchManager_onSearchTermResolutionResponse(
124 env, java_manager_.obj(), is_invalid, response_code, j_search_term.obj(),
125 j_display_text.obj(), j_alternate_term.obj(), prevent_preload,
126 selection_start_adjust, selection_end_adjust);
129 void ContextualSearchManager::OnSurroundingTextAvailable(
130 const std::string& before_text,
131 const std::string& after_text) {
132 JNIEnv* env = base::android::AttachCurrentThread();
133 base::android::ScopedJavaLocalRef<jstring> j_before_text =
134 base::android::ConvertUTF8ToJavaString(env, before_text.c_str());
135 base::android::ScopedJavaLocalRef<jstring> j_after_text =
136 base::android::ConvertUTF8ToJavaString(env, after_text.c_str());
137 Java_ContextualSearchManager_onSurroundingTextAvailable(
138 env,
139 java_manager_.obj(),
140 j_before_text.obj(),
141 j_after_text.obj());
144 void ContextualSearchManager::OnIcingSelectionAvailable(
145 const std::string& encoding,
146 const base::string16& surrounding_text,
147 size_t start_offset,
148 size_t end_offset) {
149 JNIEnv* env = base::android::AttachCurrentThread();
150 base::android::ScopedJavaLocalRef<jstring> j_encoding =
151 base::android::ConvertUTF8ToJavaString(env, encoding.c_str());
152 base::android::ScopedJavaLocalRef<jstring> j_surrounding_text =
153 base::android::ConvertUTF16ToJavaString(env, surrounding_text.c_str());
154 Java_ContextualSearchManager_onIcingSelectionAvailable(
155 env, java_manager_.obj(), j_encoding.obj(), j_surrounding_text.obj(),
156 start_offset, end_offset);
159 void ContextualSearchManager::RemoveLastSearchVisit(
160 JNIEnv* env,
161 jobject obj,
162 jstring search_url,
163 jlong search_start_time_ms) {
164 // The deletion window is from the time a search URL was put in history, up
165 // to a short amount of time later.
166 base::Time begin_time = base::Time::FromJsTime(search_start_time_ms);
167 base::Time end_time = begin_time +
168 base::TimeDelta::FromSeconds(kHistoryDeletionWindowSeconds);
170 history::HistoryService* service = HistoryServiceFactory::GetForProfile(
171 ProfileManager::GetActiveUserProfile(),
172 ServiceAccessType::EXPLICIT_ACCESS);
173 if (service) {
174 // NOTE(mathp): We are only removing |search_url| from the local history
175 // because search results that are not promoted to a Tab do not make it to
176 // the web history, only local.
177 std::set<GURL> restrict_set;
178 restrict_set.insert(
179 GURL(base::android::ConvertJavaStringToUTF8(env, search_url)));
180 service->ExpireHistoryBetween(
181 restrict_set,
182 begin_time,
183 end_time,
184 base::Bind(&OnHistoryDeletionDone),
185 &history_task_tracker_);
189 void ContextualSearchManager::SetWebContents(JNIEnv* env,
190 jobject obj,
191 jobject jcontent_view_core,
192 jobject jweb_contents_delegate) {
193 content::ContentViewCore* content_view_core =
194 content::ContentViewCore::GetNativeContentViewCore(env,
195 jcontent_view_core);
196 DCHECK(content_view_core);
197 DCHECK(content_view_core->GetWebContents());
199 // NOTE(pedrosimonetti): Takes ownership of the WebContents associated
200 // with the ContentViewCore. This is to make sure that the WebContens
201 // and the Compositor are in the same process.
202 // TODO(pedrosimonetti): Confirm with dtrainor@ if the comment above
203 // is accurate.
204 web_contents_.reset(content_view_core->GetWebContents());
205 // TODO(pedrosimonetti): confirm if we need this after promoting it
206 // to a real tab.
207 TabAndroid::AttachTabHelpers(web_contents_.get());
208 WindowAndroidHelper::FromWebContents(web_contents_.get())
209 ->SetWindowAndroid(content_view_core->GetWindowAndroid());
210 web_contents_delegate_.reset(
211 new web_contents_delegate_android::WebContentsDelegateAndroid(
212 env, jweb_contents_delegate));
213 web_contents_->SetDelegate(web_contents_delegate_.get());
216 void ContextualSearchManager::DestroyWebContents(JNIEnv* env, jobject jobj) {
217 DCHECK(web_contents_.get());
218 web_contents_.reset();
219 // |web_contents_delegate_| may already be NULL at this point.
220 web_contents_delegate_.reset();
223 void ContextualSearchManager::ReleaseWebContents(JNIEnv* env, jobject jboj) {
224 DCHECK(web_contents_.get());
225 web_contents_delegate_.reset();
226 ignore_result(web_contents_.release());
229 void ContextualSearchManager::DestroyWebContentsFromContentViewCore(
230 JNIEnv* env,
231 jobject jobj,
232 jobject jcontent_view_core) {
233 content::ContentViewCore* content_view_core =
234 content::ContentViewCore::GetNativeContentViewCore(env,
235 jcontent_view_core);
236 DCHECK(content_view_core);
237 DCHECK(content_view_core->GetWebContents());
239 delete content_view_core->GetWebContents();
242 void ContextualSearchManager::SetInterceptNavigationDelegate(
243 JNIEnv* env,
244 jobject obj,
245 jobject delegate,
246 jobject jweb_contents) {
247 content::WebContents* web_contents =
248 content::WebContents::FromJavaWebContents(jweb_contents);
249 DCHECK(web_contents);
250 navigation_interception::InterceptNavigationDelegate::Associate(
251 web_contents,
252 make_scoped_ptr(new navigation_interception::InterceptNavigationDelegate(
253 env, delegate)));
256 bool RegisterContextualSearchManager(JNIEnv* env) {
257 return RegisterNativesImpl(env);
260 jlong Init(JNIEnv* env, jobject obj) {
261 ContextualSearchManager* manager = new ContextualSearchManager(env, obj);
262 return reinterpret_cast<intptr_t>(manager);