Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: chrome/browser/android/contextualsearch/contextual_search_delegate.cc

Issue 2706333002: [TTS] Add a Java Context linked to existing native (Closed)
Patch Set: DCHECK that the context is created on the browser thread. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/contextualsearch/contextual_search_delegate.h" 5 #include "chrome/browser/android/contextualsearch/contextual_search_delegate.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 template_url_service_(template_url_service), 91 template_url_service_(template_url_service),
92 search_term_callback_(search_term_callback), 92 search_term_callback_(search_term_callback),
93 surrounding_callback_(surrounding_callback), 93 surrounding_callback_(surrounding_callback),
94 icing_callback_(icing_callback) { 94 icing_callback_(icing_callback) {
95 field_trial_.reset(new ContextualSearchFieldTrial()); 95 field_trial_.reset(new ContextualSearchFieldTrial());
96 } 96 }
97 97
98 ContextualSearchDelegate::~ContextualSearchDelegate() { 98 ContextualSearchDelegate::~ContextualSearchDelegate() {
99 } 99 }
100 100
101 void ContextualSearchDelegate::StartSearchTermResolutionRequest( 101 void ContextualSearchDelegate::GatherAndSaveSurroundingText(
102 const std::string& selection, 102 ContextualSearchContext* contextual_search_context,
103 const std::string& home_country, 103 content::WebContents* web_contents) {
104 content::WebContents* web_contents, 104 DCHECK(web_contents);
105 bool may_send_base_page_url) { 105 RenderFrameHost::TextSurroundingSelectionCallback callback =
106 GatherSurroundingTextWithCallback( 106 base::Bind(&ContextualSearchDelegate::OnTextSurroundingSelectionAvailable,
107 selection, home_country, web_contents, may_send_base_page_url, 107 AsWeakPtr());
108 base::Bind(&ContextualSearchDelegate::StartSearchTermRequestFromSelection, 108 context_ = contextual_search_context;
109 AsWeakPtr())); 109 int surroundingTextSize = context_->IsBrief()
110 ? field_trial_->GetIcingSurroundingSize()
111 : field_trial_->GetSurroundingSize();
112 RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
113 if (focused_frame) {
114 focused_frame->RequestTextSurroundingSelection(callback,
115 surroundingTextSize);
116 } else {
117 callback.Run(base::string16(), 0, 0);
118 }
110 } 119 }
111 120
112 void ContextualSearchDelegate::GatherAndSaveSurroundingText( 121 void ContextualSearchDelegate::StartSearchTermResolutionRequest(
Theresa 2017/03/08 01:54:38 nit: It looks like this method and the one above g
Donn Denman 2017/03/09 17:35:05 Fixed -- Changed the order in the header file to b
113 const std::string& selection, 122 ContextualSearchContext* contextual_search_context,
114 const std::string& home_country, 123 content::WebContents* web_contents) {
115 content::WebContents* web_contents, 124 DCHECK(web_contents);
116 bool may_send_base_page_url) { 125 DCHECK(context_ == contextual_search_context);
117 GatherSurroundingTextWithCallback( 126 DCHECK(!context_->IsBrief());
118 selection, home_country, web_contents, may_send_base_page_url, 127
119 base::Bind(&ContextualSearchDelegate::SaveSurroundingText, AsWeakPtr())); 128 // Immediately cancel any request that's in flight, since we're building a new
120 // TODO(donnd): clear the context here, since we're done with it (but risky). 129 // context (and the response disposes of any existing context).
130 search_term_fetcher_.reset();
131
132 // Decide if the URL should be sent with the context.
133 GURL page_url(web_contents->GetURL());
134 GURL url_to_send;
135 if (context_->MaySendBasePageUrl() &&
136 CanSendPageURL(page_url, ProfileManager::GetActiveUserProfile(),
137 template_url_service_)) {
138 url_to_send = page_url;
139 }
140 std::string encoding(web_contents->GetEncoding());
141 context_->page_url = url_to_send;
142 context_->encoding = encoding;
143 ResolveSearchTermFromContext();
121 } 144 }
122 145
123 void ContextualSearchDelegate::ContinueSearchTermResolutionRequest() { 146 void ContextualSearchDelegate::ResolveSearchTermFromContext() {
124 DCHECK(context_.get()); 147 DCHECK(context_);
125 if (!context_.get()) 148 if (!context_)
126 return; 149 return;
127 GURL request_url(BuildRequestUrl(context_->home_country)); 150 GURL request_url(BuildRequestUrl(context_->home_country));
128 DCHECK(request_url.is_valid()); 151 DCHECK(request_url.is_valid());
129 152
130 // Reset will delete any previous fetcher, and we won't get any callback. 153 // Reset will delete any previous fetcher, and we won't get any callback.
131 search_term_fetcher_.reset( 154 search_term_fetcher_.reset(
132 net::URLFetcher::Create(kContextualSearchURLFetcherID, request_url, 155 net::URLFetcher::Create(kContextualSearchURLFetcherID, request_url,
133 net::URLFetcher::GET, this).release()); 156 net::URLFetcher::GET, this).release());
134 search_term_fetcher_->SetRequestContext(url_request_context_); 157 search_term_fetcher_->SetRequestContext(url_request_context_);
135 158
(...skipping 23 matching lines...) Expand all
159 if (source->GetStatus().is_success() && response_code == net::HTTP_OK) { 182 if (source->GetStatus().is_success() && response_code == net::HTTP_OK) {
160 std::string response; 183 std::string response;
161 bool has_string_response = source->GetResponseAsString(&response); 184 bool has_string_response = source->GetResponseAsString(&response);
162 DCHECK(has_string_response); 185 DCHECK(has_string_response);
163 if (has_string_response) { 186 if (has_string_response) {
164 resolved_search_term = 187 resolved_search_term =
165 GetResolvedSearchTermFromJson(response_code, response); 188 GetResolvedSearchTermFromJson(response_code, response);
166 } 189 }
167 } 190 }
168 search_term_callback_.Run(*resolved_search_term); 191 search_term_callback_.Run(*resolved_search_term);
169
170 // The ContextualSearchContext is consumed once the request has completed.
171 context_.reset();
172 } 192 }
173 193
174 std::unique_ptr<ResolvedSearchTerm> 194 std::unique_ptr<ResolvedSearchTerm>
175 ContextualSearchDelegate::GetResolvedSearchTermFromJson( 195 ContextualSearchDelegate::GetResolvedSearchTermFromJson(
176 int response_code, 196 int response_code,
177 const std::string& json_string) { 197 const std::string& json_string) {
178 std::string search_term; 198 std::string search_term;
179 std::string display_text; 199 std::string display_text;
180 std::string alternate_term; 200 std::string alternate_term;
181 std::string mid; 201 std::string mid;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 if (!replacement_url.empty()) { 283 if (!replacement_url.empty()) {
264 size_t pos = request.find(kContextualSearchServerEndpoint); 284 size_t pos = request.find(kContextualSearchServerEndpoint);
265 if (pos != std::string::npos) { 285 if (pos != std::string::npos) {
266 request.replace(0, pos + strlen(kContextualSearchServerEndpoint), 286 request.replace(0, pos + strlen(kContextualSearchServerEndpoint),
267 replacement_url); 287 replacement_url);
268 } 288 }
269 } 289 }
270 return request; 290 return request;
271 } 291 }
272 292
273 void ContextualSearchDelegate::GatherSurroundingTextWithCallback( 293 void ContextualSearchDelegate::OnTextSurroundingSelectionAvailable(
274 const std::string& selection,
275 const std::string& home_country,
276 content::WebContents* web_contents,
277 bool may_send_base_page_url,
278 HandleSurroundingsCallback callback) {
279 // Immediately cancel any request that's in flight, since we're building a new
280 // context (and the response disposes of any existing context).
281 search_term_fetcher_.reset();
282 BuildContext(selection, home_country, web_contents, may_send_base_page_url);
283 DCHECK(web_contents);
284 RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
285 if (focused_frame) {
286 focused_frame->RequestTextSurroundingSelection(
287 callback, field_trial_->GetSurroundingSize());
288 } else {
289 callback.Run(base::string16(), 0, 0);
290 }
291 }
292
293 void ContextualSearchDelegate::BuildContext(const std::string& selection,
294 const std::string& home_country,
295 content::WebContents* web_contents,
296 bool may_send_base_page_url) {
297 // Decide if the URL should be sent with the context.
298 GURL page_url(web_contents->GetURL());
299 GURL url_to_send;
300 if (may_send_base_page_url &&
301 CanSendPageURL(page_url, ProfileManager::GetActiveUserProfile(),
302 template_url_service_)) {
303 url_to_send = page_url;
304 }
305 std::string encoding(web_contents->GetEncoding());
306 context_.reset(new ContextualSearchContext(selection, home_country,
307 url_to_send, encoding));
308 }
309
310 void ContextualSearchDelegate::StartSearchTermRequestFromSelection(
311 const base::string16& surrounding_text, 294 const base::string16& surrounding_text,
312 int start_offset, 295 int start_offset,
313 int end_offset) { 296 int end_offset) {
314 // TODO(donnd): figure out how to gather text surrounding the selection 297 SaveSurroundingText(surrounding_text, start_offset, end_offset);
315 // for other purposes too: e.g. to determine if we should select the 298 if (!context_->IsBrief())
316 // word where the user tapped.
317 if (context_.get()) {
318 SaveSurroundingText(surrounding_text, start_offset, end_offset);
319 SendSurroundingText(kSurroundingSizeForUI); 299 SendSurroundingText(kSurroundingSizeForUI);
320 ContinueSearchTermResolutionRequest();
321 } else {
322 DVLOG(1) << "ctxs: Null context, ignored!";
323 }
324 } 300 }
325 301
326 void ContextualSearchDelegate::SaveSurroundingText( 302 void ContextualSearchDelegate::SaveSurroundingText(
327 const base::string16& surrounding_text, 303 const base::string16& surrounding_text,
328 int start_offset, 304 int start_offset,
329 int end_offset) { 305 int end_offset) {
330 DCHECK(context_.get()); 306 DCHECK(context_);
331 // Sometimes the surroundings are 0, 0, '', so fall back on the selection. 307 // Sometimes the surroundings are 0, 0, '', so fall back on the selection.
332 // See crbug.com/393100. 308 // See crbug.com/393100.
333 if (start_offset == 0 && end_offset == 0 && surrounding_text.length() == 0) { 309 if (start_offset == 0 && end_offset == 0 && surrounding_text.length() == 0) {
334 context_->surrounding_text = base::UTF8ToUTF16(context_->selected_text); 310 context_->surrounding_text = base::UTF8ToUTF16(context_->selected_text);
335 context_->start_offset = 0; 311 context_->start_offset = 0;
336 context_->end_offset = context_->selected_text.length(); 312 context_->end_offset = context_->selected_text.length();
337 } else { 313 } else {
338 context_->surrounding_text = surrounding_text; 314 context_->surrounding_text = surrounding_text;
339 context_->start_offset = start_offset; 315 context_->start_offset = start_offset;
340 context_->end_offset = end_offset; 316 context_->end_offset = end_offset;
341 } 317 }
342 318
343 // Pin the start and end offsets to ensure they point within the string. 319 // Pin the start and end offsets to ensure they point within the string.
344 int surrounding_length = context_->surrounding_text.length(); 320 int surrounding_length = context_->surrounding_text.length();
345 context_->start_offset = 321 context_->start_offset =
346 std::min(surrounding_length, std::max(0, context_->start_offset)); 322 std::min(surrounding_length, std::max(0, context_->start_offset));
347 context_->end_offset = 323 context_->end_offset =
348 std::min(surrounding_length, std::max(0, context_->end_offset)); 324 std::min(surrounding_length, std::max(0, context_->end_offset));
349 325
350 // Call the Icing callback with a shortened copy of the surroundings. 326 // Call the Icing callback with a shortened copy of the surroundings.
351 int icing_surrounding_size = field_trial_->GetIcingSurroundingSize(); 327 int icing_surrounding_size = field_trial_->GetIcingSurroundingSize();
352 size_t selection_start = context_->start_offset; 328 size_t selection_start = context_->start_offset;
353 size_t selection_end = context_->end_offset; 329 size_t selection_end = context_->end_offset;
354 if (icing_surrounding_size >= 0 && selection_start < selection_end) { 330 if (icing_surrounding_size >= 0 && selection_start <= selection_end) {
355 int icing_padding_each_side = icing_surrounding_size / 2; 331 int icing_padding_each_side = icing_surrounding_size / 2;
356 base::string16 icing_surrounding_text = SurroundingTextForIcing( 332 base::string16 icing_surrounding_text = SurroundingTextForIcing(
357 context_->surrounding_text, icing_padding_each_side, &selection_start, 333 context_->surrounding_text, icing_padding_each_side, &selection_start,
358 &selection_end); 334 &selection_end);
359 if (selection_start < selection_end) 335 if (selection_start <= selection_end)
360 icing_callback_.Run(context_->encoding, icing_surrounding_text, 336 icing_callback_.Run(context_->encoding, icing_surrounding_text,
361 selection_start, selection_end); 337 selection_start, selection_end);
362 } 338 }
363 } 339 }
364 340
365 void ContextualSearchDelegate::SendSurroundingText(int max_surrounding_chars) { 341 void ContextualSearchDelegate::SendSurroundingText(int max_surrounding_chars) {
366 const base::string16& surrounding = context_->surrounding_text; 342 const base::string16& surrounding = context_->surrounding_text;
367 343
368 // Determine the text after the selection. 344 // Determine the text after the selection.
369 int surrounding_length = surrounding.length(); // Cast to int. 345 int surrounding_length = surrounding.length(); // Cast to int.
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 end_offset -= trim; 575 end_offset -= trim;
600 } 576 }
601 if (result_text.length() > end_offset + padding_each_side_pinned) { 577 if (result_text.length() > end_offset + padding_each_side_pinned) {
602 // Trim the end. 578 // Trim the end.
603 result_text = result_text.substr(0, end_offset + padding_each_side_pinned); 579 result_text = result_text.substr(0, end_offset + padding_each_side_pinned);
604 } 580 }
605 *start = start_offset; 581 *start = start_offset;
606 *end = end_offset; 582 *end = end_offset;
607 return result_text; 583 return result_text;
608 } 584 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698